From 8bd246818c79e0a1feba29dd393cd43a774b0991 Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Tue, 28 Jul 2015 16:37:45 -0500 Subject: [PATCH 01/43] playlist support - crashes --- Package/Environment/Common/controls.conf | 1 + RetroFE/Source/Collection/CollectionInfo.cpp | 12 +++++++++--- RetroFE/Source/Collection/CollectionInfo.h | 4 ++++ .../Collection/CollectionInfoBuilder.cpp | 8 ++++++++ RetroFE/Source/Control/UserInput.cpp | 1 + RetroFE/Source/Control/UserInput.h | 1 + .../Graphics/Component/ScrollingList.cpp | 8 +++----- RetroFE/Source/Graphics/Page.cpp | 18 ++++++++++++++++++ RetroFE/Source/Graphics/Page.h | 4 +++- RetroFE/Source/RetroFE.cpp | 5 ++++- 10 files changed, 52 insertions(+), 10 deletions(-) diff --git a/Package/Environment/Common/controls.conf b/Package/Environment/Common/controls.conf index 6e8b4c1..a315ed2 100644 --- a/Package/Environment/Common/controls.conf +++ b/Package/Environment/Common/controls.conf @@ -6,6 +6,7 @@ pageUp = A pageDown = B letterUp = N letterDown = M +nextPlaylist = P select = Space back = Escape quit = Q diff --git a/RetroFE/Source/Collection/CollectionInfo.cpp b/RetroFE/Source/Collection/CollectionInfo.cpp index 508e357..d74955b 100644 --- a/RetroFE/Source/Collection/CollectionInfo.cpp +++ b/RetroFE/Source/Collection/CollectionInfo.cpp @@ -37,11 +37,17 @@ CollectionInfo::~CollectionInfo() { // remove items from the subcollections so their destructors do not // delete the items since the parent collection will delete them. - std::vector::iterator subit; - for (subit != subcollections_.begin(); subit != subcollections_.end(); subit++) + std::vector::iterator subit = subcollections_.begin(); + while (subit != subcollections_.end()) { CollectionInfo *info = *subit; - info->items.clear(); + subcollections_.erase(subit); + + if(info != this) + { + delete info; + } + subit = subcollections_.begin(); } diff --git a/RetroFE/Source/Collection/CollectionInfo.h b/RetroFE/Source/Collection/CollectionInfo.h index a1b5812..d4086da 100644 --- a/RetroFE/Source/Collection/CollectionInfo.h +++ b/RetroFE/Source/Collection/CollectionInfo.h @@ -17,6 +17,7 @@ #include #include +#include class Item; @@ -36,6 +37,9 @@ public: std::string launcher; std::vector items; + typedef std::map > Playlists_T; + Playlists_T playlists; + private: std::vector subcollections_; std::string metadataPath_; diff --git a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp index 5209b73..595b70c 100644 --- a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp +++ b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp @@ -242,8 +242,10 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me struct dirent *dirp; std::string path = info->listpath; std::map includeFilter; + std::map favoritesFilter; std::map excludeFilter; std::string includeFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "include.txt"); + std::string favoritesFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "favorites.txt"); std::string excludeFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "exclude.txt"); std::string launcher; @@ -269,6 +271,7 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me { Logger::write(Logger::ZONE_INFO, "CollectionInfoBuilder", "Checking for \"" + includeFile + "\""); ImportBasicList(info, includeFile, includeFilter); + ImportBasicList(info, favoritesFile, favoritesFilter); ImportBasicList(info, excludeFile, excludeFilter); } @@ -297,6 +300,10 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me } } } + for(std::map::iterator it = favoritesFilter.begin(); it != favoritesFilter.end(); it++) + { + info->playlists["favorites"].push_back(it->second); + } while((dirp = readdir(dp)) != NULL) { @@ -327,6 +334,7 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me i->collectionInfo = info; info->items.push_back(i); + info->playlists["include"].push_back(i); } } } diff --git a/RetroFE/Source/Control/UserInput.cpp b/RetroFE/Source/Control/UserInput.cpp index 4449fcc..8dcc048 100644 --- a/RetroFE/Source/Control/UserInput.cpp +++ b/RetroFE/Source/Control/UserInput.cpp @@ -67,6 +67,7 @@ bool UserInput::initialize() retVal = MapKey("select", KeyCodeSelect) && retVal; retVal = MapKey("back", KeyCodeBack) && retVal; retVal = MapKey("quit", KeyCodeQuit) && retVal; + MapKey("nextPlaylist", KeyCodeNextPlaylist); // these features will need to be implemented at a later time // retVal = MapKey("admin", KeyCodeAdminMode) && retVal; // retVal = MapKey("remove", KeyCodeHideItem) && retVal; diff --git a/RetroFE/Source/Control/UserInput.h b/RetroFE/Source/Control/UserInput.h index 4fbb66a..34ed4ab 100644 --- a/RetroFE/Source/Control/UserInput.h +++ b/RetroFE/Source/Control/UserInput.h @@ -38,6 +38,7 @@ public: KeyCodePageUp, KeyCodeLetterDown, KeyCodeLetterUp, + KeyCodeNextPlaylist, KeyCodeAdminMode, KeyCodeHideItem, KeyCodeQuit, diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index c42c291..090d110 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -125,6 +125,7 @@ ScrollingList::~ScrollingList() destroyItems(); } + void ScrollingList::setItems(std::vector *spriteList) { notifyAllRequested_ = true; @@ -227,6 +228,7 @@ void ScrollingList::destroyItems() { return; } + std::vector::iterator it = spriteList_->begin(); while(it != spriteList_->end()) @@ -235,11 +237,7 @@ void ScrollingList::destroyItems() { deallocateTexture(*it); - if((*it)->item) - { - delete (*it)->item; - } - + // items are destroyed when collections are destroyed delete *it; } diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index eb7392e..7a4c3eb 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -438,6 +438,7 @@ bool Page::pushCollection(CollectionInfo *collection) activeMenu_->destroyItems(); activeMenu_->setItems(sprites); activeMenu_->triggerMenuEnterEvent(); + playlist_ = collection->playlists.begin(); if(menuDepth_ < menus_.size()) { @@ -514,9 +515,26 @@ bool Page::popCollection() } } + if(collection) + { + delete collection; + } + return true; } +void Page::nextPlaylist() +{ + CollectionInfo *collection = collections_.back(); + playlist_++; + if(playlist_ == collection->playlists.end()) playlist_ = collection->playlists.begin(); + + std::vector *sprites = ComponentItemBindingBuilder::buildCollectionItems(&playlist_->second); + + activeMenu_->destroyItems(); + activeMenu_->setItems(sprites); + activeMenu_->triggerMenuEnterEvent(); +} void Page::update(float dt) { diff --git a/RetroFE/Source/Graphics/Page.h b/RetroFE/Source/Graphics/Page.h index 617fa76..2591d5e 100644 --- a/RetroFE/Source/Graphics/Page.h +++ b/RetroFE/Source/Graphics/Page.h @@ -16,13 +16,13 @@ #pragma once #include "MenuNotifierInterface.h" +#include "../Collection/CollectionInfo.h" #include #include #include #include -class CollectionInfo; class Component; class Configuration; class ScrollingList; @@ -46,6 +46,7 @@ public: virtual void onNewItemSelected(Item *); bool pushCollection(CollectionInfo *collection); bool popCollection(); + void nextPlaylist(); void pushMenu(ScrollingList *s); bool isMenusFull(); void setLoadSound(Sound *chunk); @@ -105,6 +106,7 @@ private: Sound *selectSoundChunk_; float minShowTime_; float elapsedTime_; + CollectionInfo::Playlists_T::iterator playlist_; }; diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index 76fefb1..a7317e0 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -489,7 +489,10 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) } } } - + if(input_.keystate(UserInput::KeyCodeNextPlaylist) && page->isMenuIdle()) + { + page->nextPlaylist(); + } if (input_.keystate(UserInput::KeyCodeBack) && page->isMenuIdle()) { if(back(exit) || exit) From a73741a835377fd9f63fbbe61d1e863883fc0102 Mon Sep 17 00:00:00 2001 From: Pieter Hulshoff Date: Wed, 29 Jul 2015 08:42:37 +0200 Subject: [PATCH 02/43] Changed titleshot to screentitle in the MAMEd themes that used it. --- Package/Environment/Common/layouts/Mamed 16x9/layout.xml | 2 +- Package/Environment/Common/layouts/Mamed 2015 16x9/layout.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Package/Environment/Common/layouts/Mamed 16x9/layout.xml b/Package/Environment/Common/layouts/Mamed 16x9/layout.xml index db4770a..dd46163 100644 --- a/Package/Environment/Common/layouts/Mamed 16x9/layout.xml +++ b/Package/Environment/Common/layouts/Mamed 16x9/layout.xml @@ -76,7 +76,7 @@ - + diff --git a/Package/Environment/Common/layouts/Mamed 2015 16x9/layout.xml b/Package/Environment/Common/layouts/Mamed 2015 16x9/layout.xml index ccb4167..4ca289b 100644 --- a/Package/Environment/Common/layouts/Mamed 2015 16x9/layout.xml +++ b/Package/Environment/Common/layouts/Mamed 2015 16x9/layout.xml @@ -90,7 +90,7 @@ - + From f912afcdf017a8a12296b273a48432b0f428c8af Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Fri, 31 Jul 2015 17:33:54 -0500 Subject: [PATCH 03/43] Refactoring ScrollingList to address memory leak issues (required for playlists) --- .../Graphics/Component/ScrollingList.cpp | 722 ++++-------------- .../Source/Graphics/Component/ScrollingList.h | 266 ++++--- RetroFE/Source/Graphics/Page.cpp | 11 +- 3 files changed, 298 insertions(+), 701 deletions(-) diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index 090d110..c4e6a21 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -19,7 +19,6 @@ #include "../Animate/Animation.h" #include "../Animate/AnimationEvents.h" #include "../Animate/TweenTypes.h" -#include "../ComponentItemBinding.h" #include "../Font.h" #include "ScrollingList.h" #include "ImageBuilder.h" @@ -50,10 +49,9 @@ ScrollingList::ScrollingList(Configuration &c, , spriteList_(NULL) , scrollPoints_(NULL) , tweenPoints_(NULL) - , tweenEnterTime_(0) , focus_(false) - , firstSpriteIndex_(0) - , selectedSpriteListIndex_(0) + , itemIndex_(0) + , componentIndex_(0) , scrollStopRequested_(true) , notifyAllRequested_(false) , currentScrollDirection_(ScrollDirectionIdle) @@ -68,6 +66,7 @@ ScrollingList::ScrollingList(Configuration &c, , fontInst_(font) , layoutKey_(layoutKey) , imageType_(imageType) + , items_(NULL) { } @@ -75,10 +74,7 @@ ScrollingList::ScrollingList(const ScrollingList ©) : Component(copy) , horizontalScroll(copy.horizontalScroll) , spriteList_(NULL) - , tweenEnterTime_(0) , focus_(false) - , firstSpriteIndex_(0) - , selectedSpriteListIndex_(copy.selectedSpriteListIndex_) , scrollStopRequested_(true) , notifyAllRequested_(false) , currentScrollDirection_(ScrollDirectionIdle) @@ -93,6 +89,7 @@ ScrollingList::ScrollingList(const ScrollingList ©) , fontInst_(copy.fontInst_) , layoutKey_(copy.layoutKey_) , imageType_(copy.imageType_) + , items_(NULL) { scrollPoints_ = NULL; @@ -126,38 +123,34 @@ ScrollingList::~ScrollingList() } -void ScrollingList::setItems(std::vector *spriteList) +void ScrollingList::setItems(CollectionInfo *info) { - notifyAllRequested_ = true; - spriteList_ = spriteList; - firstSpriteIndex_ = 0; + std::cout << "setItems" << std::endl; + deallocateSpritePoints(); - if(!spriteList_) - { - return; - } - unsigned int originalSize = spriteList_->size(); - - // loop the scroll points if there are not enough, the +2 represents the head and tail nodes (for when the item is allocated) - while(scrollPoints_ && scrollPoints_->size()+2 > spriteList_->size() && spriteList_->size() > 0) - { - for(unsigned int i = 0; i < originalSize; ++i) - { - Item *newItem = new Item(); - Item *originalItem = spriteList_->at(i)->item; - - *newItem = *originalItem; - ComponentItemBinding *newSprite = new ComponentItemBinding(newItem); - spriteList_->push_back(newSprite); - } - } - - for(unsigned int i = 0; scrollPoints_ && i < selectedSpriteListIndex_; ++i) - { - circularDecrement(firstSpriteIndex_, spriteList_); - } + collection_ = info; + items_ = &collection_->items; + itemIndex_ = 0; + componentIndex_ = 0; + allocateSpritePoints(); + + notifyAllRequested_ = true; + +} + +unsigned int ScrollingList::loopIncrement(unsigned int offset, unsigned int i, unsigned int size) +{ + if(size == 0) return 0; + return (offset + i) % size; +} + +unsigned int ScrollingList::loopDecrement(unsigned int offset, unsigned int i, unsigned int size) +{ + if(size == 0) return 0; + // (A - B) % C = ((A % C) - (B % C)) % C + return ((offset % size) - (i % size) ) % size; } @@ -173,214 +166,125 @@ void ScrollingList::setStartScrollTime(float value) void ScrollingList::deallocateSpritePoints() { - if(!spriteList_) + for(unsigned int i = 0; i < components_.size(); ++i) { - return; - } - - unsigned int spriteIndex = firstSpriteIndex_; - - for(unsigned int i = 0; i < scrollPoints_->size() && spriteList_->size() > spriteIndex; ++i) - { - deallocateTexture(spriteList_->at(spriteIndex)); - circularIncrement(spriteIndex, spriteList_); + deallocateTexture(i); } } void ScrollingList::allocateSpritePoints() { - if(!scrollPoints_) + for(unsigned int i = 0; items_ && i < scrollPoints_->size(); ++i) { - return; - } - if(!spriteList_) - { - return; - } - if(spriteList_->size() == 0) - { - return; - } - if(!tweenPoints_) - { - return; - } + unsigned int index = loopIncrement(itemIndex_, i, items_->size()); + Item *item = items_->at(index); - unsigned int spriteIndex = firstSpriteIndex_; + allocateTexture(i, item); + Component *c = components_.at(i); - for(unsigned int i = 0; i < scrollPoints_->size(); ++i) - { - allocateTexture(spriteList_->at(spriteIndex)); - Component *c = spriteList_->at(spriteIndex)->component; - ViewInfo *currentViewInfo = scrollPoints_->at(i); - unsigned int nextI = getNextTween(i, scrollPoints_); - ViewInfo *nextViewInfo = scrollPoints_->at(nextI); + ViewInfo *current = scrollPoints_->at(i); - resetTweens(c, tweenPoints_->at(i), currentViewInfo, nextViewInfo, 0); + unsigned int nextI = loopIncrement(i, 1, scrollPoints_->size()); + ViewInfo *next = scrollPoints_->at(nextI); - circularIncrement(spriteIndex, spriteList_); + resetTweens(c, tweenPoints_->at(i), current, next, 0); } } void ScrollingList::destroyItems() { - if(!spriteList_) - { - return; - } - - std::vector::iterator it = spriteList_->begin(); - - while(it != spriteList_->end()) - { - if(*it != NULL) - { - deallocateTexture(*it); - - // items are destroyed when collections are destroyed - delete *it; - } - - - spriteList_->erase(it); - - it = spriteList_->begin(); - } - - delete spriteList_; - spriteList_ = NULL; + deallocateSpritePoints(); +//todo: who deletes the CollectionInfo? } void ScrollingList::setPoints(std::vector *scrollPoints, std::vector *tweenPoints) { + deallocateSpritePoints(); + scrollPoints_ = scrollPoints; tweenPoints_ = tweenPoints; + + // empty out the list as we will resize it + components_.clear(); + + if(scrollPoints && scrollPoints_->size() > components_.size()) + { + components_.resize(scrollPoints_->size(), NULL); + } + allocateSpritePoints(); } unsigned int ScrollingList::getScrollOffsetIndex() { - return firstSpriteIndex_; + return itemIndex_; } void ScrollingList::setScrollOffsetIndex(unsigned int index) { - if(spriteList_ && index < spriteList_->size()) - { - deallocateSpritePoints(); - firstSpriteIndex_ = index; - allocateSpritePoints(); - } + itemIndex_ = index; } void ScrollingList::setSelectedIndex(int selectedIndex) { - selectedSpriteListIndex_ = selectedIndex; - - for(unsigned int i = 0; spriteList_ && scrollPoints_ && i < selectedSpriteListIndex_; ++i) - { - circularDecrement(firstSpriteIndex_, spriteList_); - } + selectedOffsetIndex_ = selectedIndex; } void ScrollingList::click(double nextScrollTime) { - if(!spriteList_) - { - return; - } - if(spriteList_->size() == 0) - { - return; - } - - unsigned int listSize = scrollPoints_->size(); - unsigned int end = circularIncrement(firstSpriteIndex_, listSize - 1, spriteList_); - unsigned int allocSpriteIndex = 0; - unsigned int deallocSpriteIndex = 0; - unsigned int allocPoint = 0; - + ViewInfo *cur; + ViewInfo *next; if(currentScrollDirection_ == ScrollDirectionBack) { - deallocSpriteIndex = end; - circularDecrement(firstSpriteIndex_, spriteList_); - allocSpriteIndex = firstSpriteIndex_; - allocPoint = 0; + next = scrollPoints_->at(componentIndex_); + itemIndex_ = loopIncrement(itemIndex_, 1, items_->size()); + componentIndex_ = loopIncrement(componentIndex_, 1, components_.size()); + cur = scrollPoints_->at(componentIndex_); } else if(currentScrollDirection_ == ScrollDirectionForward) { - deallocSpriteIndex = firstSpriteIndex_; - circularIncrement(firstSpriteIndex_, spriteList_); - allocSpriteIndex = circularIncrement(firstSpriteIndex_, listSize - 1, spriteList_); - allocPoint = listSize - 1; + next = scrollPoints_->at(componentIndex_); + itemIndex_ = loopDecrement(itemIndex_, 1, items_->size()); + componentIndex_ = loopDecrement(componentIndex_, 1, components_.size()); + cur = scrollPoints_->at(componentIndex_); } else { return; } - deallocateTexture(spriteList_->at(deallocSpriteIndex)); - allocateTexture(spriteList_->at(allocSpriteIndex)); + Item *i = items_->at(itemIndex_); - Component *c = spriteList_->at(allocSpriteIndex)->component; - ViewInfo *currentViewInfo = scrollPoints_->at(allocPoint); - unsigned int nextI = getNextTween(allocPoint, scrollPoints_); - ViewInfo *nextViewInfo = scrollPoints_->at(nextI); + deallocateTexture(componentIndex_); + allocateTexture(componentIndex_, i); + Component *c = components_.at(componentIndex_); - resetTweens(c, tweenPoints_->at(allocPoint), currentViewInfo, nextViewInfo, nextScrollTime); -} + resetTweens(c, tweenPoints_->at(componentIndex_), cur, next, 0); -unsigned int ScrollingList::getNextTween(unsigned int currentIndex, std::vector *list) -{ - if(currentScrollDirection_ == ScrollDirectionForward) - { - circularDecrement(currentIndex, list); - } - else if(currentScrollDirection_ == ScrollDirectionBack) - { - circularIncrement(currentIndex, list); - } - - return currentIndex; } void ScrollingList::pageUp() { notifyAllRequested_ = true; + + if(components_.size() == 0) return; + deallocateSpritePoints(); - if(spriteList_ && scrollPoints_ && scrollPoints_->size() > 2) - { - scrollPeriod_ = 0; - unsigned int counts = scrollPoints_->size() - 2; - - for(unsigned int i = 0; i < counts; i++) - { - circularDecrement(firstSpriteIndex_, spriteList_); - } - } - + itemIndex_ = loopDecrement(itemIndex_, components_.size(), items_->size()); + allocateSpritePoints(); - -// CurrentScrollState = ScrollStatePageChange; } void ScrollingList::pageDown() { notifyAllRequested_ = true; + if(components_.size() == 0) return; + deallocateSpritePoints(); - if(spriteList_ && scrollPoints_ && scrollPoints_->size() > 2) - { - unsigned int counts = scrollPoints_->size() - 2; - - scrollPeriod_ = 0; - for(unsigned int i = 0; i < counts; i++) - { - circularIncrement(firstSpriteIndex_, spriteList_); - } - } + itemIndex_ = loopIncrement(itemIndex_, components_.size(), items_->size()); allocateSpritePoints(); } @@ -388,77 +292,39 @@ void ScrollingList::pageDown() void ScrollingList::letterUp() { - notifyAllRequested_ = true; - deallocateSpritePoints(); - - if(spriteList_ && scrollPoints_ && getSelectedCollectionItemSprite()) - { - unsigned int i = 0; - - // Select the previous item in the list in case we are at the top of all the items - // for the currently selected letter. - circularDecrement(firstSpriteIndex_, spriteList_); - std::string startname = getSelectedCollectionItemSprite()->item->lowercaseFullTitle(); - ++i; - - bool done = false; - - // traverse up through the list until we find the first item that starts with a different letter - while(!done && i < spriteList_->size()) - { - circularDecrement(firstSpriteIndex_, spriteList_); - std::string endname = getSelectedCollectionItemSprite()->item->lowercaseFullTitle(); - ++i; - - // check if we are changing characters from a-z, or changing from alpha character to non-alpha character - if(isalpha(startname[0]) ^ isalpha(endname[0])) - { - done = true; - } - else if(isalpha(startname[0]) && isalpha(endname[0]) && startname[0] != endname[0]) - { - done = true; - } - - if(done) - { - // our searching went too far, rewind to the first item in the list that matches the starting letter - circularIncrement(firstSpriteIndex_, spriteList_); - } - } - } - - allocateSpritePoints(); + letterChange(true); } void ScrollingList::letterDown() +{ + letterChange(false); +} + +void ScrollingList::letterChange(bool increment) { notifyAllRequested_ = true; deallocateSpritePoints(); - if(spriteList_ && scrollPoints_ && getSelectedCollectionItemSprite()) + std::string startname = items_->at(itemIndex_)->lowercaseFullTitle(); + + for(unsigned int i = 0; i < items_->size(); ++i) { + unsigned int index = 0; + if(increment) index = loopIncrement(itemIndex_, i, items_->size()); + else index = loopDecrement(itemIndex_, i, items_->size()); - std::string startname = getSelectedCollectionItemSprite()->item->lowercaseFullTitle(); - std::string endname = startname; + std::string endname = items_->at(index)->lowercaseFullTitle(); - unsigned int i = 0; - bool done = false; - while(!done && i < spriteList_->size()) + // check if we are changing characters from a-z, or changing from alpha character to non-alpha character + if(isalpha(startname[0]) ^ isalpha(endname[0])) { - circularIncrement(firstSpriteIndex_, spriteList_); - endname = getSelectedCollectionItemSprite()->item->lowercaseFullTitle(); - ++i; - - // check if we are changing characters from a-z, or changing from alpha character to non-alpha character - if(isalpha(startname[0]) ^ isalpha(endname[0])) - { - done = true; - } - else if(isalpha(startname[0]) && isalpha(endname[0]) && startname[0] != endname[0]) - { - done = true; - } + break; + itemIndex_ = index; + } + else if(isalpha(startname[0]) && isalpha(endname[0]) && startname[0] != endname[0]) + { + itemIndex_ = index; + break; } } @@ -469,18 +335,12 @@ void ScrollingList::letterDown() void ScrollingList::freeGraphicsMemory() { Component::freeGraphicsMemory(); - tweenEnterTime_ = 0; currentScrollDirection_ = ScrollDirectionIdle; requestedScrollDirection_ = ScrollDirectionIdle; currentScrollState_ = ScrollStateIdle; scrollPeriod_ = 0; - - for(unsigned int i = 0; spriteList_ && i < spriteList_->size(); i++) - { - ComponentItemBinding *s = spriteList_->at(i); - - deallocateTexture(s); - } + + deallocateSpritePoints(); } void ScrollingList::triggerMenuEnterEvent() @@ -488,36 +348,10 @@ void ScrollingList::triggerMenuEnterEvent() focus_ = true; notifyAllRequested_ = true; - if(!scrollPoints_) + for(unsigned int i = 0; i < components_.size(); ++i) { - return; - } - if(!spriteList_) - { - return; - } - if(spriteList_->size() == 0 ) - { - return; - } - if(firstSpriteIndex_ >= spriteList_->size()) - { - return; - } - - unsigned int spriteIndex = firstSpriteIndex_; - - for(unsigned int i = 0; i < scrollPoints_->size(); ++i) - { - ComponentItemBinding *s = spriteList_->at(spriteIndex); - - Component *c = s->component; - if(c) - { - c->triggerMenuEnterEvent(); - } - - circularIncrement(spriteIndex, spriteList_); + Component *c = components_.at(i); + if(c) c->triggerMenuEnterEvent(); } } @@ -526,36 +360,10 @@ void ScrollingList::triggerMenuExitEvent() focus_ = false; notifyAllRequested_ = true; - if(!scrollPoints_) + for(unsigned int i = 0; i < components_.size(); ++i) { - return; - } - if(!spriteList_) - { - return; - } - if(spriteList_->size() == 0 ) - { - return; - } - if(firstSpriteIndex_ >= spriteList_->size()) - { - return; - } - - unsigned int spriteIndex = firstSpriteIndex_; - - for(unsigned int i = 0; i < scrollPoints_->size(); ++i) - { - ComponentItemBinding *s = spriteList_->at(spriteIndex); - - Component *c = s->component; - if(c) - { - c->triggerMenuExitEvent(); - } - - circularIncrement(spriteIndex, spriteList_); + Component *c = components_.at(i); + if(c) c->triggerMenuExitEvent(); } } @@ -563,29 +371,15 @@ void ScrollingList::update(float dt) { Component::update(dt); - if(!scrollPoints_) - { - return; - } - if(!spriteList_) - { - return; - } - if(spriteList_->size() == 0) - { - return; - } - bool readyToScroll = true; bool scrollChanged = false; bool scrollRequested = false; bool scrollStopped = false; // validate all scroll points are done tweening to the next position - for(unsigned int i = 0; i < spriteList_->size(); i++) + for(unsigned int i = 0; i < components_.size(); i++) { - ComponentItemBinding *s = spriteList_->at(i); - Component *c = s->component; + Component *c = components_.at(i); if(c && c->isMenuScrolling()) { @@ -620,20 +414,11 @@ void ScrollingList::update(float dt) currentScrollState_ = ScrollStateIdle; scrollStopped = true; - // update the tweens now that we are done - unsigned int spriteIndex = firstSpriteIndex_; - for(unsigned int i = 0; i < tweenPoints_->size(); ++i) { - ComponentItemBinding *s = spriteList_->at(spriteIndex); + Component *c = components_.at(i); - Component *c = s->component; - if(c) - { - c->setTweens(tweenPoints_->at(i)); - } - - circularIncrement(spriteIndex, spriteList_); + if(c) c->setTweens(tweenPoints_->at(i)); } } @@ -652,28 +437,44 @@ void ScrollingList::update(float dt) } - unsigned int spriteIndex = firstSpriteIndex_; for(unsigned int i = 0; i < scrollPoints_->size(); i++) { - updateSprite(spriteIndex, i, (scrollRequested || scrollChanged), dt, scrollPeriod_); - circularIncrement(spriteIndex, spriteList_); + unsigned int cindex = loopIncrement(componentIndex_, i, components_.size()); + Component *c = components_.at(cindex); + + if(c && (scrollRequested || scrollChanged)) + { + ViewInfo *currentvi = scrollPoints_->at(i); + unsigned int nextI = 0; + if(currentScrollDirection_ == ScrollDirectionBack) + { + nextI = loopIncrement(i, 1, scrollPoints_->size()); + } + if(currentScrollDirection_ == ScrollDirectionForward) + { + nextI = loopDecrement(i, 1, scrollPoints_->size()); + } + + ViewInfo *nextvi = scrollPoints_->at(nextI); + + resetTweens(c, tweenPoints_->at(i), currentvi, nextvi, scrollPeriod_); + c->triggerMenuScrollEvent(); + } + + if(c) c->update(dt); + } if(scrollStopped || (notifyAllRequested_ && focus_)) { - ComponentItemBinding *sprite = getPendingCollectionItemSprite(); - Item *item = NULL; - - if(sprite) - { - item = sprite->item; - } + Item *item = getPendingItem(); for(std::vector::iterator it = notificationComponents_.begin(); it != notificationComponents_.end(); it++) { MenuNotifierInterface *c = *it; + if(c && item) { c->onNewItemSelected(item); @@ -689,47 +490,12 @@ void ScrollingList::update(float dt) notifyAllRequested_ = false; } -void ScrollingList::updateSprite(unsigned int spriteIndex, unsigned int pointIndex, bool newScroll, float dt, double nextScrollTime) -{ - ComponentItemBinding *s = spriteList_->at(spriteIndex); - - Component *c = s->component; - //todo: remove me - if(c && newScroll) - { - ViewInfo *currentViewInfo = scrollPoints_->at(pointIndex); - unsigned int nextI = getNextTween(pointIndex, scrollPoints_); - ViewInfo *nextViewInfo = scrollPoints_->at(nextI); - - resetTweens(c, tweenPoints_->at(pointIndex), currentViewInfo, nextViewInfo, nextScrollTime); - c->triggerMenuScrollEvent(); - } - if(c) - { - c->update(dt); - } - - circularIncrement(spriteIndex, spriteList_); -} - void ScrollingList::resetTweens(Component *c, AnimationEvents *sets, ViewInfo *currentViewInfo, ViewInfo *nextViewInfo, double scrollTime) { - if(!c) - { - return; - } - if(!sets) - { - return; - } - if(!currentViewInfo) - { - return; - } - if(!nextViewInfo) - { - return; - } + if(!c) return; + if(!sets) return; + if(!currentViewInfo) return; + if(!nextViewInfo) return; currentViewInfo->ImageHeight = c->baseViewInfo.ImageHeight; currentViewInfo->ImageWidth = c->baseViewInfo.ImageWidth; @@ -761,15 +527,11 @@ void ScrollingList::resetTweens(Component *c, AnimationEvents *sets, ViewInfo *c } -bool ScrollingList::allocateTexture(ComponentItemBinding *s) +bool ScrollingList::allocateTexture(unsigned int index, Item *item) { - if(!s || s->component != NULL) - { - return false; - } + if(index >= components_.size()) return false; - const Item *item = s->item; //todo: will create a runtime fault if not of the right type //todo: remove coupling from knowing the collection name @@ -834,20 +596,23 @@ bool ScrollingList::allocateTexture(ComponentItemBinding *s) if(t) { - s->component = t; + components_.at(index) = t; } return true; } -void ScrollingList::deallocateTexture(ComponentItemBinding *s) +void ScrollingList::deallocateTexture(unsigned int index) { - if(s && s->component != NULL) + if(components_.size() <= index) return; + + Component *s = components_.at(index); + + if(s) { - delete s->component; - //todo: memory leak here, need to destroy allocated tween points here and in page (cannot be destroyed by component) + delete s; + components_.at(index) = NULL; } - s->component = NULL; } void ScrollingList::draw() @@ -858,32 +623,11 @@ void ScrollingList::draw() void ScrollingList::draw(unsigned int layer) { - if(!scrollPoints_) + + for(unsigned int i = 0; i < components_.size(); ++i) { - return; - } - if(!spriteList_) - { - return; - } - if(spriteList_->size() == 0) - { - return; - } - - unsigned int spriteIndex = firstSpriteIndex_; - - for(unsigned int i = 0; i < scrollPoints_->size(); i++) - { - ComponentItemBinding *s = spriteList_->at(spriteIndex); - Component *c = s->component; - ViewInfo *currentViewInfo = scrollPoints_->at(i); - - if(c && currentViewInfo && currentViewInfo->Layer == layer) - { - c->draw(); - } - circularIncrement(spriteIndex, spriteList_); + Component *c = components_.at(i); + if(c) c->draw(); } } @@ -895,69 +639,6 @@ void ScrollingList::setScrollDirection(ScrollDirection direction) scrollStopRequested_ = (direction == ScrollDirectionIdle); } -void ScrollingList::removeSelectedItem() -{ - ComponentItemBinding *sprite = getSelectedCollectionItemSprite(); - if(sprite && spriteList_) - { - Item *item = sprite->item; - deallocateTexture(sprite); - int index = (firstSpriteIndex_ + selectedSpriteListIndex_) % spriteList_->size(); - - std::vector::iterator it = spriteList_->begin() + index; - - spriteList_->erase(it); - delete sprite; - - if(item) - { - delete item; - } - - if(selectedSpriteListIndex_ >= spriteList_->size()) - { - selectedSpriteListIndex_ = 0; - } - if(firstSpriteIndex_ >= spriteList_->size()) - { - firstSpriteIndex_ = 0; - } - } -} - - -std::vector *ScrollingList::getCollectionItemSprites() -{ - return spriteList_; -} - -ComponentItemBinding* ScrollingList::getSelectedCollectionItemSprite() -{ - ComponentItemBinding *item = NULL; - - if(spriteList_ && spriteList_->size() > 0) - { - int index = (firstSpriteIndex_ + selectedSpriteListIndex_) % spriteList_->size(); - - item = spriteList_->at(index); - } - - return item; -} - -ComponentItemBinding* ScrollingList::getPendingCollectionItemSprite() -{ - ComponentItemBinding *item = NULL; - unsigned int index = firstSpriteIndex_; - if(spriteList_ && spriteList_->size() > 0) - { - index = (index + selectedSpriteListIndex_) % spriteList_->size(); - - item = spriteList_->at(index); - } - - return item; -} void ScrollingList::addComponentForNotifications(MenuNotifierInterface *c) { @@ -978,29 +659,24 @@ void ScrollingList::removeComponentForNotifications(MenuNotifierInterface *c) } -ComponentItemBinding* ScrollingList::getPendingSelectedCollectionItemSprite() +Item* ScrollingList::getPendingItem() { - ComponentItemBinding *item = NULL; + Item *item = NULL; - if(spriteList_) + if(items_ && items_->size() > 0) { - unsigned int index = selectedSpriteListIndex_; + unsigned int index = itemIndex_; if(currentScrollDirection_ == ScrollDirectionBack) { - circularDecrement(index, spriteList_); + index = loopDecrement(index, 1, items_->size()); } if(currentScrollDirection_ == ScrollDirectionForward) { - circularIncrement(index, spriteList_); + index = loopIncrement(index, 1, items_->size()); } - if(spriteList_ && spriteList_->size() > 0) - { - index = (index + selectedSpriteListIndex_) % spriteList_->size(); - - item = spriteList_->at(index); - } + item = items_->at(index); } return item; @@ -1011,74 +687,4 @@ bool ScrollingList::isIdle() return (Component::isIdle() && currentScrollState_ == ScrollStateIdle); } -void ScrollingList::circularIncrement(unsigned int &index, std::vector* list) -{ - index++; - - if(index >= list->size()) - { - index = 0; - } -} - -void ScrollingList::circularDecrement(unsigned int &index, std::vector* list) -{ - if(index > 0) - { - index--; - } - else - { - if(list->size() > 0) - { - index = list->size() - 1; - } - else - { - index = 0; - } - } -} - -int ScrollingList::circularIncrement(unsigned int index, unsigned int offset, std::vector *list) -{ - unsigned int end = index + offset; - - while(end >= list->size() && list->size() > 0) - { - end -= list->size(); - } - - return end; -} - - -void ScrollingList::circularIncrement(unsigned int &index, std::vector *list) -{ - index++; - - if(index >= list->size()) - { - index = 0; - } -} - -void ScrollingList::circularDecrement(unsigned int &index, std::vector *list) -{ - if(index > 0) - { - index--; - } - else - { - if(list && list->size() > 0) - { - index = list->size() - 1; - } - else - { - index = 0; - } - } -} diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.h b/RetroFE/Source/Graphics/Component/ScrollingList.h index 2a87fb9..d0f45f0 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.h +++ b/RetroFE/Source/Graphics/Component/ScrollingList.h @@ -1,136 +1,134 @@ -/* This file is part of RetroFE. - * - * RetroFE is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RetroFE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RetroFE. If not, see . - */ -#pragma once - -#include -#include "Component.h" -#include "../Animate/Tween.h" -#include "../ComponentItemBinding.h" -#include "../MenuNotifierInterface.h" -#include "../ViewInfo.h" -#include "../../Database/Configuration.h" -#include - - -//todo: This scrolling implementation needs to be overhauled -// It needs to have a common interface to support different menu types -// (It was originally sandbox code that creeped into here) - -class Configuration; -class Font; - -class ScrollingList : public Component -{ -public: - enum ScrollDirection - { - ScrollDirectionBack, - ScrollDirectionForward, - ScrollDirectionIdle, - - }; - - ScrollingList(Configuration &c, - float scaleX, - float scaleY, - Font *font, - std::string layoutKey, - std::string imageType); - - ScrollingList(const ScrollingList ©); - virtual ~ScrollingList(); - void triggerMenuEnterEvent(); - void triggerMenuExitEvent(); - - bool allocateTexture(ComponentItemBinding *s); - void deallocateTexture(ComponentItemBinding *s); - void setItems(std::vector *spriteList); - void destroyItems(); - void setPoints(std::vector *scrollPoints, std::vector *tweenPoints); - void setScrollDirection(ScrollDirection direction); - void pageUp(); - void pageDown(); - void letterUp(); - void letterDown(); - bool isIdle(); +/* This file is part of RetroFE. + * + * RetroFE is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RetroFE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RetroFE. If not, see . + */ +#pragma once + +#include +#include "Component.h" +#include "../Animate/Tween.h" +#include "../MenuNotifierInterface.h" +#include "../ViewInfo.h" +#include "../../Database/Configuration.h" +#include + + +//todo: This scrolling implementation needs to be overhauled +// It needs to have a common interface to support different menu types +// (It was originally sandbox code that creeped into here) + +class Configuration; +class Font; + +class ScrollingList : public Component +{ +public: + enum ScrollDirection + { + ScrollDirectionBack, + ScrollDirectionForward, + ScrollDirectionIdle, + + }; + + ScrollingList(Configuration &c, + float scaleX, + float scaleY, + Font *font, + std::string layoutKey, + std::string imageType); + + ScrollingList(const ScrollingList ©); + virtual ~ScrollingList(); + void triggerMenuEnterEvent(); + void triggerMenuExitEvent(); + + bool allocateTexture(unsigned int index, Item *i); + void deallocateTexture(unsigned int index); + void setItems(CollectionInfo *info); + void destroyItems(); + void setPoints(std::vector *scrollPoints, std::vector *tweenPoints); + void setScrollDirection(ScrollDirection direction); + void pageUp(); + void pageDown(); + void letterUp(); + void letterDown(); + void letterChange(bool increment); + bool isIdle(); unsigned int getScrollOffsetIndex(); void setScrollOffsetIndex(unsigned int index); - void setSelectedIndex(int selectedIndex); - ComponentItemBinding *getSelectedCollectionItemSprite(); - ComponentItemBinding *getPendingCollectionItemSprite(); - ComponentItemBinding *getPendingSelectedCollectionItemSprite(); - void addComponentForNotifications(MenuNotifierInterface *c); - void removeComponentForNotifications(MenuNotifierInterface *c); - std::vector *getCollectionItemSprites(); - void removeSelectedItem(); - void freeGraphicsMemory(); - void update(float dt); - void draw(); - void draw(unsigned int layer); - void setScrollAcceleration(float value); - void setStartScrollTime(float value); - bool horizontalScroll; - -private: - void click(double nextScrollTime); - void deallocateSpritePoints(); - void allocateSpritePoints(); - void updateSprite(unsigned int spriteIndex, unsigned int pointIndex, bool newScroll, float dt, double nextScrollTime); - unsigned int getNextTween(unsigned int currentIndex, std::vector *list); - void resetTweens(Component *c, AnimationEvents *sets, ViewInfo *currentViewInfo, ViewInfo *nextViewInfo, double scrollTime); - - enum ScrollState - { - ScrollStateActive, - ScrollStatePageChange, - ScrollStateStopping, - ScrollStateIdle - }; - - std::vector *spriteList_; - std::vector *scrollPoints_; - std::vector *tweenPoints_; - std::vector notificationComponents_; - float tweenEnterTime_; - bool focus_; - - unsigned int firstSpriteIndex_; - unsigned int selectedSpriteListIndex_; - bool scrollStopRequested_; - bool notifyAllRequested_; - ScrollDirection currentScrollDirection_; - ScrollDirection requestedScrollDirection_; - ScrollState currentScrollState_; - float scrollAcceleration_; - float startScrollTime_; - float scrollPeriod_; - - int circularIncrement(unsigned int index, unsigned int offset, std::vector *list); - void circularIncrement(unsigned &index, std::vector *list); - void circularDecrement(unsigned &index, std::vector *list); - void circularIncrement(unsigned &index, std::vector *list); - void circularDecrement(unsigned &index, std::vector *list); - void updateOffset(float dt); - - std::string collection_; - Configuration &config_; - float scaleX_; - float scaleY_; - Font *fontInst_; - std::string layoutKey_; - std::string imageType_; -}; - + void setSelectedIndex(int selectedIndex); + Item *getPendingItem(); + void addComponentForNotifications(MenuNotifierInterface *c); + void removeComponentForNotifications(MenuNotifierInterface *c); + void freeGraphicsMemory(); + void update(float dt); + void draw(); + void draw(unsigned int layer); + void setScrollAcceleration(float value); + void setStartScrollTime(float value); + bool horizontalScroll; + + +private: + void click(double nextScrollTime); + void deallocateSpritePoints(); + void allocateSpritePoints(); + void resetTweens(Component *c, AnimationEvents *sets, ViewInfo *currentViewInfo, ViewInfo *nextViewInfo, double scrollTime); + unsigned int loopIncrement(unsigned int offset, unsigned int i, unsigned int size); + unsigned int loopDecrement(unsigned int offset, unsigned int i, unsigned int size); + + enum ScrollState + { + ScrollStateActive, + ScrollStatePageChange, + ScrollStateStopping, + ScrollStateIdle + }; + + std::vector *spriteList_; + std::vector *scrollPoints_; + std::vector *tweenPoints_; + std::vector notificationComponents_; + bool focus_; + + unsigned int itemIndex_; + unsigned int componentIndex_; + unsigned int selectedOffsetIndex_; + + bool scrollStopRequested_; + bool notifyAllRequested_; + + ScrollDirection currentScrollDirection_; + ScrollDirection requestedScrollDirection_; + ScrollState currentScrollState_; + + float scrollAcceleration_; + float startScrollTime_; + float scrollPeriod_; + + Configuration &config_; + float scaleX_; + float scaleY_; + Font *fontInst_; + std::string layoutKey_; + std::string imageType_; + CollectionInfo *collection_; + + + std::vector *items_; + std::vector components_; + +}; + diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index 7a4c3eb..d16b578 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -411,7 +411,6 @@ void Page::letterScroll(ScrollDirection direction) bool Page::pushCollection(CollectionInfo *collection) { collections_.push_back(collection); - std::vector *sprites = ComponentItemBindingBuilder::buildCollectionItems(&collection->items); int menuExitIndex = -1; int menuEnterIndex = -1; @@ -436,7 +435,7 @@ bool Page::pushCollection(CollectionInfo *collection) activeMenu_ = menus_[menuDepth_]; activeMenu_->collectionName = collection->name; activeMenu_->destroyItems(); - activeMenu_->setItems(sprites); + activeMenu_->setItems(collection); activeMenu_->triggerMenuEnterEvent(); playlist_ = collection->playlists.begin(); @@ -515,10 +514,6 @@ bool Page::popCollection() } } - if(collection) - { - delete collection; - } return true; } @@ -529,10 +524,8 @@ void Page::nextPlaylist() playlist_++; if(playlist_ == collection->playlists.end()) playlist_ = collection->playlists.begin(); - std::vector *sprites = ComponentItemBindingBuilder::buildCollectionItems(&playlist_->second); - activeMenu_->destroyItems(); - activeMenu_->setItems(sprites); + activeMenu_->setItems(collection); activeMenu_->triggerMenuEnterEvent(); } From b5e3384893c5312441d4d18ada18c240c22e5992 Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Tue, 4 Aug 2015 15:23:54 -0500 Subject: [PATCH 04/43] Cleanup ScrollingList logic. --- .../Graphics/Component/ScrollingList.cpp | 49 ++++++++----------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index c4e6a21..a4de020 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -91,7 +91,6 @@ ScrollingList::ScrollingList(const ScrollingList ©) , imageType_(copy.imageType_) , items_(NULL) { - scrollPoints_ = NULL; tweenPoints_ = NULL; @@ -125,7 +124,6 @@ ScrollingList::~ScrollingList() void ScrollingList::setItems(CollectionInfo *info) { - std::cout << "setItems" << std::endl; deallocateSpritePoints(); collection_ = info; @@ -149,8 +147,7 @@ unsigned int ScrollingList::loopIncrement(unsigned int offset, unsigned int i, u unsigned int ScrollingList::loopDecrement(unsigned int offset, unsigned int i, unsigned int size) { if(size == 0) return 0; - // (A - B) % C = ((A % C) - (B % C)) % C - return ((offset % size) - (i % size) ) % size; + return ((offset % size) - (i % size) + size) % size; } @@ -170,12 +167,15 @@ void ScrollingList::deallocateSpritePoints() { deallocateTexture(i); } + + componentIndex_ = 0; } void ScrollingList::allocateSpritePoints() { for(unsigned int i = 0; items_ && i < scrollPoints_->size(); ++i) { + componentIndex_ = 0; unsigned int index = loopIncrement(itemIndex_, i, items_->size()); Item *item = items_->at(index); @@ -232,35 +232,27 @@ void ScrollingList::setSelectedIndex(int selectedIndex) void ScrollingList::click(double nextScrollTime) { - ViewInfo *cur; - ViewInfo *next; if(currentScrollDirection_ == ScrollDirectionBack) { - next = scrollPoints_->at(componentIndex_); - itemIndex_ = loopIncrement(itemIndex_, 1, items_->size()); - componentIndex_ = loopIncrement(componentIndex_, 1, components_.size()); - cur = scrollPoints_->at(componentIndex_); + // get the previous item + itemIndex_ = loopDecrement(itemIndex_, 1, items_->size()); + Item *i = items_->at(itemIndex_); + + componentIndex_ = loopDecrement(componentIndex_, 1, components_.size()); + + deallocateTexture(componentIndex_); + allocateTexture(componentIndex_, i); } else if(currentScrollDirection_ == ScrollDirectionForward) { - next = scrollPoints_->at(componentIndex_); - itemIndex_ = loopDecrement(itemIndex_, 1, items_->size()); - componentIndex_ = loopDecrement(componentIndex_, 1, components_.size()); - cur = scrollPoints_->at(componentIndex_); + itemIndex_ = loopIncrement(itemIndex_, 1, items_->size()); + Item *i = items_->at(itemIndex_); + + deallocateTexture(componentIndex_); + allocateTexture(componentIndex_, i); + + componentIndex_ = loopIncrement(componentIndex_, 1, components_.size()); } - else - { - return; - } - - Item *i = items_->at(itemIndex_); - - deallocateTexture(componentIndex_); - allocateTexture(componentIndex_, i); - Component *c = components_.at(componentIndex_); - - resetTweens(c, tweenPoints_->at(componentIndex_), cur, next, 0); - } void ScrollingList::pageUp() @@ -416,7 +408,8 @@ void ScrollingList::update(float dt) for(unsigned int i = 0; i < tweenPoints_->size(); ++i) { - Component *c = components_.at(i); + unsigned int cindex = loopIncrement(componentIndex_, i, components_.size()); + Component *c = components_.at(cindex); if(c) c->setTweens(tweenPoints_->at(i)); } From 9330e85f31eeb0a172c94f7fcdcdad54909dbd11 Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Tue, 4 Aug 2015 16:57:47 -0500 Subject: [PATCH 05/43] Checkpoint, forward scrolling broken --- .../Graphics/Component/ScrollingList.cpp | 37 +++++-------------- .../Source/Graphics/Component/ScrollingList.h | 1 - 2 files changed, 9 insertions(+), 29 deletions(-) diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index a4de020..7e44526 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -75,6 +75,8 @@ ScrollingList::ScrollingList(const ScrollingList ©) , horizontalScroll(copy.horizontalScroll) , spriteList_(NULL) , focus_(false) + , itemIndex_(0) + , componentIndex_(0) , scrollStopRequested_(true) , notifyAllRequested_(false) , currentScrollDirection_(ScrollDirectionIdle) @@ -237,7 +239,6 @@ void ScrollingList::click(double nextScrollTime) // get the previous item itemIndex_ = loopDecrement(itemIndex_, 1, items_->size()); Item *i = items_->at(itemIndex_); - componentIndex_ = loopDecrement(componentIndex_, 1, components_.size()); deallocateTexture(componentIndex_); @@ -248,6 +249,7 @@ void ScrollingList::click(double nextScrollTime) itemIndex_ = loopIncrement(itemIndex_, 1, items_->size()); Item *i = items_->at(itemIndex_); + deallocateTexture(componentIndex_); allocateTexture(componentIndex_, i); @@ -402,9 +404,9 @@ void ScrollingList::update(float dt) { if(currentScrollState_ == ScrollStateStopping) { - click(0); currentScrollState_ = ScrollStateIdle; scrollStopped = true; + click(0); for(unsigned int i = 0; i < tweenPoints_->size(); ++i) { @@ -433,11 +435,11 @@ void ScrollingList::update(float dt) for(unsigned int i = 0; i < scrollPoints_->size(); i++) { unsigned int cindex = loopIncrement(componentIndex_, i, components_.size()); + Component *c = components_.at(cindex); if(c && (scrollRequested || scrollChanged)) { - ViewInfo *currentvi = scrollPoints_->at(i); unsigned int nextI = 0; if(currentScrollDirection_ == ScrollDirectionBack) { @@ -448,6 +450,7 @@ void ScrollingList::update(float dt) nextI = loopDecrement(i, 1, scrollPoints_->size()); } + ViewInfo *currentvi = scrollPoints_->at(i); ViewInfo *nextvi = scrollPoints_->at(nextI); resetTweens(c, tweenPoints_->at(i), currentvi, nextvi, scrollPeriod_); @@ -460,7 +463,9 @@ void ScrollingList::update(float dt) if(scrollStopped || (notifyAllRequested_ && focus_)) { - Item *item = getPendingItem(); + Item *item = NULL; + unsigned index = loopIncrement(itemIndex_, selectedOffsetIndex_, items_->size()); + item = items_->at(index); for(std::vector::iterator it = notificationComponents_.begin(); it != notificationComponents_.end(); @@ -651,30 +656,6 @@ void ScrollingList::removeComponentForNotifications(MenuNotifierInterface *c) } } - -Item* ScrollingList::getPendingItem() -{ - Item *item = NULL; - - if(items_ && items_->size() > 0) - { - unsigned int index = itemIndex_; - - if(currentScrollDirection_ == ScrollDirectionBack) - { - index = loopDecrement(index, 1, items_->size()); - } - if(currentScrollDirection_ == ScrollDirectionForward) - { - index = loopIncrement(index, 1, items_->size()); - } - - item = items_->at(index); - } - - return item; -} - bool ScrollingList::isIdle() { return (Component::isIdle() && currentScrollState_ == ScrollStateIdle); diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.h b/RetroFE/Source/Graphics/Component/ScrollingList.h index d0f45f0..2522aa8 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.h +++ b/RetroFE/Source/Graphics/Component/ScrollingList.h @@ -69,7 +69,6 @@ public: unsigned int getScrollOffsetIndex(); void setScrollOffsetIndex(unsigned int index); void setSelectedIndex(int selectedIndex); - Item *getPendingItem(); void addComponentForNotifications(MenuNotifierInterface *c); void removeComponentForNotifications(MenuNotifierInterface *c); void freeGraphicsMemory(); From c20ac31fea22af9e9c762e08ea77b1fdf429b969 Mon Sep 17 00:00:00 2001 From: emb <> Date: Wed, 5 Aug 2015 10:44:27 -0500 Subject: [PATCH 06/43] Scrolling now works. ReloadableImages are not always updating properly from component states. --- RetroFE/Source/Graphics/Component/ScrollingList.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index 7e44526..99dbf3e 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -36,7 +36,7 @@ #include #include #include - +#include //todo: remove coupling from configuration data (if possible) ScrollingList::ScrollingList(Configuration &c, @@ -246,10 +246,10 @@ void ScrollingList::click(double nextScrollTime) } else if(currentScrollDirection_ == ScrollDirectionForward) { + unsigned int itemIncrement = loopIncrement(itemIndex_, scrollPoints_->size(), items_->size()); itemIndex_ = loopIncrement(itemIndex_, 1, items_->size()); - Item *i = items_->at(itemIndex_); + Item *i = items_->at(itemIncrement); - deallocateTexture(componentIndex_); allocateTexture(componentIndex_, i); From 3fc64ed01d07723b5f317078da1e23149de7333f Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Thu, 6 Aug 2015 09:18:04 -0500 Subject: [PATCH 07/43] Set viewInfo when allocating tweens --- RetroFE/Source/Graphics/Component/ScrollingList.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index 99dbf3e..b622429 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -243,6 +243,10 @@ void ScrollingList::click(double nextScrollTime) deallocateTexture(componentIndex_); allocateTexture(componentIndex_, i); + + Component *c = components_.at(componentIndex_); + ViewInfo *v = scrollPoints_->at(0); + resetTweens(c, tweenPoints_->at(componentIndex_), v, v, 0); } else if(currentScrollDirection_ == ScrollDirectionForward) { @@ -253,6 +257,10 @@ void ScrollingList::click(double nextScrollTime) deallocateTexture(componentIndex_); allocateTexture(componentIndex_, i); + Component *c = components_.at(componentIndex_); + ViewInfo *v = scrollPoints_->back(); + resetTweens(c, tweenPoints_->at(componentIndex_), v, v, 0); + componentIndex_ = loopIncrement(componentIndex_, 1, components_.size()); } } From 8fdc7ece6436ff8cdd5d47713c6e202d4c59d79c Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Thu, 6 Aug 2015 13:17:40 -0500 Subject: [PATCH 08/43] Supporting favorites --- RetroFE/Source/Collection/CollectionInfo.cpp | 12 +++ RetroFE/Source/Collection/CollectionInfo.h | 2 +- .../Collection/CollectionInfoBuilder.cpp | 12 ++- RetroFE/Source/Collection/MenuParser.cpp | 3 - .../Graphics/Component/ScrollingList.cpp | 44 +++++---- .../Source/Graphics/Component/ScrollingList.h | 4 +- RetroFE/Source/Graphics/Page.cpp | 95 +++++++++++++------ RetroFE/Source/Graphics/Page.h | 17 +++- 8 files changed, 129 insertions(+), 60 deletions(-) diff --git a/RetroFE/Source/Collection/CollectionInfo.cpp b/RetroFE/Source/Collection/CollectionInfo.cpp index d74955b..85ac94c 100644 --- a/RetroFE/Source/Collection/CollectionInfo.cpp +++ b/RetroFE/Source/Collection/CollectionInfo.cpp @@ -51,6 +51,18 @@ CollectionInfo::~CollectionInfo() } + Playlists_T::iterator pit = playlists.begin(); + + while(pit != playlists.end()) + { + if(pit->second != &items) + { + delete pit->second; + } + playlists.erase(pit); + pit = playlists.begin(); + } + std::vector::iterator it = items.begin(); while(it != items.end()) { diff --git a/RetroFE/Source/Collection/CollectionInfo.h b/RetroFE/Source/Collection/CollectionInfo.h index d4086da..b6450ec 100644 --- a/RetroFE/Source/Collection/CollectionInfo.h +++ b/RetroFE/Source/Collection/CollectionInfo.h @@ -37,7 +37,7 @@ public: std::string launcher; std::vector items; - typedef std::map > Playlists_T; + typedef std::map *> Playlists_T; Playlists_T playlists; private: diff --git a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp index 595b70c..475a18b 100644 --- a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp +++ b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp @@ -279,6 +279,8 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me std::vector::iterator extensionsIt; info->extensionList(extensions); + info->playlists["all"] = &info->items; + info->playlists["favorites"] = new std::vector(); dp = opendir(path.c_str()); @@ -300,10 +302,11 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me } } } - for(std::map::iterator it = favoritesFilter.begin(); it != favoritesFilter.end(); it++) - { - info->playlists["favorites"].push_back(it->second); - } + // add the favorites list + for(std::map::iterator it = favoritesFilter.begin(); it != favoritesFilter.end(); it++) + { + info->playlists["favorites"]->push_back(it->second); + } while((dirp = readdir(dp)) != NULL) { @@ -334,7 +337,6 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me i->collectionInfo = info; info->items.push_back(i); - info->playlists["include"].push_back(i); } } } diff --git a/RetroFE/Source/Collection/MenuParser.cpp b/RetroFE/Source/Collection/MenuParser.cpp index 5e62290..766dc75 100644 --- a/RetroFE/Source/Collection/MenuParser.cpp +++ b/RetroFE/Source/Collection/MenuParser.cpp @@ -149,9 +149,6 @@ bool MenuParser::buildLegacyXmlMenu(CollectionInfo *collection, bool sort) } - std::sort( collection->items.begin(), collection->items.end(), VectorSort); - - // todo: sorting should occur within the collection itself, not externally if(sort) { // sort the menu if requested diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index b622429..d140618 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -124,15 +124,12 @@ ScrollingList::~ScrollingList() } -void ScrollingList::setItems(CollectionInfo *info) +void ScrollingList::setItems(std::vector *items) { deallocateSpritePoints(); - collection_ = info; - items_ = &collection_->items; - + items_ = items; itemIndex_ = 0; - componentIndex_ = 0; allocateSpritePoints(); @@ -175,7 +172,10 @@ void ScrollingList::deallocateSpritePoints() void ScrollingList::allocateSpritePoints() { - for(unsigned int i = 0; items_ && i < scrollPoints_->size(); ++i) + if(!items_ || items_->size() == 0) return; + if(!scrollPoints_) return; + + for(unsigned int i = 0; i < scrollPoints_->size(); ++i) { componentIndex_ = 0; unsigned int index = loopIncrement(itemIndex_, i, items_->size()); @@ -210,10 +210,11 @@ void ScrollingList::setPoints(std::vector *scrollPoints, std::vector // empty out the list as we will resize it components_.clear(); - if(scrollPoints && scrollPoints_->size() > components_.size()) - { - components_.resize(scrollPoints_->size(), NULL); - } + int size = 0; + + if(scrollPoints) size = scrollPoints_->size(); + components_.resize(size); + allocateSpritePoints(); } @@ -378,12 +379,13 @@ void ScrollingList::update(float dt) bool scrollRequested = false; bool scrollStopped = false; - // validate all scroll points are done tweening to the next position - for(unsigned int i = 0; i < components_.size(); i++) - { - Component *c = components_.at(i); + if(components_.size() == 0) return; + if(!items_ || items_->size() == 0) return; - if(c && c->isMenuScrolling()) + // validate all scroll points are done tweening to the next position + for(std::vector::iterator c = components_.begin(); c != components_.end(); c++) + { + if(*c && (*c)->isMenuScrolling()) { readyToScroll = false; break; @@ -630,6 +632,8 @@ void ScrollingList::draw() void ScrollingList::draw(unsigned int layer) { + if(components_.size() == 0) return; + for(unsigned int i = 0; i < components_.size(); ++i) { Component *c = components_.at(i); @@ -666,7 +670,15 @@ void ScrollingList::removeComponentForNotifications(MenuNotifierInterface *c) bool ScrollingList::isIdle() { - return (Component::isIdle() && currentScrollState_ == ScrollStateIdle); + if(!Component::isIdle() || currentScrollState_ != ScrollStateIdle) return false; + + for(unsigned int i = 0; i < components_.size(); ++i) + { + Component *c = components_.at(i); + if(c && !c->isIdle()) return false; + } + + return true; } diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.h b/RetroFE/Source/Graphics/Component/ScrollingList.h index 2522aa8..9680317 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.h +++ b/RetroFE/Source/Graphics/Component/ScrollingList.h @@ -56,7 +56,7 @@ public: bool allocateTexture(unsigned int index, Item *i); void deallocateTexture(unsigned int index); - void setItems(CollectionInfo *info); + void setItems(std::vector *items); void destroyItems(); void setPoints(std::vector *scrollPoints, std::vector *tweenPoints); void setScrollDirection(ScrollDirection direction); @@ -123,11 +123,11 @@ private: Font *fontInst_; std::string layoutKey_; std::string imageType_; - CollectionInfo *collection_; std::vector *items_; std::vector components_; + }; diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index d16b578..9054507 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -23,13 +23,13 @@ #include "Component/ScrollingList.h" #include "../Sound/Sound.h" #include "ComponentItemBindingBuilder.h" +#include #include Page::Page(Configuration &config) : config_(config) , activeMenu_(NULL) , menuDepth_(0) - , items_(NULL) , scrollActive_(false) , selectedItem_(NULL) , textStatusComponent_(NULL) @@ -410,7 +410,6 @@ void Page::letterScroll(ScrollDirection direction) bool Page::pushCollection(CollectionInfo *collection) { - collections_.push_back(collection); int menuExitIndex = -1; int menuEnterIndex = -1; @@ -425,6 +424,7 @@ bool Page::pushCollection(CollectionInfo *collection) menuExitIndex = menuDepth_ - 1; } + // grow the menu as needed if(menus_.size() >= menuDepth_ && activeMenu_) { ScrollingList *newList = new ScrollingList(*activeMenu_); @@ -432,12 +432,21 @@ bool Page::pushCollection(CollectionInfo *collection) pushMenu(newList); } + activeMenu_ = menus_[menuDepth_]; activeMenu_->collectionName = collection->name; - activeMenu_->destroyItems(); - activeMenu_->setItems(collection); + activeMenu_->setItems(&collection->items); activeMenu_->triggerMenuEnterEvent(); - playlist_ = collection->playlists.begin(); + + // build the collection info instance + MenuInfo_S info; + info.collection = collection; + info.menu = activeMenu_; + info.playlist = collection->playlists.begin(); + info.queueDelete = false; + collections_.push_back(info); + + playlist_ = info.playlist; if(menuDepth_ < menus_.size()) { @@ -469,18 +478,19 @@ bool Page::popCollection() { int menuExitIndex = -1; int menuEnterIndex = -1; - CollectionInfo *collection = NULL; - if(menuDepth_ <= 1) - { - return false; - } - if(collections_.size() <= 1) - { - return false; - } + if(!activeMenu_) return false; + if(menuDepth_ <= 1) return false; + if(collections_.size() <= 1) return false; + + // queue the collection for deletion + MenuInfo_S &info = collections_.back(); + info.queueDelete = true; + + // get the next collection off of the stack collections_.pop_back(); - collection = collections_.back(); + info = collections_.back(); + playlist_ = info.playlist; if(activeMenu_) { @@ -500,7 +510,7 @@ bool Page::popCollection() { for(std::vector::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) { - (*it)->collectionName = collection->name; + (*it)->collectionName = info.collection->name; if(menuEnterIndex >= 0) { @@ -514,18 +524,25 @@ bool Page::popCollection() } } - return true; } void Page::nextPlaylist() { - CollectionInfo *collection = collections_.back(); - playlist_++; - if(playlist_ == collection->playlists.end()) playlist_ = collection->playlists.begin(); + MenuInfo_S &info = collections_.back(); + unsigned int numlists = info.collection->playlists.size(); - activeMenu_->destroyItems(); - activeMenu_->setItems(collection); + for(unsigned int i = 0; i <= numlists; ++i) + { + 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(); } @@ -555,7 +572,28 @@ void Page::update(float dt) { for(std::vector::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) { - (*it)->update(dt); + if(*it) (*it)->update(dt); + } + } + + // many nodes still have handles on the collection info. We need to delete + // them once everything is done using them + std::list::iterator del = collections_.begin(); + + while(del != collections_.end()) + { + MenuInfo_S &info = *del; + if(info.queueDelete && info.menu && info.menu->isIdle()) + { + std::list::iterator next = del; + ++next; + + if(info.collection) delete info.collection; + collections_.erase(del); + } + else + { + ++del; } } } @@ -566,7 +604,7 @@ void Page::draw() { for(std::vector::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) { - (*it)->draw(); + if(*it) (*it)->draw(); } for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++) @@ -580,14 +618,11 @@ void Page::draw() std::string Page::getCollectionName() { - CollectionInfo *info = collections_.back(); + if(collections_.size() == 0) return ""; - if(info) - { - return info->name; - } + MenuInfo_S &info = collections_.back(); + return info.collection->name; - return ""; } void Page::freeGraphicsMemory() diff --git a/RetroFE/Source/Graphics/Page.h b/RetroFE/Source/Graphics/Page.h index 2591d5e..cbf6406 100644 --- a/RetroFE/Source/Graphics/Page.h +++ b/RetroFE/Source/Graphics/Page.h @@ -84,17 +84,28 @@ private: void highlight(); std::string collectionName_; Configuration &config_; + + struct MenuInfo_S + { + CollectionInfo *collection; + ScrollingList *menu; + CollectionInfo::Playlists_T::iterator playlist; + bool queueDelete; + }; + typedef std::vector MenuVector_T; - typedef std::vector CollectionInfo_T; + typedef std::list CollectionVector_T; ScrollingList *activeMenu_; unsigned int menuDepth_; MenuVector_T menus_; - CollectionInfo_T collections_; + CollectionVector_T collections_; static const unsigned int NUM_LAYERS = 8; std::vector LayerComponents[NUM_LAYERS]; - std::vector *items_; + std::list deleteMenuList_; + std::list deleteCollectionList_; + bool scrollActive_; Item *selectedItem_; From a778d36aa16f2b3c2b075fcfa9c4159fd23b409c Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Thu, 6 Aug 2015 13:30:13 -0500 Subject: [PATCH 09/43] Fixed scrolling speed for playlist toggling --- RetroFE/Source/RetroFE.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index 8cc0a88..e974fe9 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -447,7 +447,8 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) if (!input_.keystate(UserInput::KeyCodePageUp) && !input_.keystate(UserInput::KeyCodePageDown) && !input_.keystate(UserInput::KeyCodeLetterUp) && - !input_.keystate(UserInput::KeyCodeLetterDown)) + !input_.keystate(UserInput::KeyCodeLetterDown) && + !input_.keystate(UserInput::KeyCodeNextPlaylist)) { keyLastTime_ = 0; keyDelayTime_= 0.3f; @@ -475,6 +476,10 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) { page->letterScroll(Page::ScrollDirectionForward); } + if(input_.keystate(UserInput::KeyCodeNextPlaylist)) + { + page->nextPlaylist(); + } } if (input_.keystate(UserInput::KeyCodeAdminMode)) @@ -512,10 +517,6 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) } } } - if(input_.keystate(UserInput::KeyCodeNextPlaylist) && page->isMenuIdle()) - { - page->nextPlaylist(); - } if (input_.keystate(UserInput::KeyCodeBack) && page->isMenuIdle()) { From bea64006c93530ff4b56c21172748ac1e2b80617 Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Thu, 6 Aug 2015 14:15:46 -0500 Subject: [PATCH 10/43] Supporting reloadable text tag --- .../Source/Graphics/Component/Component.cpp | 918 +++++++++--------- RetroFE/Source/Graphics/Component/Component.h | 3 + .../Graphics/Component/ReloadableText.cpp | 10 +- .../Graphics/Component/ReloadableText.h | 1 + RetroFE/Source/Graphics/Page.cpp | 48 +- RetroFE/Source/Graphics/Page.h | 2 + 6 files changed, 513 insertions(+), 469 deletions(-) diff --git a/RetroFE/Source/Graphics/Component/Component.cpp b/RetroFE/Source/Graphics/Component/Component.cpp index 31b03ce..3fcb79f 100644 --- a/RetroFE/Source/Graphics/Component/Component.cpp +++ b/RetroFE/Source/Graphics/Component/Component.cpp @@ -1,460 +1,466 @@ -/* This file is part of RetroFE. - * - * RetroFE is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RetroFE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RetroFE. If not, see . - */ -#include "Component.h" -#include "../Animate/Tween.h" -#include "../../Graphics/ViewInfo.h" -#include "../../Utility/Log.h" -#include "../../SDL.h" - -Component::Component() -{ - tweens_ = NULL; - selectedItem_ = NULL; - newItemSelectedSinceEnter = false; - backgroundTexture_ = NULL; - freeGraphicsMemory(); - -} - -Component::Component(const Component ©) -{ - tweens_ = NULL; - selectedItem_ = NULL; - newItemSelectedSinceEnter = false; - backgroundTexture_ = NULL; - freeGraphicsMemory(); - +/* This file is part of RetroFE. + * + * RetroFE is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RetroFE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RetroFE. If not, see . + */ +#include "Component.h" +#include "../Animate/Tween.h" +#include "../../Graphics/ViewInfo.h" +#include "../../Utility/Log.h" +#include "../../SDL.h" + +Component::Component() +{ + tweens_ = NULL; + selectedItem_ = NULL; + newItemSelectedSinceEnter = false; + backgroundTexture_ = NULL; + freeGraphicsMemory(); + +} + +Component::Component(const Component ©) +{ + tweens_ = NULL; + selectedItem_ = NULL; + newItemSelectedSinceEnter = false; + backgroundTexture_ = NULL; + freeGraphicsMemory(); + if(copy.tweens_) { AnimationEvents *tweens = new AnimationEvents(*copy.tweens_); setTweens(tweens); - } - - -} - -Component::~Component() -{ - freeGraphicsMemory(); -} - -void Component::freeGraphicsMemory() -{ - currentAnimationState = HIDDEN; - enterRequested = false; - exitRequested = false; - menuEnterRequested = false; - menuEnterIndex = -1; - menuScrollRequested = false; - menuExitRequested = false; - menuExitIndex = -1; - - newItemSelected = false; - highlightExitComplete = false; - currentTweens_ = NULL; - currentTweenIndex_ = 0; - currentTweenComplete_ = false; - elapsedTweenTime_ = 0; - scrollActive = false; - - if(backgroundTexture_) - { - SDL_LockMutex(SDL::getMutex()); - SDL_DestroyTexture(backgroundTexture_); - SDL_UnlockMutex(SDL::getMutex()); - - backgroundTexture_ = NULL; - } -} -void Component::allocateGraphicsMemory() -{ - if(!backgroundTexture_) - { - // make a 4x4 pixel wide surface to be stretched during rendering, make it a white background so we can use - // color later - SDL_Surface *surface = SDL_CreateRGBSurface(0, 4, 4, 32, 0, 0, 0, 0); - SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 255, 255, 255)); - - SDL_LockMutex(SDL::getMutex()); - backgroundTexture_ = SDL_CreateTextureFromSurface(SDL::getRenderer(), surface); - SDL_UnlockMutex(SDL::getMutex()); - - SDL_FreeSurface(surface); - SDL_SetTextureBlendMode(backgroundTexture_, SDL_BLENDMODE_BLEND); - } -} - -Item *Component::getSelectedItem() -{ - return selectedItem_; -} - -void Component::triggerEnterEvent() -{ - enterRequested = true; -} - -void Component::triggerExitEvent() -{ - 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(Item *selectedItem) -{ - newItemSelected = true; - this->selectedItem_ = selectedItem; -} - - -bool Component::isIdle() -{ - return (currentAnimationState == IDLE); -} - -bool Component::isHidden() -{ - return (currentAnimationState == HIDDEN); -} -bool Component::isWaiting() -{ - return (currentAnimationState == HIGHLIGHT_WAIT); -} - -bool Component::isMenuScrolling() -{ - return (currentAnimationState == MENU_ENTER || currentAnimationState == MENU_SCROLL || currentAnimationState == MENU_EXIT || menuScrollRequested); -} - -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)) - { - currentTweenComplete_ = true; - } - - 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; - } - - currentTweenComplete_ = animate(isIdle()); -} - -void Component::draw() -{ - - if(backgroundTexture_) - { - SDL_Rect rect; - rect.h = static_cast(baseViewInfo.ScaledHeight()); - rect.w = static_cast(baseViewInfo.ScaledWidth()); - rect.x = static_cast(baseViewInfo.XRelativeToOrigin()); - rect.y = static_cast(baseViewInfo.YRelativeToOrigin()); - - - SDL_SetTextureColorMod(backgroundTexture_, - static_cast(baseViewInfo.BackgroundRed*255), - static_cast(baseViewInfo.BackgroundGreen*255), - static_cast(baseViewInfo.BackgroundBlue*255)); - - SDL::renderCopy(backgroundTexture_, static_cast(baseViewInfo.BackgroundAlpha*255), NULL, &rect, baseViewInfo.Angle); - } -} - -bool Component::animate(bool loop) -{ - bool completeDone = false; - if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->size()) - { - completeDone = true; - } - else if(currentTweens_) - { - bool currentDone = true; - TweenSet *tweens = currentTweens_->tweenSet(currentTweenIndex_); - - for(unsigned int i = 0; i < tweens->size(); i++) - { - Tween *tween = tweens->tweens()->at(i); - double elapsedTime = elapsedTweenTime_; - - //todo: too many levels of nesting - if(elapsedTime < tween->duration) - { - currentDone = false; - } - else - { - elapsedTime = static_cast(tween->duration); - } - - float value = tween->animate(elapsedTime); - - switch(tween->property) - { - case TWEEN_PROPERTY_X: - baseViewInfo.X = value; - break; - - case TWEEN_PROPERTY_Y: - baseViewInfo.Y = value; - break; - - case TWEEN_PROPERTY_HEIGHT: - baseViewInfo.Height = value; - break; - - case TWEEN_PROPERTY_WIDTH: - baseViewInfo.Width = value; - break; - - case TWEEN_PROPERTY_ANGLE: - baseViewInfo.Angle = value; - break; - - case TWEEN_PROPERTY_ALPHA: - baseViewInfo.Alpha = value; - break; - - case TWEEN_PROPERTY_X_ORIGIN: - baseViewInfo.XOrigin = value; - break; - - case TWEEN_PROPERTY_Y_ORIGIN: - baseViewInfo.YOrigin = value; - break; - - case TWEEN_PROPERTY_X_OFFSET: - baseViewInfo.XOffset = value; - break; - - case TWEEN_PROPERTY_Y_OFFSET: - baseViewInfo.YOffset = value; - break; - - case TWEEN_PROPERTY_FONT_SIZE: - baseViewInfo.FontSize = value; - break; - - case TWEEN_PROPERTY_BACKGROUND_ALPHA: - baseViewInfo.BackgroundAlpha = value; - break; - } - } - - if(currentDone) - { - currentTweenIndex_++; - elapsedTweenTime_ = 0; - } - } - - if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->tweenSets()->size()) - { - if(loop) - { - currentTweenIndex_ = 0; - } - completeDone = true; - } - - return completeDone; -} + } + + +} + +Component::~Component() +{ + freeGraphicsMemory(); +} + +void Component::freeGraphicsMemory() +{ + currentAnimationState = HIDDEN; + enterRequested = false; + exitRequested = false; + menuEnterRequested = false; + menuEnterIndex = -1; + menuScrollRequested = false; + menuExitRequested = false; + menuExitIndex = -1; + + newItemSelected = false; + playlistChanged = false; + highlightExitComplete = false; + currentTweens_ = NULL; + currentTweenIndex_ = 0; + currentTweenComplete_ = false; + elapsedTweenTime_ = 0; + scrollActive = false; + + if(backgroundTexture_) + { + SDL_LockMutex(SDL::getMutex()); + SDL_DestroyTexture(backgroundTexture_); + SDL_UnlockMutex(SDL::getMutex()); + + backgroundTexture_ = NULL; + } +} +void Component::allocateGraphicsMemory() +{ + if(!backgroundTexture_) + { + // make a 4x4 pixel wide surface to be stretched during rendering, make it a white background so we can use + // color later + SDL_Surface *surface = SDL_CreateRGBSurface(0, 4, 4, 32, 0, 0, 0, 0); + SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 255, 255, 255)); + + SDL_LockMutex(SDL::getMutex()); + backgroundTexture_ = SDL_CreateTextureFromSurface(SDL::getRenderer(), surface); + SDL_UnlockMutex(SDL::getMutex()); + + SDL_FreeSurface(surface); + SDL_SetTextureBlendMode(backgroundTexture_, SDL_BLENDMODE_BLEND); + } +} + +Item *Component::getSelectedItem() +{ + return selectedItem_; +} + +void Component::triggerEnterEvent() +{ + enterRequested = true; +} + +void Component::triggerExitEvent() +{ + 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(Item *selectedItem) +{ + newItemSelected = true; + this->selectedItem_ = selectedItem; +} + +void Component::triggerPlaylistChangeEvent(std::string name) +{ + playlistChanged = true; + this->playlistName = name; +} + +bool Component::isIdle() +{ + return (currentAnimationState == IDLE); +} + +bool Component::isHidden() +{ + return (currentAnimationState == HIDDEN); +} +bool Component::isWaiting() +{ + return (currentAnimationState == HIGHLIGHT_WAIT); +} + +bool Component::isMenuScrolling() +{ + return (currentAnimationState == MENU_ENTER || currentAnimationState == MENU_SCROLL || currentAnimationState == MENU_EXIT || menuScrollRequested); +} + +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)) + { + currentTweenComplete_ = true; + } + + 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; + } + + currentTweenComplete_ = animate(isIdle()); +} + +void Component::draw() +{ + + if(backgroundTexture_) + { + SDL_Rect rect; + rect.h = static_cast(baseViewInfo.ScaledHeight()); + rect.w = static_cast(baseViewInfo.ScaledWidth()); + rect.x = static_cast(baseViewInfo.XRelativeToOrigin()); + rect.y = static_cast(baseViewInfo.YRelativeToOrigin()); + + + SDL_SetTextureColorMod(backgroundTexture_, + static_cast(baseViewInfo.BackgroundRed*255), + static_cast(baseViewInfo.BackgroundGreen*255), + static_cast(baseViewInfo.BackgroundBlue*255)); + + SDL::renderCopy(backgroundTexture_, static_cast(baseViewInfo.BackgroundAlpha*255), NULL, &rect, baseViewInfo.Angle); + } +} + +bool Component::animate(bool loop) +{ + bool completeDone = false; + if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->size()) + { + completeDone = true; + } + else if(currentTweens_) + { + bool currentDone = true; + TweenSet *tweens = currentTweens_->tweenSet(currentTweenIndex_); + + for(unsigned int i = 0; i < tweens->size(); i++) + { + Tween *tween = tweens->tweens()->at(i); + double elapsedTime = elapsedTweenTime_; + + //todo: too many levels of nesting + if(elapsedTime < tween->duration) + { + currentDone = false; + } + else + { + elapsedTime = static_cast(tween->duration); + } + + float value = tween->animate(elapsedTime); + + switch(tween->property) + { + case TWEEN_PROPERTY_X: + baseViewInfo.X = value; + break; + + case TWEEN_PROPERTY_Y: + baseViewInfo.Y = value; + break; + + case TWEEN_PROPERTY_HEIGHT: + baseViewInfo.Height = value; + break; + + case TWEEN_PROPERTY_WIDTH: + baseViewInfo.Width = value; + break; + + case TWEEN_PROPERTY_ANGLE: + baseViewInfo.Angle = value; + break; + + case TWEEN_PROPERTY_ALPHA: + baseViewInfo.Alpha = value; + break; + + case TWEEN_PROPERTY_X_ORIGIN: + baseViewInfo.XOrigin = value; + break; + + case TWEEN_PROPERTY_Y_ORIGIN: + baseViewInfo.YOrigin = value; + break; + + case TWEEN_PROPERTY_X_OFFSET: + baseViewInfo.XOffset = value; + break; + + case TWEEN_PROPERTY_Y_OFFSET: + baseViewInfo.YOffset = value; + break; + + case TWEEN_PROPERTY_FONT_SIZE: + baseViewInfo.FontSize = value; + break; + + case TWEEN_PROPERTY_BACKGROUND_ALPHA: + baseViewInfo.BackgroundAlpha = value; + break; + } + } + + if(currentDone) + { + currentTweenIndex_++; + elapsedTweenTime_ = 0; + } + } + + if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->tweenSets()->size()) + { + if(loop) + { + currentTweenIndex_ = 0; + } + completeDone = true; + } + + return completeDone; +} diff --git a/RetroFE/Source/Graphics/Component/Component.h b/RetroFE/Source/Graphics/Component/Component.h index 78d20e9..d8b8a26 100644 --- a/RetroFE/Source/Graphics/Component/Component.h +++ b/RetroFE/Source/Graphics/Component/Component.h @@ -40,6 +40,7 @@ public: void triggerMenuExitEvent(int menuIndex = -1); void triggerMenuScrollEvent(); void triggerHighlightEvent(Item *selectedItem); + void triggerPlaylistChangeEvent(std::string name); bool isIdle(); bool isHidden(); bool isWaiting(); @@ -78,6 +79,8 @@ protected: bool menuExitRequested; int menuExitIndex; bool newItemSelected; + bool playlistChanged; + std::string playlistName; bool highlightExitComplete; bool newItemSelectedSinceEnter; private: diff --git a/RetroFE/Source/Graphics/Component/ReloadableText.cpp b/RetroFE/Source/Graphics/Component/ReloadableText.cpp index ceab954..b8454d1 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableText.cpp +++ b/RetroFE/Source/Graphics/Component/ReloadableText.cpp @@ -59,6 +59,10 @@ ReloadableText::ReloadableText(std::string type, Font *font, std::string layoutK { type_ = TextTypeGenre; } + else if(type == "playlist") + { + type_ = TextTypePlaylist; + } allocateGraphicsMemory(); } @@ -75,7 +79,8 @@ ReloadableText::~ReloadableText() void ReloadableText::update(float dt) { - if(newItemSelected) + if((type_ != TextTypePlaylist && newItemSelected) || + (type_ == TextTypePlaylist && playlistChanged)) { reloadRequested_ = true; } @@ -154,6 +159,9 @@ void ReloadableText::ReloadTexture() case TextTypeGenre: ss << selectedItem->genre; break; + case TextTypePlaylist: + ss << playlistName; + break; default: break; } diff --git a/RetroFE/Source/Graphics/Component/ReloadableText.h b/RetroFE/Source/Graphics/Component/ReloadableText.h index 161ccb9..578ad9f 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableText.h +++ b/RetroFE/Source/Graphics/Component/ReloadableText.h @@ -43,6 +43,7 @@ private: TextTypeTitle, TextTypeManufacturer, TextTypeGenre, + TextTypePlaylist, }; void ReloadTexture(); diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index 9054507..5e9693e 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -34,6 +34,7 @@ Page::Page(Configuration &config) , selectedItem_(NULL) , textStatusComponent_(NULL) , selectedItemChanged_(false) + , playlistChanged_(false) , loadSoundChunk_(NULL) , unloadSoundChunk_(NULL) , highlightSoundChunk_(NULL) @@ -315,25 +316,39 @@ float Page::getMinShowTime() return minShowTime_; } +void Page::playlistChange() +{ + if(activeMenu_) + { + activeMenu_->triggerPlaylistChangeEvent(playlist_->first); + } + + for(unsigned int i = 0; i < NUM_LAYERS; ++i) + { + for(std::vector::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) + { + (*it)->triggerPlaylistChangeEvent(playlist_->first); + } + } +} + void Page::highlight() { Item *item = selectedItem_; - if(item) + if(!item) return; + if(activeMenu_) { - if(activeMenu_) - { - activeMenu_->triggerHighlightEvent(item); - activeMenu_->scrollActive = scrollActive_; - } + activeMenu_->triggerHighlightEvent(item); + activeMenu_->scrollActive = scrollActive_; + } - for(unsigned int i = 0; i < NUM_LAYERS; ++i) + for(unsigned int i = 0; i < NUM_LAYERS; ++i) + { + for(std::vector::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) { - for(std::vector::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) - { - (*it)->triggerHighlightEvent(item); - (*it)->scrollActive = scrollActive_; - } + (*it)->triggerHighlightEvent(item); + (*it)->scrollActive = scrollActive_; } } } @@ -447,6 +462,7 @@ bool Page::pushCollection(CollectionInfo *collection) collections_.push_back(info); playlist_ = info.playlist; + playlistChanged_ = true; if(menuDepth_ < menus_.size()) { @@ -491,6 +507,7 @@ bool Page::popCollection() collections_.pop_back(); info = collections_.back(); playlist_ = info.playlist; + playlistChanged_ = true; if(activeMenu_) { @@ -544,6 +561,7 @@ void Page::nextPlaylist() activeMenu_->setItems(playlist_->second); activeMenu_->triggerMenuEnterEvent(); + playlistChanged_ = true; } void Page::update(float dt) @@ -554,6 +572,12 @@ void Page::update(float dt) menu->update(dt); } + + if(playlistChanged_) + { + playlistChange(); + playlistChanged_ = false; + } if(selectedItemChanged_ && !scrollActive_) { diff --git a/RetroFE/Source/Graphics/Page.h b/RetroFE/Source/Graphics/Page.h index cbf6406..69ba80a 100644 --- a/RetroFE/Source/Graphics/Page.h +++ b/RetroFE/Source/Graphics/Page.h @@ -82,6 +82,7 @@ public: private: void highlight(); + void playlistChange(); std::string collectionName_; Configuration &config_; @@ -111,6 +112,7 @@ private: Item *selectedItem_; Text *textStatusComponent_; bool selectedItemChanged_; + bool playlistChanged_; Sound *loadSoundChunk_; Sound *unloadSoundChunk_; Sound *highlightSoundChunk_; From bf1286653aadde53691c6c1f7cd3e2b0fb01e06d Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Thu, 6 Aug 2015 16:19:13 -0500 Subject: [PATCH 11/43] Add key to randomly highlight a game --- Package/Environment/Common/controls.conf | 1 + RetroFE/Source/Control/UserInput.cpp | 1 + RetroFE/Source/Control/UserInput.h | 1 + RetroFE/Source/Graphics/Component/ScrollingList.cpp | 8 ++++++++ RetroFE/Source/Graphics/Component/ScrollingList.h | 1 + RetroFE/Source/Graphics/Page.cpp | 5 +++++ RetroFE/Source/Graphics/Page.h | 1 + RetroFE/Source/RetroFE.cpp | 7 ++++++- 8 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Package/Environment/Common/controls.conf b/Package/Environment/Common/controls.conf index e2946ee..638ccb3 100644 --- a/Package/Environment/Common/controls.conf +++ b/Package/Environment/Common/controls.conf @@ -7,6 +7,7 @@ pageDown = B letterUp = N letterDown = M nextPlaylist = P +random = R select = Space back = Escape quit = Q diff --git a/RetroFE/Source/Control/UserInput.cpp b/RetroFE/Source/Control/UserInput.cpp index d57bd3b..5683b69 100644 --- a/RetroFE/Source/Control/UserInput.cpp +++ b/RetroFE/Source/Control/UserInput.cpp @@ -74,6 +74,7 @@ bool UserInput::initialize() retVal = MapKey("back", KeyCodeBack) && retVal; retVal = MapKey("quit", KeyCodeQuit) && retVal; MapKey("nextPlaylist", KeyCodeNextPlaylist); + MapKey("random", KeyCodeRandom); // these features will need to be implemented at a later time // retVal = MapKey("admin", KeyCodeAdminMode) && retVal; // retVal = MapKey("remove", KeyCodeHideItem) && retVal; diff --git a/RetroFE/Source/Control/UserInput.h b/RetroFE/Source/Control/UserInput.h index d63337e..dc7aa03 100644 --- a/RetroFE/Source/Control/UserInput.h +++ b/RetroFE/Source/Control/UserInput.h @@ -40,6 +40,7 @@ public: KeyCodeLetterDown, KeyCodeLetterUp, KeyCodeNextPlaylist, + KeyCodeRandom, KeyCodeAdminMode, KeyCodeHideItem, KeyCodeQuit, diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index d140618..cf688d9 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -292,6 +292,14 @@ void ScrollingList::pageDown() allocateSpritePoints(); } +void ScrollingList::random() +{ + if(!items_ || items_->size() == 0) return; + + deallocateSpritePoints(); + itemIndex_ = rand() % items_->size(); + allocateSpritePoints(); +} void ScrollingList::letterUp() { diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.h b/RetroFE/Source/Graphics/Component/ScrollingList.h index 9680317..f4f0f11 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.h +++ b/RetroFE/Source/Graphics/Component/ScrollingList.h @@ -65,6 +65,7 @@ public: void letterUp(); void letterDown(); void letterChange(bool increment); + void random(); bool isIdle(); unsigned int getScrollOffsetIndex(); void setScrollOffsetIndex(unsigned int index); diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index 5e9693e..0b54ef8 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -407,6 +407,11 @@ void Page::pageScroll(ScrollDirection direction) } } +void Page::selectRandom() +{ + if(activeMenu_) activeMenu_->random(); +} + void Page::letterScroll(ScrollDirection direction) { if(activeMenu_) diff --git a/RetroFE/Source/Graphics/Page.h b/RetroFE/Source/Graphics/Page.h index 69ba80a..29b62d9 100644 --- a/RetroFE/Source/Graphics/Page.h +++ b/RetroFE/Source/Graphics/Page.h @@ -56,6 +56,7 @@ public: bool addComponent(Component *c); void pageScroll(ScrollDirection direction); void letterScroll(ScrollDirection direction); + void selectRandom(); void start(); void startComponents(); void stop(); diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index e974fe9..20ba9d6 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -448,7 +448,8 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) !input_.keystate(UserInput::KeyCodePageDown) && !input_.keystate(UserInput::KeyCodeLetterUp) && !input_.keystate(UserInput::KeyCodeLetterDown) && - !input_.keystate(UserInput::KeyCodeNextPlaylist)) + !input_.keystate(UserInput::KeyCodeNextPlaylist) && + !input_.keystate(UserInput::KeyCodeRandom)) { keyLastTime_ = 0; keyDelayTime_= 0.3f; @@ -480,6 +481,10 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) { page->nextPlaylist(); } + if(input_.keystate(UserInput::KeyCodeRandom)) + { + page->selectRandom(); + } } if (input_.keystate(UserInput::KeyCodeAdminMode)) From 24d4b37cf73b0517928f6d35eea611606d74403d Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Fri, 7 Aug 2015 11:21:04 -0500 Subject: [PATCH 12/43] Adding button to add to playlists (does not yet save favorites.txt yet) --- Package/Environment/Common/controls.conf | 1 + .../Common/layouts/Default 16x9/layout.xml | 4 ++-- RetroFE/Source/Control/UserInput.cpp | 22 +++++++++++++------ RetroFE/Source/Control/UserInput.h | 2 ++ .../Graphics/Component/ScrollingList.cpp | 11 ++++++++-- .../Source/Graphics/Component/ScrollingList.h | 4 ++-- RetroFE/Source/Graphics/Page.cpp | 19 ++++++++++++++++ RetroFE/Source/Graphics/Page.h | 1 + RetroFE/Source/RetroFE.cpp | 5 +++++ 9 files changed, 56 insertions(+), 13 deletions(-) diff --git a/Package/Environment/Common/controls.conf b/Package/Environment/Common/controls.conf index 638ccb3..8f530df 100644 --- a/Package/Environment/Common/controls.conf +++ b/Package/Environment/Common/controls.conf @@ -7,6 +7,7 @@ pageDown = B letterUp = N letterDown = M nextPlaylist = P +addPlaylist = O random = R select = Space back = Escape diff --git a/Package/Environment/Common/layouts/Default 16x9/layout.xml b/Package/Environment/Common/layouts/Default 16x9/layout.xml index 87eb262..90732e1 100644 --- a/Package/Environment/Common/layouts/Default 16x9/layout.xml +++ b/Package/Environment/Common/layouts/Default 16x9/layout.xml @@ -12,7 +12,7 @@ - + @@ -367,4 +367,4 @@ - \ No newline at end of file + diff --git a/RetroFE/Source/Control/UserInput.cpp b/RetroFE/Source/Control/UserInput.cpp index 5683b69..30ac3b7 100644 --- a/RetroFE/Source/Control/UserInput.cpp +++ b/RetroFE/Source/Control/UserInput.cpp @@ -66,15 +66,17 @@ bool UserInput::initialize() retVal = MapKey("down", KeyCodeRight) && retVal; } - retVal = MapKey("pageDown", KeyCodePageDown) && retVal; - retVal = MapKey("pageUp", KeyCodePageUp) && retVal; - MapKey("letterDown", KeyCodeLetterDown); - MapKey("letterUp", KeyCodeLetterUp); retVal = MapKey("select", KeyCodeSelect) && retVal; retVal = MapKey("back", KeyCodeBack) && retVal; retVal = MapKey("quit", KeyCodeQuit) && retVal; - MapKey("nextPlaylist", KeyCodeNextPlaylist); - MapKey("random", KeyCodeRandom); + retVal = MapKey("pageDown", KeyCodePageDown); + retVal = MapKey("pageUp", KeyCodePageUp); + + MapKey("letterDown", KeyCodeLetterDown, false); + MapKey("letterUp", KeyCodeLetterUp, false); + MapKey("nextPlaylist", KeyCodeNextPlaylist, false); + MapKey("addPlaylist", KeyCodeAddPlaylist, false); + MapKey("random", KeyCodeRandom, false); // these features will need to be implemented at a later time // retVal = MapKey("admin", KeyCodeAdminMode) && retVal; // retVal = MapKey("remove", KeyCodeHideItem) && retVal; @@ -89,6 +91,11 @@ bool UserInput::initialize() } bool UserInput::MapKey(std::string keyDescription, KeyCode_E key) +{ + return MapKey(keyDescription, key, true); +} + +bool UserInput::MapKey(std::string keyDescription, KeyCode_E key, bool required) { SDL_Scancode scanCode; std::string description; @@ -97,7 +104,8 @@ bool UserInput::MapKey(std::string keyDescription, KeyCode_E key) if(!config_.getProperty(configKey, description)) { - Logger::write(Logger::ZONE_ERROR, "Input", "Missing property " + configKey); + Logger::Zone zone = (required) ? Logger::ZONE_ERROR : Logger::ZONE_INFO; + Logger::write(zone, "Input", "Missing property " + configKey); return false; } diff --git a/RetroFE/Source/Control/UserInput.h b/RetroFE/Source/Control/UserInput.h index dc7aa03..11e8545 100644 --- a/RetroFE/Source/Control/UserInput.h +++ b/RetroFE/Source/Control/UserInput.h @@ -41,6 +41,7 @@ public: KeyCodeLetterUp, KeyCodeNextPlaylist, KeyCodeRandom, + KeyCodeAddPlaylist, KeyCodeAdminMode, KeyCodeHideItem, KeyCodeQuit, @@ -56,6 +57,7 @@ public: private: bool MapKey(std::string keyDescription, KeyCode_E key); + bool MapKey(std::string keyDescription, KeyCode_E key, bool required); Configuration &config_; std::vector joysticks_; InputHandler *keyHandlers_[KeyCodeMax]; diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index cf688d9..685b37b 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -129,12 +129,14 @@ void ScrollingList::setItems(std::vector *items) deallocateSpritePoints(); items_ = items; - itemIndex_ = 0; + if(items_) + { + itemIndex_ = loopDecrement(0, selectedOffsetIndex_, items_->size()); + } allocateSpritePoints(); notifyAllRequested_ = true; - } unsigned int ScrollingList::loopIncrement(unsigned int offset, unsigned int i, unsigned int size) @@ -215,6 +217,11 @@ void ScrollingList::setPoints(std::vector *scrollPoints, std::vector if(scrollPoints) size = scrollPoints_->size(); components_.resize(size); + if(items_) + { + itemIndex_ = loopDecrement(0, selectedOffsetIndex_, items_->size()); + } + allocateSpritePoints(); } diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.h b/RetroFE/Source/Graphics/Component/ScrollingList.h index f4f0f11..798b3ce 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.h +++ b/RetroFE/Source/Graphics/Component/ScrollingList.h @@ -79,12 +79,12 @@ public: void setScrollAcceleration(float value); void setStartScrollTime(float value); bool horizontalScroll; + void deallocateSpritePoints(); + void allocateSpritePoints(); private: void click(double nextScrollTime); - void deallocateSpritePoints(); - void allocateSpritePoints(); void resetTweens(Component *c, AnimationEvents *sets, ViewInfo *currentViewInfo, ViewInfo *nextViewInfo, double scrollTime); unsigned int loopIncrement(unsigned int offset, unsigned int i, unsigned int size); unsigned int loopDecrement(unsigned int offset, unsigned int i, unsigned int size); diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index 0b54ef8..7df2c17 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -645,6 +645,25 @@ void Page::draw() } +void Page::addPlaylist() +{ + if(!selectedItem_) return; + + MenuInfo_S &info = collections_.back(); + CollectionInfo *collection = info.collection; + + std::vector *items = collection->playlists["favorites"]; + if(playlist_->first != "favorites" && std::find(items->begin(), items->end(), selectedItem_) == items->end()) + { + items->push_back(selectedItem_); + if(activeMenu_) + { + activeMenu_->deallocateSpritePoints(); + activeMenu_->allocateSpritePoints(); + } + } +} + std::string Page::getCollectionName() { if(collections_.size() == 0) return ""; diff --git a/RetroFE/Source/Graphics/Page.h b/RetroFE/Source/Graphics/Page.h index 29b62d9..3b4a003 100644 --- a/RetroFE/Source/Graphics/Page.h +++ b/RetroFE/Source/Graphics/Page.h @@ -80,6 +80,7 @@ public: std::string getCollectionName(); void setMinShowTime(float value); float getMinShowTime(); + void addPlaylist(); private: void highlight(); diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index 20ba9d6..eed65e1 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -449,6 +449,7 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) !input_.keystate(UserInput::KeyCodeLetterUp) && !input_.keystate(UserInput::KeyCodeLetterDown) && !input_.keystate(UserInput::KeyCodeNextPlaylist) && + !input_.keystate(UserInput::KeyCodeAddPlaylist) && !input_.keystate(UserInput::KeyCodeRandom)) { keyLastTime_ = 0; @@ -481,6 +482,10 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) { page->nextPlaylist(); } + if(input_.keystate(UserInput::KeyCodeAddPlaylist)) + { + page->addPlaylist(); + } if(input_.keystate(UserInput::KeyCodeRandom)) { page->selectRandom(); From 0ff46605eb33fcf8ef353eba3a9f4ece3d2382a0 Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Fri, 7 Aug 2015 11:27:12 -0500 Subject: [PATCH 13/43] Adding button to add to playlists (does not yet save favorites.txt yet) --- Package/Environment/Common/controls.conf | 3 ++- RetroFE/Source/Control/UserInput.cpp | 1 + RetroFE/Source/Control/UserInput.h | 1 + RetroFE/Source/Graphics/Page.cpp | 24 ++++++++++++++++++++++++ RetroFE/Source/RetroFE.cpp | 5 +++++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Package/Environment/Common/controls.conf b/Package/Environment/Common/controls.conf index 8f530df..1d0dbc4 100644 --- a/Package/Environment/Common/controls.conf +++ b/Package/Environment/Common/controls.conf @@ -7,7 +7,8 @@ pageDown = B letterUp = N letterDown = M nextPlaylist = P -addPlaylist = O +addPlaylist = I +removePlaylist = O random = R select = Space back = Escape diff --git a/RetroFE/Source/Control/UserInput.cpp b/RetroFE/Source/Control/UserInput.cpp index 30ac3b7..e3f89c2 100644 --- a/RetroFE/Source/Control/UserInput.cpp +++ b/RetroFE/Source/Control/UserInput.cpp @@ -76,6 +76,7 @@ bool UserInput::initialize() MapKey("letterUp", KeyCodeLetterUp, false); MapKey("nextPlaylist", KeyCodeNextPlaylist, false); MapKey("addPlaylist", KeyCodeAddPlaylist, false); + MapKey("removePlaylist", KeyCodeRemovePlaylist, false); MapKey("random", KeyCodeRandom, false); // these features will need to be implemented at a later time // retVal = MapKey("admin", KeyCodeAdminMode) && retVal; diff --git a/RetroFE/Source/Control/UserInput.h b/RetroFE/Source/Control/UserInput.h index 11e8545..feaffc5 100644 --- a/RetroFE/Source/Control/UserInput.h +++ b/RetroFE/Source/Control/UserInput.h @@ -42,6 +42,7 @@ public: KeyCodeNextPlaylist, KeyCodeRandom, KeyCodeAddPlaylist, + KeyCodeRemovePlaylist, KeyCodeAdminMode, KeyCodeHideItem, KeyCodeQuit, diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index 7df2c17..f47bd99 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -645,6 +645,30 @@ void Page::draw() } +void Page::removePlaylist() +{ + if(!selectedItem_) return; + + MenuInfo_S &info = collections_.back(); + CollectionInfo *collection = info.collection; + + std::vector *items = collection->playlists["favorites"]; + std::vector it = std::find(items->begin(), items->end(), selectedItem_); + + if(it != items->end()) + { + items->erase(it); + + items->shrink_to_fit(); + + if(activeMenu_) + { + activeMenu_->deallocateSpritePoints(); + activeMenu_->allocateSpritePoints(); + } + } +} + void Page::addPlaylist() { if(!selectedItem_) return; diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index eed65e1..8fdcea1 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -450,6 +450,7 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) !input_.keystate(UserInput::KeyCodeLetterDown) && !input_.keystate(UserInput::KeyCodeNextPlaylist) && !input_.keystate(UserInput::KeyCodeAddPlaylist) && + !input_.keystate(UserInput::KeyCodeRemovePlaylist) && !input_.keystate(UserInput::KeyCodeRandom)) { keyLastTime_ = 0; @@ -482,6 +483,10 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) { page->nextPlaylist(); } + if(input_.keystate(UserInput::KeyCodeRemovePlaylist)) + { + page->removePlaylist(); + } if(input_.keystate(UserInput::KeyCodeAddPlaylist)) { page->addPlaylist(); From b940534e481a1824804a1a230a52fb038fb2f7db Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Fri, 7 Aug 2015 11:31:05 -0500 Subject: [PATCH 14/43] Adding button to remove from playlists (does not yet save favorites.txt yet) --- RetroFE/Source/Graphics/Page.cpp | 4 +--- RetroFE/Source/Graphics/Page.h | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index f47bd99..8d1e07e 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -653,14 +653,12 @@ void Page::removePlaylist() CollectionInfo *collection = info.collection; std::vector *items = collection->playlists["favorites"]; - std::vector it = std::find(items->begin(), items->end(), selectedItem_); + std::vector::iterator it = std::find(items->begin(), items->end(), selectedItem_); if(it != items->end()) { items->erase(it); - items->shrink_to_fit(); - if(activeMenu_) { activeMenu_->deallocateSpritePoints(); diff --git a/RetroFE/Source/Graphics/Page.h b/RetroFE/Source/Graphics/Page.h index 3b4a003..1d634c0 100644 --- a/RetroFE/Source/Graphics/Page.h +++ b/RetroFE/Source/Graphics/Page.h @@ -81,6 +81,7 @@ public: void setMinShowTime(float value); float getMinShowTime(); void addPlaylist(); + void removePlaylist(); private: void highlight(); From 248f1993a0fd839f22ed339a0b30d4b9c94e9564 Mon Sep 17 00:00:00 2001 From: emb <> Date: Fri, 7 Aug 2015 17:28:53 -0500 Subject: [PATCH 15/43] Save support for favorites.txt. Misc bug fixes. Not fully tested. --- RetroFE/Source/Collection/CollectionInfo.cpp | 29 +++++++++++++++++++- RetroFE/Source/Collection/CollectionInfo.h | 1 + RetroFE/Source/Graphics/Page.cpp | 21 ++++++++------ RetroFE/Source/Graphics/Page.h | 1 + 4 files changed, 43 insertions(+), 9 deletions(-) diff --git a/RetroFE/Source/Collection/CollectionInfo.cpp b/RetroFE/Source/Collection/CollectionInfo.cpp index 88304fe..62489f7 100644 --- a/RetroFE/Source/Collection/CollectionInfo.cpp +++ b/RetroFE/Source/Collection/CollectionInfo.cpp @@ -17,8 +17,11 @@ #include "Item.h" #include "../Database/Configuration.h" #include "../Utility/Utils.h" +#include "../Utility/Log.h" #include +#include #include +#include CollectionInfo::CollectionInfo(std::string name, std::string listPath, @@ -27,6 +30,7 @@ CollectionInfo::CollectionInfo(std::string name, std::string metadataPath) : name(name) , listpath(listPath) + , saveRequest(false) , metadataType(metadataType) , menusort(true) , metadataPath_(metadataPath) @@ -38,8 +42,31 @@ CollectionInfo::~CollectionInfo() { // remove items from the subcollections so their destructors do not // delete the items since the parent collection will delete them. + if(saveRequest) + { + std::string file = Utils::combinePath(Configuration::absolutePath, "collections", name, "favorites.txt"); + Logger::write(Logger::ZONE_INFO, "Collection", "Saving " + file); + + std::ofstream filestream; + try + { + filestream.open(file.c_str()); + std::vector *saveitems = playlists["favorites"]; + for(std::vector::iterator it = saveitems->begin(); it != saveitems->end(); it++) + { + filestream << (*it)->name << std::endl; + } + + filestream.close(); + } + catch(std::exception &) + { + Logger::write(Logger::ZONE_ERROR, "Collection", "Save failed: " + file); + } + } + std::vector::iterator subit; - for (subit != subcollections_.begin(); subit != subcollections_.end(); subit++) + for (subit = subcollections_.begin(); subit != subcollections_.end(); subit++) { CollectionInfo *info = *subit; info->items.clear(); diff --git a/RetroFE/Source/Collection/CollectionInfo.h b/RetroFE/Source/Collection/CollectionInfo.h index b017fcf..c520f4f 100644 --- a/RetroFE/Source/Collection/CollectionInfo.h +++ b/RetroFE/Source/Collection/CollectionInfo.h @@ -33,6 +33,7 @@ public: void extensionList(std::vector &extensions); std::string name; std::string listpath; + bool saveRequest; std::string metadataType; std::string launcher; std::vector items; diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index 8d1e07e..1b24174 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -505,18 +505,20 @@ bool Page::popCollection() if(collections_.size() <= 1) return false; // queue the collection for deletion - MenuInfo_S &info = collections_.back(); - info.queueDelete = true; + MenuInfo_S *info = &collections_.back(); + info->queueDelete = true; + deleteCollections_.push_back(*info); // get the next collection off of the stack collections_.pop_back(); - info = collections_.back(); - playlist_ = info.playlist; + info = &collections_.back(); + playlist_ = info->playlist; playlistChanged_ = true; if(activeMenu_) { activeMenu_->triggerMenuExitEvent(); + } menuDepth_--; @@ -532,7 +534,7 @@ bool Page::popCollection() { for(std::vector::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) { - (*it)->collectionName = info.collection->name; + (*it)->collectionName = info->collection->name; if(menuEnterIndex >= 0) { @@ -607,9 +609,9 @@ void Page::update(float dt) // many nodes still have handles on the collection info. We need to delete // them once everything is done using them - std::list::iterator del = collections_.begin(); + std::list::iterator del = deleteCollections_.begin(); - while(del != collections_.end()) + while(del != deleteCollections_.end()) { MenuInfo_S &info = *del; if(info.queueDelete && info.menu && info.menu->isIdle()) @@ -618,7 +620,8 @@ void Page::update(float dt) ++next; if(info.collection) delete info.collection; - collections_.erase(del); + deleteCollections_.erase(del); + del = next; } else { @@ -658,6 +661,7 @@ void Page::removePlaylist() if(it != items->end()) { items->erase(it); + collection->saveRequest = true; if(activeMenu_) { @@ -678,6 +682,7 @@ void Page::addPlaylist() if(playlist_->first != "favorites" && std::find(items->begin(), items->end(), selectedItem_) == items->end()) { items->push_back(selectedItem_); + collection->saveRequest = true; if(activeMenu_) { activeMenu_->deallocateSpritePoints(); diff --git a/RetroFE/Source/Graphics/Page.h b/RetroFE/Source/Graphics/Page.h index 1d634c0..6ac2a8b 100644 --- a/RetroFE/Source/Graphics/Page.h +++ b/RetroFE/Source/Graphics/Page.h @@ -104,6 +104,7 @@ private: unsigned int menuDepth_; MenuVector_T menus_; CollectionVector_T collections_; + CollectionVector_T deleteCollections_; static const unsigned int NUM_LAYERS = 8; std::vector LayerComponents[NUM_LAYERS]; From c5c84995004a24efc033bb6962136df78a632b44 Mon Sep 17 00:00:00 2001 From: emb <> Date: Mon, 19 Oct 2015 21:48:20 -0500 Subject: [PATCH 16/43] Sorting for playlists. --- RetroFE/Source/Collection/CollectionInfo.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/RetroFE/Source/Collection/CollectionInfo.cpp b/RetroFE/Source/Collection/CollectionInfo.cpp index 62489f7..caea3b6 100644 --- a/RetroFE/Source/Collection/CollectionInfo.cpp +++ b/RetroFE/Source/Collection/CollectionInfo.cpp @@ -134,5 +134,8 @@ bool CollectionInfo::itemIsLess(Item *lhs, Item *rhs) void CollectionInfo::sortItems() { - std::sort(items.begin(), items.end(), itemIsLess); + for(Playlists_T::iterator it = playlists.begin(); it != playlists.end(); it++) + { + std::sort(it->second->begin(), it->second->end(), itemIsLess); + } } From 1785c008a1e594c37a513e43b2557bbdbfef3cb0 Mon Sep 17 00:00:00 2001 From: emb <> Date: Mon, 19 Oct 2015 21:59:40 -0500 Subject: [PATCH 17/43] MLaunching merged romset support --- RetroFE/Source/Execute/Launcher.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/RetroFE/Source/Execute/Launcher.cpp b/RetroFE/Source/Execute/Launcher.cpp index 8c307ba..a6510dd 100644 --- a/RetroFE/Source/Execute/Launcher.cpp +++ b/RetroFE/Source/Execute/Launcher.cpp @@ -67,11 +67,10 @@ bool Launcher::run(std::string collection, Item *collectionItem) Logger::write(Logger::ZONE_ERROR, "Launcher", "No launcher arguments specified for launcher " + launcherName); return false; } - if(!findFile(selectedItemsPath, matchedExtension, selectedItemsDirectory, collectionItem->name, extensionstr)) - { - // FindFile() prints out diagnostic messages for us, no need to print anything here - return false; - } + + // It is ok to continue if the file could not be found. We could be launching a merged romset + findFile(selectedItemsPath, matchedExtension, selectedItemsDirectory, collectionItem->name, extensionstr); + args = replaceVariables(args, selectedItemsPath, collectionItem->name, @@ -329,7 +328,7 @@ bool Launcher::findFile(std::string &foundFilePath, std::string &foundFilename, << filenameWithoutExtension << "\" in folder \"" << directory; - Logger::write(Logger::ZONE_ERROR, "Launcher", ss.str()); + Logger::write(Logger::ZONE_WARNING, "Launcher", ss.str()); } From 4d4acca35fce4fbf2479c6f5e090103ee01b6768 Mon Sep 17 00:00:00 2001 From: emb <> Date: Mon, 19 Oct 2015 22:05:30 -0500 Subject: [PATCH 18/43] Added media.system_artwork path parameter support to settings.conf. --- RetroFE/Source/Collection/CollectionInfoBuilder.cpp | 1 + RetroFE/Source/Database/Configuration.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp index 79a150c..39d97ec 100644 --- a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp +++ b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp @@ -131,6 +131,7 @@ bool CollectionInfoBuilder::createCollectionDirectory(std::string name) settingsFile << "#media.screenshot = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screenshot") << std::endl; settingsFile << "#media.screentitle = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screentitle") << std::endl; settingsFile << "#media.video = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "video") << std::endl; + settingsFile << "#media.system_artwork = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "system_artwork") << std::endl; settingsFile.close(); filename = Utils::combinePath(collectionPath, "menu.txt"); diff --git a/RetroFE/Source/Database/Configuration.cpp b/RetroFE/Source/Database/Configuration.cpp index e95a196..8f8a621 100644 --- a/RetroFE/Source/Database/Configuration.cpp +++ b/RetroFE/Source/Database/Configuration.cpp @@ -332,6 +332,10 @@ void Configuration::getMediaPropertyAbsolutePath(std::string collectionName, std void Configuration::getMediaPropertyAbsolutePath(std::string collectionName, std::string mediaType, bool system, std::string &value) { std::string key = "collections." + collectionName + ".media." + mediaType; + if (system) + { + key = "collections." + collectionName + ".media.system_artwork"; + } // use user-overridden setting if it exists if(getPropertyAbsolutePath(key, value)) From 1c67c485c3a0d922ab50801ae20f26f481da7e6f Mon Sep 17 00:00:00 2001 From: emb <> Date: Tue, 20 Oct 2015 21:13:01 -0500 Subject: [PATCH 19/43] Fix %ITEM_FILENAME% replacement for launcher. --- RetroFE/Source/Execute/Launcher.cpp | 6 +++--- RetroFE/Source/Main.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/RetroFE/Source/Execute/Launcher.cpp b/RetroFE/Source/Execute/Launcher.cpp index a6510dd..53323f0 100644 --- a/RetroFE/Source/Execute/Launcher.cpp +++ b/RetroFE/Source/Execute/Launcher.cpp @@ -74,21 +74,21 @@ bool Launcher::run(std::string collection, Item *collectionItem) args = replaceVariables(args, selectedItemsPath, collectionItem->name, - collectionItem->filename(), + Utils::getFileName(selectedItemsPath), selectedItemsDirectory, collection); executablePath = replaceVariables(executablePath, selectedItemsPath, collectionItem->name, - collectionItem->filename(), + Utils::getFileName(selectedItemsPath), selectedItemsDirectory, collection); currentDirectory = replaceVariables(currentDirectory, selectedItemsPath, collectionItem->name, - collectionItem->filename(), + Utils::getFileName(selectedItemsPath), selectedItemsDirectory, collection); diff --git a/RetroFE/Source/Main.cpp b/RetroFE/Source/Main.cpp index d14bb6a..519617e 100644 --- a/RetroFE/Source/Main.cpp +++ b/RetroFE/Source/Main.cpp @@ -115,7 +115,7 @@ bool ImportConfiguration(Configuration *c) std::string importFile = Utils::combinePath(launchersPath, std::string(dirp->d_name)); - if(!c->import(prefix, importFile)) + if(!c->import(basename, prefix, importFile)) { Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not import \"" + importFile + "\""); closedir(dp); From ba5b3ffff77170672a37f176978c87d89d007d1c Mon Sep 17 00:00:00 2001 From: emb <> Date: Wed, 21 Oct 2015 20:29:36 -0500 Subject: [PATCH 20/43] Fixed multiwheel crash (bug from copy constructor). --- .../Graphics/Component/ScrollingList.cpp | 20 ++----------------- RetroFE/Source/Graphics/Page.cpp | 6 +++--- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index 685b37b..b964b0e 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -96,25 +96,8 @@ ScrollingList::ScrollingList(const ScrollingList ©) scrollPoints_ = NULL; tweenPoints_ = NULL; - if(copy.scrollPoints_) - { - scrollPoints_ = new std::vector(); - for(unsigned int i = 0; i < copy.scrollPoints_->size(); ++i) - { - ViewInfo *v = new ViewInfo(*copy.scrollPoints_->at(i)); - scrollPoints_->push_back(v); - } - } + setPoints(copy.scrollPoints_, copy.tweenPoints_); - if(copy.tweenPoints_) - { - tweenPoints_ = new std::vector(); - for(unsigned int i = 0; i < copy.tweenPoints_->size(); ++i) - { - AnimationEvents *v = new AnimationEvents(*copy.tweenPoints_->at(i)); - tweenPoints_->push_back(v); - } - } } @@ -176,6 +159,7 @@ void ScrollingList::allocateSpritePoints() { if(!items_ || items_->size() == 0) return; if(!scrollPoints_) return; + if(components_.size() == 0) return; for(unsigned int i = 0; i < scrollPoints_->size(); ++i) { diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index 1b24174..fb59e3d 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -447,9 +447,9 @@ bool Page::pushCollection(CollectionInfo *collection) // grow the menu as needed if(menus_.size() >= menuDepth_ && activeMenu_) { - ScrollingList *newList = new ScrollingList(*activeMenu_); - newList->forceIdle(); - pushMenu(newList); + activeMenu_ = new ScrollingList(*activeMenu_); + activeMenu_->forceIdle(); + pushMenu(activeMenu_); } From 1770efb2000a40366f0831f2d9791916d8cb930c Mon Sep 17 00:00:00 2001 From: emb <> Date: Wed, 21 Oct 2015 20:39:36 -0500 Subject: [PATCH 21/43] Moved favorites to playlists folder --- RetroFE/Source/Collection/CollectionInfo.cpp | 2 +- RetroFE/Source/Collection/CollectionInfoBuilder.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/RetroFE/Source/Collection/CollectionInfo.cpp b/RetroFE/Source/Collection/CollectionInfo.cpp index caea3b6..083054d 100644 --- a/RetroFE/Source/Collection/CollectionInfo.cpp +++ b/RetroFE/Source/Collection/CollectionInfo.cpp @@ -44,7 +44,7 @@ CollectionInfo::~CollectionInfo() // delete the items since the parent collection will delete them. if(saveRequest) { - std::string file = Utils::combinePath(Configuration::absolutePath, "collections", name, "favorites.txt"); + std::string file = Utils::combinePath(Configuration::absolutePath, "collections", name, "playlists/favorites.txt"); Logger::write(Logger::ZONE_INFO, "Collection", "Saving " + file); std::ofstream filestream; diff --git a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp index 39d97ec..79be5c1 100644 --- a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp +++ b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp @@ -235,7 +235,7 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me std::map favoritesFilter; std::map excludeFilter; std::string includeFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "include.txt"); - std::string favoritesFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "favorites.txt"); + std::string favoritesFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "playlists/favorites.txt"); std::string excludeFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "exclude.txt"); std::string launcher; From d1a45e650eb71d202b7d67680e3a39bff235584b Mon Sep 17 00:00:00 2001 From: emb <> Date: Wed, 21 Oct 2015 20:56:13 -0500 Subject: [PATCH 22/43] Fixed another ScrollinList copy constructor issue (selecting wrong item) --- RetroFE/Source/Graphics/Component/ScrollingList.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index b964b0e..589f3b0 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -52,6 +52,7 @@ ScrollingList::ScrollingList(Configuration &c, , focus_(false) , itemIndex_(0) , componentIndex_(0) + , selectedOffsetIndex_(0) , scrollStopRequested_(true) , notifyAllRequested_(false) , currentScrollDirection_(ScrollDirectionIdle) @@ -77,6 +78,7 @@ ScrollingList::ScrollingList(const ScrollingList ©) , focus_(false) , itemIndex_(0) , componentIndex_(0) + , selectedOffsetIndex_(copy.selectedOffsetIndex_) , scrollStopRequested_(true) , notifyAllRequested_(false) , currentScrollDirection_(ScrollDirectionIdle) From cdba6f5df7e5b7943c8faa2e3b7584b9a1bba9b3 Mon Sep 17 00:00:00 2001 From: emb <> Date: Wed, 21 Oct 2015 21:29:39 -0500 Subject: [PATCH 23/43] Playlist save support --- RetroFE/Source/Collection/CollectionInfo.cpp | 53 +++++++++++--------- RetroFE/Source/Collection/CollectionInfo.h | 1 + RetroFE/Source/Graphics/Page.cpp | 20 +++++++- RetroFE/Source/RetroFE.cpp | 1 - 4 files changed, 50 insertions(+), 25 deletions(-) diff --git a/RetroFE/Source/Collection/CollectionInfo.cpp b/RetroFE/Source/Collection/CollectionInfo.cpp index 083054d..59f8f0c 100644 --- a/RetroFE/Source/Collection/CollectionInfo.cpp +++ b/RetroFE/Source/Collection/CollectionInfo.cpp @@ -42,29 +42,6 @@ CollectionInfo::~CollectionInfo() { // remove items from the subcollections so their destructors do not // delete the items since the parent collection will delete them. - if(saveRequest) - { - std::string file = Utils::combinePath(Configuration::absolutePath, "collections", name, "playlists/favorites.txt"); - Logger::write(Logger::ZONE_INFO, "Collection", "Saving " + file); - - std::ofstream filestream; - try - { - filestream.open(file.c_str()); - std::vector *saveitems = playlists["favorites"]; - for(std::vector::iterator it = saveitems->begin(); it != saveitems->end(); it++) - { - filestream << (*it)->name << std::endl; - } - - filestream.close(); - } - catch(std::exception &) - { - Logger::write(Logger::ZONE_ERROR, "Collection", "Save failed: " + file); - } - } - std::vector::iterator subit; for (subit = subcollections_.begin(); subit != subcollections_.end(); subit++) { @@ -94,6 +71,36 @@ CollectionInfo::~CollectionInfo() } } +bool CollectionInfo::Save() +{ + bool retval = true; + if(saveRequest) + { + std::string file = Utils::combinePath(Configuration::absolutePath, "collections", name, "playlists/favorites.txt"); + Logger::write(Logger::ZONE_INFO, "Collection", "Saving " + file); + + std::ofstream filestream; + try + { + filestream.open(file.c_str()); + std::vector *saveitems = playlists["favorites"]; + for(std::vector::iterator it = saveitems->begin(); it != saveitems->end(); it++) + { + filestream << (*it)->name << std::endl; + } + + filestream.close(); + } + catch(std::exception &) + { + Logger::write(Logger::ZONE_ERROR, "Collection", "Save failed: " + file); + retval = false; + } + } + + return retval; +} + std::string CollectionInfo::settingsPath() const { return Utils::combinePath(Configuration::absolutePath, "collections", name); diff --git a/RetroFE/Source/Collection/CollectionInfo.h b/RetroFE/Source/Collection/CollectionInfo.h index c520f4f..dd15d1a 100644 --- a/RetroFE/Source/Collection/CollectionInfo.h +++ b/RetroFE/Source/Collection/CollectionInfo.h @@ -27,6 +27,7 @@ public: CollectionInfo(std::string name, std::string listPath, std::string extensions, std::string metadataType, std::string metadataPath); virtual ~CollectionInfo(); std::string settingsPath() const; + bool Save(); void sortItems(); void addSubcollection(CollectionInfo *info); bool hasSubcollections(); diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index fb59e3d..6776caf 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -90,6 +90,19 @@ Page::~Page() delete selectSoundChunk_; selectSoundChunk_ = NULL; } + CollectionVector_T::iterator itc = collections_.begin(); + + while(itc != collections_.end()) + { + itc->collection->Save(); + + if(itc->collection) + { + delete itc->collection; + } + collections_.erase(itc); + itc = collections_.begin(); + } } @@ -554,6 +567,7 @@ bool Page::popCollection() void Page::nextPlaylist() { MenuInfo_S &info = collections_.back(); + info.collection->Save(); unsigned int numlists = info.collection->playlists.size(); for(unsigned int i = 0; i <= numlists; ++i) @@ -619,7 +633,11 @@ void Page::update(float dt) std::list::iterator next = del; ++next; - if(info.collection) delete info.collection; + if(info.collection) + { + info.collection->Save(); + delete info.collection; + } deleteCollections_.erase(del); del = next; } diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index 8fdcea1..009a032 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -389,7 +389,6 @@ void RetroFE::run() render(); } } - } From 8f2f1d5839cde4126aa6dfa5ff32b94c9439f5a7 Mon Sep 17 00:00:00 2001 From: emb <> Date: Wed, 21 Oct 2015 21:53:36 -0500 Subject: [PATCH 24/43] Random button press now sends notification to all components. --- RetroFE/Source/Graphics/Component/ScrollingList.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index 589f3b0..ca9c5fd 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -289,6 +289,8 @@ void ScrollingList::random() { if(!items_ || items_->size() == 0) return; + notifyAllRequested_ = true; + deallocateSpritePoints(); itemIndex_ = rand() % items_->size(); allocateSpritePoints(); From c19669e3813ee15529c7b112e24cc96e8411b39a Mon Sep 17 00:00:00 2001 From: emb <> Date: Thu, 22 Oct 2015 20:55:32 -0500 Subject: [PATCH 25/43] Suport new mame xml format (changed "game" to "machine"). --- RetroFE/Source/Database/MetadataDatabase.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/RetroFE/Source/Database/MetadataDatabase.cpp b/RetroFE/Source/Database/MetadataDatabase.cpp index 80a93b1..19453f1 100644 --- a/RetroFE/Source/Database/MetadataDatabase.cpp +++ b/RetroFE/Source/Database/MetadataDatabase.cpp @@ -417,7 +417,14 @@ bool MetadataDatabase::importMamelist(std::string filename, std::string collecti } sqlite3_exec(handle, "BEGIN IMMEDIATE TRANSACTION;", NULL, NULL, &error); - for (rapidxml::xml_node<> * game = rootNode->first_node("game"); game; game = game->next_sibling()) + std::string gameNodeName = "game"; + + // support new mame formats + if(rootNode->first_node(gameNodeName.c_str()) == NULL) { + gameNodeName = "machine"; + } + + for (rapidxml::xml_node<> * game = rootNode->first_node(gameNodeName.c_str()); game; game = game->next_sibling()) { rapidxml::xml_attribute<> *nameNode = game->first_attribute("name"); rapidxml::xml_attribute<> *cloneOfXml = game->first_attribute("cloneof"); From a5ef2bdcbcdf20b74bb6729c9c390ad4b4649b20 Mon Sep 17 00:00:00 2001 From: emb <> Date: Thu, 22 Oct 2015 22:04:28 -0500 Subject: [PATCH 26/43] ReloadableText support for collectionName, collectionSize, and collectionIndex --- .../Graphics/Component/ReloadableText.cpp | 32 +++++++++++++++++-- .../Graphics/Component/ReloadableText.h | 7 +++- .../Graphics/Component/ScrollingList.cpp | 13 ++++++++ .../Source/Graphics/Component/ScrollingList.h | 2 ++ RetroFE/Source/Graphics/Page.cpp | 10 ++++++ RetroFE/Source/Graphics/Page.h | 2 ++ RetroFE/Source/Graphics/PageBuilder.cpp | 2 +- 7 files changed, 64 insertions(+), 4 deletions(-) diff --git a/RetroFE/Source/Graphics/Component/ReloadableText.cpp b/RetroFE/Source/Graphics/Component/ReloadableText.cpp index b8454d1..430a274 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableText.cpp +++ b/RetroFE/Source/Graphics/Component/ReloadableText.cpp @@ -23,8 +23,9 @@ #include #include -ReloadableText::ReloadableText(std::string type, Font *font, std::string layoutKey, float scaleX, float scaleY) +ReloadableText::ReloadableText(std::string type, Page *page, Font *font, std::string layoutKey, float scaleX, float scaleY) : imageInst_(NULL) + , page_(page) , layoutKey_(layoutKey) , reloadRequested_(false) , firstLoad_(true) @@ -63,7 +64,18 @@ ReloadableText::ReloadableText(std::string type, Font *font, std::string layoutK { type_ = TextTypePlaylist; } - + else if(type == "collectionName") + { + type_ = TextTypeCollectionName; + } + else if(type == "collectionSize") + { + type_ = TextTypeCollectionSize; + } + else if(type == "collectionIndex") + { + type_ = TextTypeCollectionIndex; + } allocateGraphicsMemory(); } @@ -162,6 +174,22 @@ void ReloadableText::ReloadTexture() case TextTypePlaylist: ss << playlistName; break; + case TextTypeCollectionName: + if (page_ != NULL) { + ss << page_->getCollectionName(); + } + break; + case TextTypeCollectionSize: + if (page_ != NULL) { + ss << page_->getCollectionSize(); + } + break; + case TextTypeCollectionIndex: + if (page_ != NULL) { + ss << (1+page_->getSelectedIndex()); + } + break; + default: break; } diff --git a/RetroFE/Source/Graphics/Component/ReloadableText.h b/RetroFE/Source/Graphics/Component/ReloadableText.h index 578ad9f..608026b 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableText.h +++ b/RetroFE/Source/Graphics/Component/ReloadableText.h @@ -17,6 +17,7 @@ #include "Component.h" #include "Text.h" #include "../Font.h" +#include "../Page.h" #include "../../Collection/Item.h" #include #include @@ -24,7 +25,7 @@ class ReloadableText : public Component { public: - ReloadableText(std::string type, Font *font, std::string layoutKey, float scaleX, float scaleY); + ReloadableText(std::string type, Page *page, Font *font, std::string layoutKey, float scaleX, float scaleY); virtual ~ReloadableText(); void update(float dt); void draw(); @@ -44,12 +45,16 @@ private: TextTypeManufacturer, TextTypeGenre, TextTypePlaylist, + TextTypeCollectionName, + TextTypeCollectionSize, + TextTypeCollectionIndex }; void ReloadTexture(); Text *imageInst_; TextType type_; + Page *page_; std::string layoutKey_; bool reloadRequested_; bool firstLoad_; diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index ca9c5fd..f8f5da3 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -501,6 +501,19 @@ void ScrollingList::update(float dt) notifyAllRequested_ = false; } +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(); +} + void ScrollingList::resetTweens(Component *c, AnimationEvents *sets, ViewInfo *currentViewInfo, ViewInfo *nextViewInfo, double scrollTime) { if(!c) return; diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.h b/RetroFE/Source/Graphics/Component/ScrollingList.h index 798b3ce..3702cb9 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.h +++ b/RetroFE/Source/Graphics/Component/ScrollingList.h @@ -60,6 +60,8 @@ public: void destroyItems(); void setPoints(std::vector *scrollPoints, std::vector *tweenPoints); void setScrollDirection(ScrollDirection direction); + unsigned int getSelectedIndex(); + unsigned int getSize(); void pageUp(); void pageDown(); void letterUp(); diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index 6776caf..d2c0c07 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -440,6 +440,16 @@ void Page::letterScroll(ScrollDirection direction) } } +unsigned int Page::getCollectionSize() +{ + return activeMenu_->getSize(); +} + +unsigned int Page::getSelectedIndex() +{ + return activeMenu_->getSelectedIndex(); +} + bool Page::pushCollection(CollectionInfo *collection) { diff --git a/RetroFE/Source/Graphics/Page.h b/RetroFE/Source/Graphics/Page.h index 6ac2a8b..852fc9e 100644 --- a/RetroFE/Source/Graphics/Page.h +++ b/RetroFE/Source/Graphics/Page.h @@ -56,6 +56,8 @@ public: bool addComponent(Component *c); void pageScroll(ScrollDirection direction); void letterScroll(ScrollDirection direction); + unsigned int getCollectionSize(); + unsigned int getSelectedIndex(); void selectRandom(); void start(); void startComponents(); diff --git a/RetroFE/Source/Graphics/PageBuilder.cpp b/RetroFE/Source/Graphics/PageBuilder.cpp index e912ccc..f6b94d8 100644 --- a/RetroFE/Source/Graphics/PageBuilder.cpp +++ b/RetroFE/Source/Graphics/PageBuilder.cpp @@ -438,7 +438,7 @@ void PageBuilder::loadReloadableImages(xml_node<> *layout, std::string tagName, if(type) { Font *font = addFont(componentXml, NULL); - c = new ReloadableText(type->value(), font, layoutKey, scaleX_, scaleY_); + c = new ReloadableText(type->value(), page, font, layoutKey, scaleX_, scaleY_); } } else From 6ff4acbd309e39cb7a81d2bef338da3768a90091 Mon Sep 17 00:00:00 2001 From: emb <> Date: Fri, 23 Oct 2015 23:00:30 -0500 Subject: [PATCH 27/43] Added selectedOffset tag to support preloading and rendering of items not selected --- .../Source/Graphics/Component/Component.cpp | 14 +++----- RetroFE/Source/Graphics/Component/Component.h | 10 +++--- .../Source/Graphics/Component/Container.cpp | 3 +- RetroFE/Source/Graphics/Component/Container.h | 2 +- RetroFE/Source/Graphics/Component/Image.cpp | 5 +-- RetroFE/Source/Graphics/Component/Image.h | 2 +- .../Graphics/Component/ImageBuilder.cpp | 4 +-- .../Source/Graphics/Component/ImageBuilder.h | 3 +- .../Graphics/Component/ReloadableMedia.cpp | 15 ++++---- .../Graphics/Component/ReloadableMedia.h | 4 ++- .../Graphics/Component/ReloadableText.cpp | 22 +++++------- .../Graphics/Component/ReloadableText.h | 3 +- .../Graphics/Component/ScrollingList.cpp | 36 +++++++++++++------ .../Source/Graphics/Component/ScrollingList.h | 3 ++ RetroFE/Source/Graphics/Component/Text.cpp | 5 +-- RetroFE/Source/Graphics/Component/Text.h | 4 +-- .../Graphics/Component/VideoBuilder.cpp | 4 +-- .../Source/Graphics/Component/VideoBuilder.h | 3 +- .../Graphics/Component/VideoComponent.cpp | 5 +-- .../Graphics/Component/VideoComponent.h | 3 +- RetroFE/Source/Graphics/Page.cpp | 15 ++++++-- RetroFE/Source/Graphics/Page.h | 2 ++ RetroFE/Source/Graphics/PageBuilder.cpp | 28 +++++++++------ RetroFE/Source/Graphics/PageBuilder.h | 2 +- RetroFE/Source/RetroFE.cpp | 2 ++ 25 files changed, 120 insertions(+), 79 deletions(-) diff --git a/RetroFE/Source/Graphics/Component/Component.cpp b/RetroFE/Source/Graphics/Component/Component.cpp index 3fcb79f..3b81db2 100644 --- a/RetroFE/Source/Graphics/Component/Component.cpp +++ b/RetroFE/Source/Graphics/Component/Component.cpp @@ -19,10 +19,10 @@ #include "../../Utility/Log.h" #include "../../SDL.h" -Component::Component() +Component::Component(Page &p) +: page(p) { tweens_ = NULL; - selectedItem_ = NULL; newItemSelectedSinceEnter = false; backgroundTexture_ = NULL; freeGraphicsMemory(); @@ -30,9 +30,9 @@ Component::Component() } Component::Component(const Component ©) + : page(copy.page) { tweens_ = NULL; - selectedItem_ = NULL; newItemSelectedSinceEnter = false; backgroundTexture_ = NULL; freeGraphicsMemory(); @@ -98,11 +98,6 @@ void Component::allocateGraphicsMemory() } } -Item *Component::getSelectedItem() -{ - return selectedItem_; -} - void Component::triggerEnterEvent() { enterRequested = true; @@ -132,10 +127,9 @@ void Component::triggerMenuExitEvent(int menuIndex) menuExitRequested = true; menuExitIndex = menuIndex; } -void Component::triggerHighlightEvent(Item *selectedItem) +void Component::triggerHighlightEvent() { newItemSelected = true; - this->selectedItem_ = selectedItem; } void Component::triggerPlaylistChangeEvent(std::string name) diff --git a/RetroFE/Source/Graphics/Component/Component.h b/RetroFE/Source/Graphics/Component/Component.h index d8b8a26..495961e 100644 --- a/RetroFE/Source/Graphics/Component/Component.h +++ b/RetroFE/Source/Graphics/Component/Component.h @@ -19,15 +19,15 @@ #include "../../SDL.h" #include "../MenuNotifierInterface.h" +#include "../Page.h" #include "../ViewInfo.h" #include "../Animate/Tween.h" #include "../Animate/AnimationEvents.h" #include "../../Collection/Item.h" - class Component { public: - Component(); + Component(Page &p); Component(const Component ©); virtual ~Component(); virtual void freeGraphicsMemory(); @@ -39,7 +39,7 @@ public: void triggerMenuEnterEvent(int menuIndex = -1); void triggerMenuExitEvent(int menuIndex = -1); void triggerMenuScrollEvent(); - void triggerHighlightEvent(Item *selectedItem); + void triggerHighlightEvent(); void triggerPlaylistChangeEvent(std::string name); bool isIdle(); bool isHidden(); @@ -55,7 +55,8 @@ public: bool scrollActive; protected: - Item *getSelectedItem(); + Page &page; + enum AnimationState { IDLE, @@ -90,7 +91,6 @@ private: AnimationEvents *tweens_; Animation *currentTweens_; - Item *selectedItem_; SDL_Texture *backgroundTexture_; unsigned int currentTweenIndex_; diff --git a/RetroFE/Source/Graphics/Component/Container.cpp b/RetroFE/Source/Graphics/Component/Container.cpp index df8982b..1b59d1e 100644 --- a/RetroFE/Source/Graphics/Component/Container.cpp +++ b/RetroFE/Source/Graphics/Component/Container.cpp @@ -18,7 +18,8 @@ #include "../ViewInfo.h" #include "../../SDL.h" -Container::Container() +Container::Container(Page &p) +: Component(p) { allocateGraphicsMemory(); } diff --git a/RetroFE/Source/Graphics/Component/Container.h b/RetroFE/Source/Graphics/Component/Container.h index 9c04a63..d98c0d4 100644 --- a/RetroFE/Source/Graphics/Component/Container.h +++ b/RetroFE/Source/Graphics/Component/Container.h @@ -22,7 +22,7 @@ class Container : public Component { public: - Container(); + Container(Page &p); virtual ~Container(); void freeGraphicsMemory(); void allocateGraphicsMemory(); diff --git a/RetroFE/Source/Graphics/Component/Image.cpp b/RetroFE/Source/Graphics/Component/Image.cpp index 347f7be..d13de5b 100644 --- a/RetroFE/Source/Graphics/Component/Image.cpp +++ b/RetroFE/Source/Graphics/Component/Image.cpp @@ -19,8 +19,9 @@ #include "../../Utility/Log.h" #include -Image::Image(std::string file, float scaleX, float scaleY) - : texture_(NULL) +Image::Image(std::string file, Page &p, float scaleX, float scaleY) + : Component(p) + , texture_(NULL) , file_(file) , scaleX_(scaleX) , scaleY_(scaleY) diff --git a/RetroFE/Source/Graphics/Component/Image.h b/RetroFE/Source/Graphics/Component/Image.h index 4798793..6dd5ff3 100644 --- a/RetroFE/Source/Graphics/Component/Image.h +++ b/RetroFE/Source/Graphics/Component/Image.h @@ -22,7 +22,7 @@ class Image : public Component { public: - Image(std::string file, float scaleX, float scaleY); + Image(std::string file, Page &p, float scaleX, float scaleY); virtual ~Image(); void freeGraphicsMemory(); void allocateGraphicsMemory(); diff --git a/RetroFE/Source/Graphics/Component/ImageBuilder.cpp b/RetroFE/Source/Graphics/Component/ImageBuilder.cpp index 964b1c7..8da2923 100644 --- a/RetroFE/Source/Graphics/Component/ImageBuilder.cpp +++ b/RetroFE/Source/Graphics/Component/ImageBuilder.cpp @@ -18,7 +18,7 @@ #include "../../Utility/Log.h" #include -Image * ImageBuilder::CreateImage(std::string path, std::string name, float scaleX, float scaleY) +Image * ImageBuilder::CreateImage(std::string path, Page &p, std::string name, float scaleX, float scaleY) { Image *image = NULL; std::vector extensions; @@ -35,7 +35,7 @@ Image * ImageBuilder::CreateImage(std::string path, std::string name, float scal if(Utils::findMatchingFile(prefix, extensions, file)) { - image = new Image(file, scaleX, scaleY); + image = new Image(file, p, scaleX, scaleY); } return image; diff --git a/RetroFE/Source/Graphics/Component/ImageBuilder.h b/RetroFE/Source/Graphics/Component/ImageBuilder.h index 7b77ba6..be3dc31 100644 --- a/RetroFE/Source/Graphics/Component/ImageBuilder.h +++ b/RetroFE/Source/Graphics/Component/ImageBuilder.h @@ -15,6 +15,7 @@ */ #pragma once +#include "../Page.h" #include "Image.h" #include "VideoComponent.h" #include "../../Video/VideoFactory.h" @@ -23,5 +24,5 @@ class ImageBuilder { public: - Image * CreateImage(std::string path, std::string name, float scaleX, float scaleY); + Image * CreateImage(std::string path, Page &p, std::string name, float scaleX, float scaleY); }; diff --git a/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp b/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp index fd855dc..2343c1e 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp +++ b/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp @@ -28,8 +28,9 @@ #include #include -ReloadableMedia::ReloadableMedia(Configuration &config, bool systemMode, std::string type, bool isVideo, Font *font, float scaleX, float scaleY) - : config_(config) +ReloadableMedia::ReloadableMedia(Configuration &config, bool systemMode, std::string type, Page &p, int displayOffset, bool isVideo, Font *font, float scaleX, float scaleY) + : Component(p) + , config_(config) , systemMode_(systemMode) , loadedComponent_(NULL) , reloadRequested_(false) @@ -41,6 +42,8 @@ ReloadableMedia::ReloadableMedia(Configuration &config, bool systemMode, std::st , type_(type) , scaleX_(scaleX) , scaleY_(scaleY) + , displayOffset_(displayOffset) + { allocateGraphicsMemory(); } @@ -145,7 +148,7 @@ void ReloadableMedia::reloadTexture() loadedComponent_ = NULL; } - Item *selectedItem = getSelectedItem(); + Item *selectedItem = page.getSelectedItem(displayOffset_); if(!selectedItem) return; config_.getProperty("currentCollection", currentCollection_); @@ -324,7 +327,7 @@ void ReloadableMedia::reloadTexture() // if image and artwork was not specified, fall back to displaying text if(!loadedComponent_ && textFallback_) { - loadedComponent_ = new Text(selectedItem->fullTitle, FfntInst_, scaleX_, scaleY_); + loadedComponent_ = new Text(selectedItem->fullTitle, page, FfntInst_, scaleX_, scaleY_); baseViewInfo.ImageWidth = loadedComponent_->baseViewInfo.ImageWidth; baseViewInfo.ImageHeight = loadedComponent_->baseViewInfo.ImageHeight; } @@ -343,11 +346,11 @@ Component *ReloadableMedia::findComponent(std::string collection, std::string ty if(type == "video") { - component = videoBuild.createVideo(imagePath, basename, scaleX_, scaleY_); + component = videoBuild.createVideo(imagePath, page, basename, scaleX_, scaleY_); } else { - component = imageBuild.CreateImage(imagePath, basename, scaleX_, scaleY_); + component = imageBuild.CreateImage(imagePath, page, basename, scaleX_, scaleY_); } return component; diff --git a/RetroFE/Source/Graphics/Component/ReloadableMedia.h b/RetroFE/Source/Graphics/Component/ReloadableMedia.h index 6cfdaf1..2f5683d 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableMedia.h +++ b/RetroFE/Source/Graphics/Component/ReloadableMedia.h @@ -27,7 +27,7 @@ class Image; class ReloadableMedia : public Component { public: - ReloadableMedia(Configuration &config, bool systemMode, std::string type, bool isVideo, Font *font, float scaleX, float scaleY); + ReloadableMedia(Configuration &config, bool systemMode, std::string type, Page &page, int displayOffset, bool isVideo, Font *font, float scaleX, float scaleY); virtual ~ReloadableMedia(); void update(float dt); void draw(); @@ -54,4 +54,6 @@ private: float scaleX_; float scaleY_; std::string currentCollection_; + Page *page_; + int displayOffset_; }; diff --git a/RetroFE/Source/Graphics/Component/ReloadableText.cpp b/RetroFE/Source/Graphics/Component/ReloadableText.cpp index 430a274..d0b21af 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableText.cpp +++ b/RetroFE/Source/Graphics/Component/ReloadableText.cpp @@ -23,9 +23,9 @@ #include #include -ReloadableText::ReloadableText(std::string type, Page *page, Font *font, std::string layoutKey, float scaleX, float scaleY) - : imageInst_(NULL) - , page_(page) +ReloadableText::ReloadableText(std::string type, Page &page, Font *font, std::string layoutKey, float scaleX, float scaleY) + : Component(page) + , imageInst_(NULL) , layoutKey_(layoutKey) , reloadRequested_(false) , firstLoad_(true) @@ -145,7 +145,7 @@ void ReloadableText::ReloadTexture() imageInst_ = NULL; } - Item *selectedItem = getSelectedItem(); + Item *selectedItem = page.getSelectedItem(); if (selectedItem != NULL) { @@ -175,26 +175,20 @@ void ReloadableText::ReloadTexture() ss << playlistName; break; case TextTypeCollectionName: - if (page_ != NULL) { - ss << page_->getCollectionName(); - } + ss << page.getCollectionName(); break; case TextTypeCollectionSize: - if (page_ != NULL) { - ss << page_->getCollectionSize(); - } + ss << page.getCollectionSize(); break; case TextTypeCollectionIndex: - if (page_ != NULL) { - ss << (1+page_->getSelectedIndex()); - } + ss << (1+page.getSelectedIndex()); break; default: break; } - imageInst_ = new Text(ss.str(), fontInst_, scaleX_, scaleY_); + imageInst_ = new Text(ss.str(), page, fontInst_, scaleX_, scaleY_); } } diff --git a/RetroFE/Source/Graphics/Component/ReloadableText.h b/RetroFE/Source/Graphics/Component/ReloadableText.h index 608026b..d0dfcb4 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableText.h +++ b/RetroFE/Source/Graphics/Component/ReloadableText.h @@ -25,7 +25,7 @@ class ReloadableText : public Component { public: - ReloadableText(std::string type, Page *page, Font *font, std::string layoutKey, float scaleX, float scaleY); + ReloadableText(std::string type, Page &page, Font *font, std::string layoutKey, float scaleX, float scaleY); virtual ~ReloadableText(); void update(float dt); void draw(); @@ -54,7 +54,6 @@ private: Text *imageInst_; TextType type_; - Page *page_; std::string layoutKey_; bool reloadRequested_; bool firstLoad_; diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index f8f5da3..49fd45b 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -14,13 +14,13 @@ * along with RetroFE. If not, see . */ +#include "ScrollingList.h" #include "../Animate/Tween.h" #include "../Animate/TweenSet.h" #include "../Animate/Animation.h" #include "../Animate/AnimationEvents.h" #include "../Animate/TweenTypes.h" #include "../Font.h" -#include "ScrollingList.h" #include "ImageBuilder.h" #include "VideoBuilder.h" #include "VideoComponent.h" @@ -40,12 +40,14 @@ //todo: remove coupling from configuration data (if possible) ScrollingList::ScrollingList(Configuration &c, + Page &p, float scaleX, float scaleY, Font *font, std::string layoutKey, std::string imageType) - : horizontalScroll(false) + : Component(p) + , horizontalScroll(false) , spriteList_(NULL) , scrollPoints_(NULL) , tweenPoints_(NULL) @@ -226,6 +228,20 @@ void ScrollingList::setSelectedIndex(int selectedIndex) selectedOffsetIndex_ = selectedIndex; } +Item *ScrollingList::getItemByOffset(int offset) +{ + if(!items_ || items_->size() == 0) return NULL; + unsigned int index = getSelectedIndex(); + if(offset > 0) { + index = loopIncrement(index, offset, items_->size()); + } + else if(offset < 0) { + index = loopDecrement(index, offset*-1, items_->size()); + } + + return items_->at(index); +} + void ScrollingList::click(double nextScrollTime) { if(currentScrollDirection_ == ScrollDirectionBack) @@ -569,53 +585,53 @@ bool ScrollingList::allocateTexture(unsigned int index, Item *item) // check collection path for art based on gamename config_.getMediaPropertyAbsolutePath(collectionName, imageType_, false, imagePath); - t = imageBuild.CreateImage(imagePath, item->name, scaleX_, scaleY_); + t = imageBuild.CreateImage(imagePath, page, item->name, scaleX_, scaleY_); // check sub-collection path for art based on gamename if(!t) { config_.getMediaPropertyAbsolutePath(item->collectionInfo->name, imageType_, false, imagePath); - t = imageBuild.CreateImage(imagePath, item->name, scaleX_, scaleY_); + t = imageBuild.CreateImage(imagePath, page, item->name, scaleX_, scaleY_); } // check collection path for art based on game name (full title) if(!t && item->title != item->fullTitle) { config_.getMediaPropertyAbsolutePath(collectionName, imageType_, false, imagePath); - t = imageBuild.CreateImage(imagePath, item->fullTitle, scaleX_, scaleY_); + t = imageBuild.CreateImage(imagePath, page, item->fullTitle, scaleX_, scaleY_); } // check sub-collection path for art based on game name (full title) if(!t && item->title != item->fullTitle) { config_.getMediaPropertyAbsolutePath(item->collectionInfo->name, imageType_, false, imagePath); - t = imageBuild.CreateImage(imagePath, item->fullTitle, scaleX_, scaleY_); + t = imageBuild.CreateImage(imagePath, page, item->fullTitle, scaleX_, scaleY_); } // check collection path for art based on parent game name if(!t && item->cloneof != "") { config_.getMediaPropertyAbsolutePath(collectionName, imageType_, false, imagePath); - t = imageBuild.CreateImage(imagePath, item->cloneof, scaleX_, scaleY_); + t = imageBuild.CreateImage(imagePath, page, item->cloneof, scaleX_, scaleY_); } // check sub-collection path for art based on parent game name if(!t && item->cloneof != "") { config_.getMediaPropertyAbsolutePath(item->collectionInfo->name, imageType_, false, imagePath); - t = imageBuild.CreateImage(imagePath, item->cloneof, scaleX_, scaleY_); + t = imageBuild.CreateImage(imagePath, page, item->cloneof, scaleX_, scaleY_); } // check collection path for art based on system name if(!t) { config_.getMediaPropertyAbsolutePath(item->name, imageType_, true, imagePath); - t = imageBuild.CreateImage(imagePath, imageType_, scaleX_, scaleY_); + t = imageBuild.CreateImage(imagePath, page, imageType_, scaleX_, scaleY_); } if (!t) { - t = new Text(item->title, fontInst_, scaleX_, scaleY_); + t = new Text(item->title, page, fontInst_, scaleX_, scaleY_); } if(t) diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.h b/RetroFE/Source/Graphics/Component/ScrollingList.h index 3702cb9..4dafc51 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.h +++ b/RetroFE/Source/Graphics/Component/ScrollingList.h @@ -18,6 +18,7 @@ #include #include "Component.h" #include "../Animate/Tween.h" +#include "../Page.h" #include "../MenuNotifierInterface.h" #include "../ViewInfo.h" #include "../../Database/Configuration.h" @@ -43,6 +44,7 @@ public: }; ScrollingList(Configuration &c, + Page &p, float scaleX, float scaleY, Font *font, @@ -72,6 +74,7 @@ public: unsigned int getScrollOffsetIndex(); void setScrollOffsetIndex(unsigned int index); void setSelectedIndex(int selectedIndex); + Item *getItemByOffset(int offset); void addComponentForNotifications(MenuNotifierInterface *c); void removeComponentForNotifications(MenuNotifierInterface *c); void freeGraphicsMemory(); diff --git a/RetroFE/Source/Graphics/Component/Text.cpp b/RetroFE/Source/Graphics/Component/Text.cpp index d703cf3..c065ae2 100644 --- a/RetroFE/Source/Graphics/Component/Text.cpp +++ b/RetroFE/Source/Graphics/Component/Text.cpp @@ -20,8 +20,9 @@ #include "../Font.h" #include -Text::Text(std::string text, Font *font, float scaleX, float scaleY) - : textData_(text) +Text::Text(std::string text, Page &p, Font *font, float scaleX, float scaleY) + : Component(p) + , textData_(text) , fontInst_(font) , scaleX_(scaleX) , scaleY_(scaleY) diff --git a/RetroFE/Source/Graphics/Component/Text.h b/RetroFE/Source/Graphics/Component/Text.h index 6f38a64..321cd44 100644 --- a/RetroFE/Source/Graphics/Component/Text.h +++ b/RetroFE/Source/Graphics/Component/Text.h @@ -16,7 +16,7 @@ #pragma once #include "Component.h" - +#include "../Page.h" #include #include @@ -26,7 +26,7 @@ class Text : public Component { public: //todo: should have a Font flass that references fontcache, pass that in as an argument - Text(std::string text, Font *font, float scaleX, float scaleY); + Text(std::string text, Page &p, Font *font, float scaleX, float scaleY); virtual ~Text(); void setText(std::string text); void allocateGraphicsMemory(); diff --git a/RetroFE/Source/Graphics/Component/VideoBuilder.cpp b/RetroFE/Source/Graphics/Component/VideoBuilder.cpp index fd3e950..30b615c 100644 --- a/RetroFE/Source/Graphics/Component/VideoBuilder.cpp +++ b/RetroFE/Source/Graphics/Component/VideoBuilder.cpp @@ -21,7 +21,7 @@ #include -VideoComponent * VideoBuilder::createVideo(std::string path, std::string name, float scaleX, float scaleY) +VideoComponent * VideoBuilder::createVideo(std::string path, Page &page, std::string name, float scaleX, float scaleY) { VideoComponent *component = NULL; std::vector extensions; @@ -40,7 +40,7 @@ VideoComponent * VideoBuilder::createVideo(std::string path, std::string name, f if(video) { - component = new VideoComponent(video, file, scaleX, scaleY); + component = new VideoComponent(video, page, file, scaleX, scaleY); } } diff --git a/RetroFE/Source/Graphics/Component/VideoBuilder.h b/RetroFE/Source/Graphics/Component/VideoBuilder.h index f944587..bd9954e 100644 --- a/RetroFE/Source/Graphics/Component/VideoBuilder.h +++ b/RetroFE/Source/Graphics/Component/VideoBuilder.h @@ -17,13 +17,14 @@ #include "Image.h" #include "VideoComponent.h" +#include "../Page.h" #include "../../Video/VideoFactory.h" //todo: this is more of a factory than a builder class VideoBuilder { public: - VideoComponent * createVideo(std::string path, std::string name, float scaleX, float scaleY); + VideoComponent * createVideo(std::string path, Page &page, std::string name, float scaleX, float scaleY); private: VideoFactory factory_; diff --git a/RetroFE/Source/Graphics/Component/VideoComponent.cpp b/RetroFE/Source/Graphics/Component/VideoComponent.cpp index 3b63bbd..672b6b4 100644 --- a/RetroFE/Source/Graphics/Component/VideoComponent.cpp +++ b/RetroFE/Source/Graphics/Component/VideoComponent.cpp @@ -20,8 +20,9 @@ #include "../../Utility/Log.h" #include "../../SDL.h" -VideoComponent::VideoComponent(IVideo *videoInst, std::string videoFile, float scaleX, float scaleY) - : videoFile_(videoFile) +VideoComponent::VideoComponent(IVideo *videoInst, Page &p, std::string videoFile, float scaleX, float scaleY) + : Component(p) + , videoFile_(videoFile) , videoInst_(videoInst) , scaleX_(scaleX) , scaleY_(scaleY) diff --git a/RetroFE/Source/Graphics/Component/VideoComponent.h b/RetroFE/Source/Graphics/Component/VideoComponent.h index 81fa93a..9477c7b 100644 --- a/RetroFE/Source/Graphics/Component/VideoComponent.h +++ b/RetroFE/Source/Graphics/Component/VideoComponent.h @@ -16,6 +16,7 @@ #pragma once #include "Component.h" #include "Image.h" +#include "../Page.h" #include "../../Collection/Item.h" #include "../../Video/IVideo.h" #include @@ -24,7 +25,7 @@ class VideoComponent : public Component { public: - VideoComponent(IVideo *videoInst, std::string videoFile, float scaleX, float scaleY); + VideoComponent(IVideo *videoInst, Page &p, std::string videoFile, float scaleX, float scaleY); virtual ~VideoComponent(); void update(float dt); void draw(); diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index d2c0c07..a6ab599 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -44,6 +44,11 @@ Page::Page(Configuration &config) } Page::~Page() +{ +} + + +void Page::DeInitialize() { MenuVector_T::iterator it = menus_.begin(); while(it != menus_.end()) @@ -292,6 +297,12 @@ Item *Page::getSelectedItem() return selectedItem_; } +Item *Page::getSelectedItem(int offset) +{ + return activeMenu_->getItemByOffset(offset); +} + + void Page::removeSelectedItem() { /* @@ -352,7 +363,7 @@ void Page::highlight() if(!item) return; if(activeMenu_) { - activeMenu_->triggerHighlightEvent(item); + activeMenu_->triggerHighlightEvent(); activeMenu_->scrollActive = scrollActive_; } @@ -360,7 +371,7 @@ void Page::highlight() { for(std::vector::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) { - (*it)->triggerHighlightEvent(item); + (*it)->triggerHighlightEvent(); (*it)->scrollActive = scrollActive_; } } diff --git a/RetroFE/Source/Graphics/Page.h b/RetroFE/Source/Graphics/Page.h index 852fc9e..8594aee 100644 --- a/RetroFE/Source/Graphics/Page.h +++ b/RetroFE/Source/Graphics/Page.h @@ -43,6 +43,7 @@ public: Page(Configuration &c); virtual ~Page(); + void DeInitialize(); virtual void onNewItemSelected(Item *); bool pushCollection(CollectionInfo *collection); bool popCollection(); @@ -66,6 +67,7 @@ public: bool isHorizontalScroll(); unsigned int getMenuDepth(); Item *getSelectedItem(); + Item *getSelectedItem(int offset); void removeSelectedItem(); void setScrollOffsetIndex(unsigned int i); unsigned int getScrollOffsetIndex(); diff --git a/RetroFE/Source/Graphics/PageBuilder.cpp b/RetroFE/Source/Graphics/PageBuilder.cpp index f6b94d8..5f0c52c 100644 --- a/RetroFE/Source/Graphics/PageBuilder.cpp +++ b/RetroFE/Source/Graphics/PageBuilder.cpp @@ -320,13 +320,13 @@ bool PageBuilder::buildComponents(xml_node<> *layout, Page *page) { for(xml_node<> *componentXml = layout->first_node("menu"); componentXml; componentXml = componentXml->next_sibling("menu")) { - ScrollingList *scrollingList = buildMenu(componentXml); + ScrollingList *scrollingList = buildMenu(componentXml,*page); page->pushMenu(scrollingList); } for(xml_node<> *componentXml = layout->first_node("container"); componentXml; componentXml = componentXml->next_sibling("container")) { - Container *c = new Container(); + Container *c = new Container(*page); buildViewInfo(componentXml, c->baseViewInfo); loadTweens(c, componentXml); page->addComponent(c); @@ -346,7 +346,7 @@ bool PageBuilder::buildComponents(xml_node<> *layout, Page *page) std::string imagePath; imagePath = Utils::combinePath(Configuration::convertToAbsolutePath(layoutPath, imagePath), std::string(src->value())); - Image *c = new Image(imagePath, scaleX_, scaleY_); + Image *c = new Image(imagePath, *page, scaleX_, scaleY_); buildViewInfo(componentXml, c->baseViewInfo); loadTweens(c, componentXml); page->addComponent(c); @@ -365,7 +365,7 @@ bool PageBuilder::buildComponents(xml_node<> *layout, Page *page) else { Font *font = addFont(componentXml, NULL); - Text *c = new Text(value->value(), font, scaleX_, scaleY_); + Text *c = new Text(value->value(), *page, font, scaleX_, scaleY_); buildViewInfo(componentXml, c->baseViewInfo); @@ -377,7 +377,7 @@ bool PageBuilder::buildComponents(xml_node<> *layout, Page *page) for(xml_node<> *componentXml = layout->first_node("statusText"); componentXml; componentXml = componentXml->next_sibling("statusText")) { Font *font = addFont(componentXml, NULL); - Text *c = new Text("", font, scaleX_, scaleY_); + Text *c = new Text("", *page, font, scaleX_, scaleY_); buildViewInfo(componentXml, c->baseViewInfo); @@ -403,8 +403,9 @@ void PageBuilder::loadReloadableImages(xml_node<> *layout, std::string tagName, std::string reloadableVideoPath; xml_attribute<> *type = componentXml->first_attribute("type"); xml_attribute<> *mode = componentXml->first_attribute("mode"); + xml_attribute<> *selectedOffsetXml = componentXml->first_attribute("selectedOffset"); bool systemMode = false; - + int selectedOffset = 0; if(tagName == "reloadableVideo") { type = componentXml->first_attribute("imageType"); @@ -430,6 +431,13 @@ void PageBuilder::loadReloadableImages(xml_node<> *layout, std::string tagName, } } + if(selectedOffsetXml) + { + std::stringstream ss; + ss << selectedOffsetXml->value(); + ss >> selectedOffset; + } + Component *c = NULL; @@ -438,13 +446,13 @@ void PageBuilder::loadReloadableImages(xml_node<> *layout, std::string tagName, if(type) { Font *font = addFont(componentXml, NULL); - c = new ReloadableText(type->value(), page, font, layoutKey, scaleX_, scaleY_); + c = new ReloadableText(type->value(), *page, font, layoutKey, scaleX_, scaleY_); } } else { Font *font = addFont(componentXml, NULL); - c = new ReloadableMedia(config_, systemMode, type->value(), (tagName == "reloadableVideo"), font, scaleX_, scaleY_); + c = new ReloadableMedia(config_, systemMode, type->value(), *page, selectedOffset, (tagName == "reloadableVideo"), font, scaleX_, scaleY_); xml_attribute<> *textFallback = componentXml->first_attribute("textFallback"); if(textFallback && Utils::toLower(textFallback->value()) == "true") @@ -564,7 +572,7 @@ void PageBuilder::buildTweenSet(AnimationEvents *tweens, xml_node<> *componentXm } -ScrollingList * PageBuilder::buildMenu(xml_node<> *menuXml) +ScrollingList * PageBuilder::buildMenu(xml_node<> *menuXml, Page &page) { ScrollingList *menu = NULL; std::string menuType = "vertical"; @@ -596,7 +604,7 @@ ScrollingList * PageBuilder::buildMenu(xml_node<> *menuXml) // on default, text will be rendered to the menu. Preload it into cache. Font *font = addFont(itemDefaults, NULL); - menu = new ScrollingList(config_, scaleX_, scaleY_, font, layoutKey, imageType); + menu = new ScrollingList(config_, page, scaleX_, scaleY_, font, layoutKey, imageType); if(scrollTimeXml) { diff --git a/RetroFE/Source/Graphics/PageBuilder.h b/RetroFE/Source/Graphics/PageBuilder.h index a53602b..bea62ff 100644 --- a/RetroFE/Source/Graphics/PageBuilder.h +++ b/RetroFE/Source/Graphics/PageBuilder.h @@ -58,7 +58,7 @@ private: void loadTweens(Component *c, rapidxml::xml_node<> *componentXml); AnimationEvents *createTweenInstance(rapidxml::xml_node<> *componentXml); void buildTweenSet(AnimationEvents *tweens, rapidxml::xml_node<> *componentXml, std::string tagName, std::string tweenName); - ScrollingList * buildMenu(rapidxml::xml_node<> *menuXml); + ScrollingList * buildMenu(rapidxml::xml_node<> *menuXml, Page &p); void buildCustomMenu(ScrollingList *menu, rapidxml::xml_node<> *menuXml, rapidxml::xml_node<> *itemDefaults); void buildVerticalMenu(ScrollingList *menu, rapidxml::xml_node<> *menuXml, rapidxml::xml_node<> *itemDefaults); int parseMenuPosition(std::string strIndex); diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index 009a032..855d2d8 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -178,6 +178,7 @@ bool RetroFE::deInitialize() if(currentPage_) { + currentPage_->DeInitialize(); delete currentPage_; currentPage_ = NULL; } @@ -288,6 +289,7 @@ void RetroFE::run() } // delete the splash screen and use the standard menu + currentPage_->DeInitialize(); delete currentPage_; currentPage_ = loadPage(); From 2d188fd2b232aebaf7f4a5552bc567f02a87e349 Mon Sep 17 00:00:00 2001 From: emb <> Date: Tue, 27 Oct 2015 22:42:15 -0500 Subject: [PATCH 28/43] Support for checking for new keypresses. Fix playlist updating bug. --- .../Collection/CollectionInfoBuilder.cpp | 39 +++++++++++++------ RetroFE/Source/Control/UserInput.cpp | 14 ++++++- RetroFE/Source/Control/UserInput.h | 3 +- RetroFE/Source/RetroFE.cpp | 6 +-- 4 files changed, 44 insertions(+), 18 deletions(-) diff --git a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp index 79be5c1..65b5518 100644 --- a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp +++ b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp @@ -231,6 +231,7 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me DIR *dp; struct dirent *dirp; std::string path = info->listpath; + std::map allMap; std::map includeFilter; std::map favoritesFilter; std::map excludeFilter; @@ -261,7 +262,6 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me { Logger::write(Logger::ZONE_INFO, "CollectionInfoBuilder", "Checking for \"" + includeFile + "\""); ImportBasicList(info, includeFile, includeFilter); - ImportBasicList(info, favoritesFile, favoritesFilter); ImportBasicList(info, excludeFile, excludeFilter); } @@ -269,9 +269,6 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me std::vector::iterator extensionsIt; info->extensionList(extensions); - info->playlists["all"] = &info->items; - info->playlists["favorites"] = new std::vector(); - dp = opendir(path.c_str()); @@ -279,7 +276,6 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me if(dp == NULL) { Logger::write(Logger::ZONE_INFO, "CollectionInfoBuilder", "Could not read directory \"" + path + "\". Ignore if this is a menu."); - return false; } if(showMissing) @@ -292,13 +288,8 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me } } } - // add the favorites list - for(std::map::iterator it = favoritesFilter.begin(); it != favoritesFilter.end(); it++) - { - info->playlists["favorites"]->push_back(it->second); - } - while((dirp = readdir(dp)) != NULL) + while(dp != NULL && (dirp = readdir(dp)) != NULL) { std::string file = dirp->d_name; @@ -333,7 +324,10 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me } } - closedir(dp); + if(dp != NULL) + { + closedir(dp); + } while(includeFilter.size() > 0) { @@ -352,6 +346,27 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me excludeFilter.erase(it); } + for(std::vector::iterator it = info->items.begin(); it != info->items.end(); it++) { + allMap[(*it)->fullTitle] = *it; + } + + + ImportBasicList(info, favoritesFile, favoritesFilter); + info->playlists["all"] = &info->items; + info->playlists["favorites"] = new std::vector(); + + // add the favorites list + for(std::map::iterator it = favoritesFilter.begin(); it != favoritesFilter.end(); it++) + { + std::map::iterator itemit = allMap.find(it->first); + + if(itemit != allMap.end()) + { + info->playlists["favorites"]->push_back(itemit->second); + } + } + + metaDB_.injectMetadata(info); return true; diff --git a/RetroFE/Source/Control/UserInput.cpp b/RetroFE/Source/Control/UserInput.cpp index e3f89c2..310c0c6 100644 --- a/RetroFE/Source/Control/UserInput.cpp +++ b/RetroFE/Source/Control/UserInput.cpp @@ -30,6 +30,7 @@ UserInput::UserInput(Configuration &c) for(unsigned int i = 0; i < KeyCodeMax; ++i) { keyHandlers_[i] = NULL; + currentKeyState_[i] = false; lastKeyState_[i] = false; } } @@ -234,6 +235,9 @@ void UserInput::resetStates() bool UserInput::update(SDL_Event &e) { bool updated = false; + + memcpy(lastKeyState_, currentKeyState_, sizeof(lastKeyState_)); + for(unsigned int i = 0; i < KeyCodeMax; ++i) { InputHandler *h = keyHandlers_[i]; @@ -241,7 +245,7 @@ bool UserInput::update(SDL_Event &e) { if(h->update(e)) updated = true; - lastKeyState_[i] = h->pressed(); + currentKeyState_[i] = h->pressed(); } } @@ -250,5 +254,11 @@ bool UserInput::update(SDL_Event &e) bool UserInput::keystate(KeyCode_E code) { - return lastKeyState_[code]; + return currentKeyState_[code]; } + +bool UserInput::newKeyPressed(KeyCode_E code) +{ + return currentKeyState_[code] && !lastKeyState_[code]; +} + diff --git a/RetroFE/Source/Control/UserInput.h b/RetroFE/Source/Control/UserInput.h index feaffc5..92f9684 100644 --- a/RetroFE/Source/Control/UserInput.h +++ b/RetroFE/Source/Control/UserInput.h @@ -55,6 +55,7 @@ public: void resetStates(); bool update(SDL_Event &e); bool keystate(KeyCode_E); + bool newKeyPressed(KeyCode_E code); private: bool MapKey(std::string keyDescription, KeyCode_E key); @@ -63,5 +64,5 @@ private: std::vector joysticks_; InputHandler *keyHandlers_[KeyCodeMax]; bool lastKeyState_[KeyCodeMax]; - + bool currentKeyState_[KeyCodeMax]; }; diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index 855d2d8..394d596 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -480,15 +480,15 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) { page->letterScroll(Page::ScrollDirectionForward); } - if(input_.keystate(UserInput::KeyCodeNextPlaylist)) + if(input_.newKeyPressed(UserInput::KeyCodeNextPlaylist)) { page->nextPlaylist(); } - if(input_.keystate(UserInput::KeyCodeRemovePlaylist)) + if(input_.newKeyPressed(UserInput::KeyCodeRemovePlaylist)) { page->removePlaylist(); } - if(input_.keystate(UserInput::KeyCodeAddPlaylist)) + if(input_.newKeyPressed(UserInput::KeyCodeAddPlaylist)) { page->addPlaylist(); } From ba7a5ebfb9f61b796397aa7b738a899578eee2ea Mon Sep 17 00:00:00 2001 From: emb <> Date: Wed, 28 Oct 2015 22:52:44 -0500 Subject: [PATCH 29/43] Reverted ITEM_COLLECTION_NAME, yet again, caused bugs when preloading. --- RetroFE/Source/Database/Configuration.cpp | 5 ++++- RetroFE/Source/Main.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/RetroFE/Source/Database/Configuration.cpp b/RetroFE/Source/Database/Configuration.cpp index 8f8a621..7d3e294 100644 --- a/RetroFE/Source/Database/Configuration.cpp +++ b/RetroFE/Source/Database/Configuration.cpp @@ -133,8 +133,11 @@ bool Configuration::parseLine(std::string collection, std::string keyPrefix, std value = line.substr(position + delimiter.length(), line.length()); value = trimEnds(value); - value = Utils::replace(value, "%ITEM_COLLECTION_NAME%", collection); + if(collection != "") + { + value = Utils::replace(value, "%ITEM_COLLECTION_NAME%", collection); + } properties_.insert(PropertiesPair(key, value)); std::stringstream ss; diff --git a/RetroFE/Source/Main.cpp b/RetroFE/Source/Main.cpp index 519617e..d14bb6a 100644 --- a/RetroFE/Source/Main.cpp +++ b/RetroFE/Source/Main.cpp @@ -115,7 +115,7 @@ bool ImportConfiguration(Configuration *c) std::string importFile = Utils::combinePath(launchersPath, std::string(dirp->d_name)); - if(!c->import(basename, prefix, importFile)) + if(!c->import(prefix, importFile)) { Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not import \"" + importFile + "\""); closedir(dp); From 6aa0a452b5f5425fd6ecb7402be290a252a86835 Mon Sep 17 00:00:00 2001 From: Pieter Hulshoff Date: Tue, 3 May 2016 16:00:36 +0200 Subject: [PATCH 30/43] Fixed font color bug, as implemented by KMetalMind. --- RetroFE/Source/Graphics/Font.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RetroFE/Source/Graphics/Font.cpp b/RetroFE/Source/Graphics/Font.cpp index b1e8354..3d1e70b 100644 --- a/RetroFE/Source/Graphics/Font.cpp +++ b/RetroFE/Source/Graphics/Font.cpp @@ -145,7 +145,7 @@ bool Font::initialize(std::string fontPath, int fontSize, SDL_Color color) SDL_LockMutex(SDL::getMutex()); texture = SDL_CreateTextureFromSurface(SDL::getRenderer(), atlasSurface); - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_ADD); + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); SDL_FreeSurface(atlasSurface); SDL_UnlockMutex(SDL::getMutex()); From 11afa1dad4f68933347e797d0a9846c0570bf25d Mon Sep 17 00:00:00 2001 From: Pieter Hulshoff Date: Tue, 3 May 2016 16:03:13 +0200 Subject: [PATCH 31/43] Removed backslashes from Sega Genesys XML file. --- .../Common/meta/hyperlist/Sega Genesis.xml | 138 +++++++++--------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/Package/Environment/Common/meta/hyperlist/Sega Genesis.xml b/Package/Environment/Common/meta/hyperlist/Sega Genesis.xml index 80e79e2..56c9281 100644 --- a/Package/Environment/Common/meta/hyperlist/Sega Genesis.xml +++ b/Package/Environment/Common/meta/hyperlist/Sega Genesis.xml @@ -1227,7 +1227,7 @@ Yes - Chi Chi\'s Pro Challenge Golf (USA) + Chi Chi's Pro Challenge Golf (USA) 9c3973a4 Coconuts Japan @@ -1337,7 +1337,7 @@ Yes - College Football\'s National Championship (USA) + College Football's National Championship (USA) 172c5dbb Bluesky Innovations @@ -1347,7 +1347,7 @@ Yes - College Football\'s National Championship II (USA) + College Football's National Championship II (USA) 65b64413 Bluesky Innovations @@ -1477,7 +1477,7 @@ Yes - Crystal\'s Pony Tale (USA) + Crystal's Pony Tale (USA) 6cf7a4df Artech Studios @@ -1547,7 +1547,7 @@ Yes - Dashin\' Desperadoes (USA) + Dashin' Desperadoes (USA) dcb76fb7 Data East @@ -1557,7 +1557,7 @@ Yes - David Crane\'s Amazing Tennis (USA) + David Crane's Amazing Tennis (USA) 9177088c Absolute Entertainment @@ -1567,7 +1567,7 @@ Yes - David Robinson\'s Supreme Court (USA, Europe) + David Robinson's Supreme Court (USA, Europe) 512b7599 Sega @@ -1677,7 +1677,7 @@ Yes - Dick Vitale\'s \'Awesome, Baby!\' College Hoops (USA) + Dick Vitale's 'Awesome, Baby!' College Hoops (USA) 1312cf22 Time Warner Interactive @@ -1687,7 +1687,7 @@ Yes - Dino Dini\'s Soccer (Europe) + Dino Dini's Soccer (Europe) 4608f53a Dini and Dini Productions @@ -1717,7 +1717,7 @@ Yes - Dinosaur\'s Tale, A (USA) + Dinosaur's Tale, A (USA) 70155b5b Malibu @@ -1817,7 +1817,7 @@ Yes - Dr. Robotnik\'s Mean Bean Machine (USA) + Dr. Robotnik's Mean Bean Machine (USA) c7ca517f Sega @@ -1837,7 +1837,7 @@ Yes - Dragon\'s Fury (USA, Europe) + Dragon's Fury (USA, Europe) 58037bc6 TechnoSoft @@ -1847,7 +1847,7 @@ Yes - Dragon\'s Revenge (USA, Europe) + Dragon's Revenge (USA, Europe) 841edbc0 Tengen @@ -2057,7 +2057,7 @@ Yes - Evander Holyfield\'s \'Real Deal\' Boxing (World) + Evander Holyfield's 'Real Deal' Boxing (World) 4fef37c8 ACME Interactive @@ -2407,7 +2407,7 @@ Yes - Fun \'N\' Games (USA) + Fun 'N' Games (USA) b5ae351d Leland Interactive Media @@ -2547,7 +2547,7 @@ Yes - George Foreman\'s KO Boxing (USA) + George Foreman's KO Boxing (USA) e1fdc787 Beam Software @@ -2567,7 +2567,7 @@ Yes - Ghouls \'n Ghosts (USA, Europe) (Rev A) + Ghouls 'n Ghosts (USA, Europe) (Rev A) 4f2561d5 AM8 @@ -2607,7 +2607,7 @@ Yes - Goofy\'s Hysterical History Tour (USA) + Goofy's Hysterical History Tour (USA) 4e1cc833 Imagineering @@ -2707,7 +2707,7 @@ Yes - Hard Drivin\' (World) + Hard Drivin' (World) 3225baaf Sterling Silver Software @@ -2727,7 +2727,7 @@ Yes - HardBall \'94 (USA, Europe) + HardBall '94 (USA, Europe) ea9c4878 MindSpan @@ -2737,7 +2737,7 @@ Yes - HardBall \'95 (USA) + HardBall '95 (USA) ed10bc9e MindSpan @@ -2977,7 +2977,7 @@ Yes - Izzy\'s Quest for the Olympic Rings (USA, Europe) + Izzy's Quest for the Olympic Rings (USA, Europe) 77b416e4 Alexandria @@ -2987,7 +2987,7 @@ Yes - Jack Nicklaus\' Power Challenge Golf (USA, Europe) + Jack Nicklaus' Power Challenge Golf (USA, Europe) 5545e909 Accolade @@ -3037,7 +3037,7 @@ Yes - James \'Buster\' Douglas Knockout Boxing (USA, Europe) + James 'Buster' Douglas Knockout Boxing (USA, Europe) 87bbcf2a Domark @@ -3097,7 +3097,7 @@ Yes - Jerry Glanville\'s Pigskin Footbrawl (USA) + Jerry Glanville's Pigskin Footbrawl (USA) e7f48d30 Developer Resources @@ -3117,7 +3117,7 @@ Yes - Jimmy White\'s Whirlwind Snooker (Europe) + Jimmy White's Whirlwind Snooker (Europe) 0aef5b1f Virgin Interactive @@ -3177,7 +3177,7 @@ Yes - John Madden Football \'92 (USA, Europe) + John Madden Football '92 (USA, Europe) 046e3945 Park Place Productions @@ -3187,7 +3187,7 @@ Yes - John Madden Football \'93 (USA, Europe) + John Madden Football '93 (USA, Europe) ca323b3e Park Place Productions @@ -3357,7 +3357,7 @@ Yes - King\'s Bounty - The Conqueror\'s Quest (USA, Europe) + King's Bounty - The Conqueror's Quest (USA, Europe) aa68a92e New World Computing @@ -3377,7 +3377,7 @@ Yes - Krusty\'s Super Fun House (USA, Europe) (v1.1) + Krusty's Super Fun House (USA, Europe) (v1.1) 56976261 Audiogenic @@ -3637,7 +3637,7 @@ Yes - Madden NFL \'94 (USA, Europe) + Madden NFL '94 (USA, Europe) d14b811b High Score Productions @@ -3727,7 +3727,7 @@ Yes - Mary Shelley\'s Frankenstein (USA) + Mary Shelley's Frankenstein (USA) 48993dc3 Bits Studios @@ -3767,7 +3767,7 @@ Yes - McDonald\'s Treasure Land Adventure (USA) + McDonald's Treasure Land Adventure (USA) 04ef4899 Treasure @@ -3897,7 +3897,7 @@ Yes - Michael Jackson\'s Moonwalker (World) (Rev A) + Michael Jackson's Moonwalker (World) (Rev A) 11ce1f9e Ultimate Productions @@ -3927,7 +3927,7 @@ Yes - Mickey\'s Ultimate Challenge (USA) + Mickey's Ultimate Challenge (USA) 30b512ee Designer Software @@ -4177,7 +4177,7 @@ Yes - NBA Action \'94 (USA) + NBA Action '94 (USA) 99c348ba Sega @@ -4187,7 +4187,7 @@ Yes - NBA Action \'95 Starring David Robinson (USA, Europe) + NBA Action '95 Starring David Robinson (USA, Europe) aa7006d6 Sega @@ -4277,7 +4277,7 @@ Yes - NBA Showdown \'94 (USA, Europe) + NBA Showdown '94 (USA, Europe) 160b7090 Electronic Arts @@ -4337,7 +4337,7 @@ Yes - NFL Football \'94 Starring Joe Montana (USA) + NFL Football '94 Starring Joe Montana (USA) 0d486ed5 Bluesky Innovations @@ -4367,7 +4367,7 @@ Yes - NFL Sports Talk Football \'93 Starring Joe Montana (USA, Europe) + NFL Sports Talk Football '93 Starring Joe Montana (USA, Europe) ce0b1fe1 Bluesky Innovations @@ -4377,7 +4377,7 @@ Yes - NFL \'95 (USA, Europe) + NFL '95 (USA, Europe) b58e4a81 Sega @@ -4427,7 +4427,7 @@ Yes - NHL All-Star Hockey \'95 (USA) + NHL All-Star Hockey '95 (USA) e6c0218b Sega @@ -4447,7 +4447,7 @@ Yes - NHL \'94 (USA, Europe) + NHL '94 (USA, Europe) 9438f5dd High Score Productions @@ -4467,7 +4467,7 @@ Yes - Nigel Mansell\'s World Championship Racing (USA) + Nigel Mansell's World Championship Racing (USA) 6bc57b2c Gremlin Interactive @@ -4487,7 +4487,7 @@ Yes - Nobunaga\'s Ambition (USA) + Nobunaga's Ambition (USA) b9bc07bc Koei @@ -4497,7 +4497,7 @@ Yes - Normy\'s Beach Babe-O-Rama (USA, Europe) + Normy's Beach Babe-O-Rama (USA, Europe) b56a8220 Realtime Associates @@ -5087,7 +5087,7 @@ Yes - R.B.I. Baseball \'93 (USA) + R.B.I. Baseball '93 (USA) beafce84 Tengen @@ -5097,7 +5097,7 @@ Yes - R.B.I. Baseball \'94 (USA, Europe) + R.B.I. Baseball '94 (USA, Europe) 4eb4d5e4 Tengen @@ -5107,7 +5107,7 @@ Yes - Race Drivin\' (USA) + Race Drivin' (USA) d737cf3d Polygames @@ -5187,7 +5187,7 @@ Yes - Ren & Stimpy Show Presents Stimpy\'s Invention, The (USA) + Ren & Stimpy Show Presents Stimpy's Invention, The (USA) d9503ba5 Blue Sky Software @@ -5217,7 +5217,7 @@ Yes - Richard Scarry\'s BusyTown (USA) + Richard Scarry's BusyTown (USA) 7bb60c3f Novotrade @@ -5337,7 +5337,7 @@ Yes - Rock n\' Roll Racing (USA) + Rock n' Roll Racing (USA) 6abab577 Blizzard Entertainment @@ -5597,7 +5597,7 @@ Yes - Shanghai II - Dragon\'s Eye (USA) + Shanghai II - Dragon's Eye (USA) ebe9e840 Activision @@ -5687,7 +5687,7 @@ Yes - Simpsons, The - Bart\'s Nightmare (USA, Europe) + Simpsons, The - Bart's Nightmare (USA, Europe) 24d7507c Sculptured Software @@ -5707,7 +5707,7 @@ Yes - Skitchin\' (USA, Europe) + Skitchin' (USA, Europe) f785f9d7 Electronic Arts @@ -5887,7 +5887,7 @@ Yes - Sorcerer\'s Kingdom (USA) (v1.1) + Sorcerer's Kingdom (USA) (v1.1) bb1fc9ce Treco @@ -5907,7 +5907,7 @@ Yes - Space Invaders \'91 (USA) + Space Invaders '91 (USA) bb83b528 Taito @@ -5977,7 +5977,7 @@ Yes - Spider-Man and X-Men - Arcade\'s Revenge (USA, Europe) + Spider-Man and X-Men - Arcade's Revenge (USA, Europe) 4a4414ea Software Creations @@ -6127,7 +6127,7 @@ Yes - Street Fighter II\' - Special Champion Edition (USA) + Street Fighter II' - Special Champion Edition (USA) 13fe08a1 Capcom @@ -6767,7 +6767,7 @@ Yes - Tiny Toon Adventures - Buster\'s Hidden Treasure (USA) + Tiny Toon Adventures - Buster's Hidden Treasure (USA) a26d3ae0 Konami @@ -6787,7 +6787,7 @@ Yes - TNN Outdoors Bass Tournament \'96 (USA) + TNN Outdoors Bass Tournament '96 (USA) 5c523c0b Imagitec Design @@ -6797,7 +6797,7 @@ Yes - Todd\'s Adventures in Slime World (USA) + Todd's Adventures in Slime World (USA) 652e8b7d Epyx @@ -7127,7 +7127,7 @@ Yes - Unnecessary Roughness \'95 (USA) + Unnecessary Roughness '95 (USA) 9920e7b7 Accolade @@ -7337,7 +7337,7 @@ Yes - Wayne\'s World (USA) + Wayne's World (USA) d2cf6ebe Gray Matter @@ -7407,7 +7407,7 @@ Yes - Williams Arcade\'s Greatest Hits (USA) + Williams Arcade's Greatest Hits (USA) d68e9c00 Digital Eclipse @@ -7457,7 +7457,7 @@ Yes - Wiz\'n\'Liz (USA) + Wiz'n'Liz (USA) df036b62 Raising Hell @@ -7587,7 +7587,7 @@ Yes - World Series Baseball \'95 (USA) + World Series Baseball '95 (USA) 25130077 Blue Sky Software @@ -7597,7 +7597,7 @@ Yes - World Series Baseball \'96 (USA) + World Series Baseball '96 (USA) 04ee8272 Blue Sky Software @@ -7787,7 +7787,7 @@ Yes - Zool - Ninja of the \'Nth\' Dimension (USA) + Zool - Ninja of the 'Nth' Dimension (USA) cb2939f1 Gremlin Interactive From 93f6b65c1e440eae9fa88bf427f0d9178345484d Mon Sep 17 00:00:00 2001 From: Pieter Hulshoff Date: Wed, 4 May 2016 10:01:28 +0200 Subject: [PATCH 32/43] Fixed letter up/down selection. --- .../Graphics/Component/ScrollingList.cpp | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index 49fd45b..dfcbdae 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -327,7 +327,7 @@ void ScrollingList::letterChange(bool increment) notifyAllRequested_ = true; deallocateSpritePoints(); - std::string startname = items_->at(itemIndex_)->lowercaseFullTitle(); + std::string startname = items_->at((itemIndex_+selectedOffsetIndex_)%items_->size())->lowercaseFullTitle(); for(unsigned int i = 0; i < items_->size(); ++i) { @@ -335,21 +335,37 @@ void ScrollingList::letterChange(bool increment) if(increment) index = loopIncrement(itemIndex_, i, items_->size()); else index = loopDecrement(itemIndex_, i, items_->size()); - std::string endname = items_->at(index)->lowercaseFullTitle(); + std::string endname = items_->at((index+selectedOffsetIndex_)%items_->size())->lowercaseFullTitle(); // check if we are changing characters from a-z, or changing from alpha character to non-alpha character - if(isalpha(startname[0]) ^ isalpha(endname[0])) - { - break; - itemIndex_ = index; - } - else if(isalpha(startname[0]) && isalpha(endname[0]) && startname[0] != endname[0]) + if((isalpha(startname[0]) ^ isalpha(endname[0])) || + (isalpha(startname[0]) && isalpha(endname[0]) && startname[0] != endname[0])) { itemIndex_ = index; break; } } + if (!increment) // For decrement, find the first game of the new letter + { + startname = items_->at((itemIndex_+selectedOffsetIndex_)%items_->size())->lowercaseFullTitle(); + + for(unsigned int i = 0; i < items_->size(); ++i) + { + unsigned int index = loopDecrement(itemIndex_, i, items_->size()); + + std::string endname = items_->at((index+selectedOffsetIndex_)%items_->size())->lowercaseFullTitle(); + + // check if we are changing characters from a-z, or changing from alpha character to non-alpha character + if((isalpha(startname[0]) ^ isalpha(endname[0])) || + (isalpha(startname[0]) && isalpha(endname[0]) && startname[0] != endname[0])) + { + itemIndex_ = loopIncrement(index,1,items_->size()); + break; + } + } + } + allocateSpritePoints(); } From 9ead0700522703cb40c0df0d31c5e604841b23fb Mon Sep 17 00:00:00 2001 From: Pieter Hulshoff Date: Wed, 4 May 2016 10:22:01 +0200 Subject: [PATCH 33/43] Added support for genre/manufacturer/year for collections, drawing the information from fields of the same name in the collection's settings.conf. --- .../Collection/CollectionInfoBuilder.cpp | 26 +++++++++++-------- .../Graphics/Component/ReloadableText.cpp | 21 ++++++++++++--- .../Graphics/Component/ReloadableText.h | 3 ++- RetroFE/Source/Graphics/PageBuilder.cpp | 2 +- 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp index 65b5518..bcd7707 100644 --- a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp +++ b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp @@ -119,18 +119,22 @@ bool CollectionInfoBuilder::createCollectionDirectory(std::string name) settingsFile << "list.menuSort = yes" << std::endl; settingsFile << std::endl; settingsFile << "launcher = mame" << std::endl; - settingsFile << "metadata.type = MAME" << std::endl; + settingsFile << "#metadata.type = MAME" << std::endl; settingsFile << std::endl; - settingsFile << "#media.screenshot = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screenshot") << std::endl; - settingsFile << "#media.screentitle = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screentitle") << std::endl; - settingsFile << "#media.artwork_back = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "artwork_back") << std::endl; - settingsFile << "#media.artwork_front = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "artwork_front") << std::endl; - settingsFile << "#media.logo = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "logo") << std::endl; - settingsFile << "#media.medium_back = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "medium_back") << std::endl; - settingsFile << "#media.medium_front = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "medium_front") << std::endl; - settingsFile << "#media.screenshot = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screenshot") << std::endl; - settingsFile << "#media.screentitle = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screentitle") << std::endl; - settingsFile << "#media.video = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "video") << std::endl; + settingsFile << "#manufacturer = " << std::endl; + settingsFile << "#year = " << std::endl; + settingsFile << "#genre = " << std::endl; + settingsFile << std::endl; + settingsFile << "#media.screenshot = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screenshot") << std::endl; + settingsFile << "#media.screentitle = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screentitle") << std::endl; + settingsFile << "#media.artwork_back = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "artwork_back") << std::endl; + settingsFile << "#media.artwork_front = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "artwork_front") << std::endl; + settingsFile << "#media.logo = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "logo") << std::endl; + settingsFile << "#media.medium_back = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "medium_back") << std::endl; + settingsFile << "#media.medium_front = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "medium_front") << std::endl; + settingsFile << "#media.screenshot = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screenshot") << std::endl; + settingsFile << "#media.screentitle = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screentitle") << std::endl; + settingsFile << "#media.video = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "video") << std::endl; settingsFile << "#media.system_artwork = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "system_artwork") << std::endl; settingsFile.close(); diff --git a/RetroFE/Source/Graphics/Component/ReloadableText.cpp b/RetroFE/Source/Graphics/Component/ReloadableText.cpp index d0b21af..36997d8 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableText.cpp +++ b/RetroFE/Source/Graphics/Component/ReloadableText.cpp @@ -23,8 +23,9 @@ #include #include -ReloadableText::ReloadableText(std::string type, Page &page, Font *font, std::string layoutKey, float scaleX, float scaleY) +ReloadableText::ReloadableText(std::string type, Page &page, Configuration &config, Font *font, std::string layoutKey, float scaleX, float scaleY) : Component(page) + , config_(config) , imageInst_(NULL) , layoutKey_(layoutKey) , reloadRequested_(false) @@ -160,16 +161,28 @@ void ReloadableText::ReloadTexture() ss << selectedItem->numberPlayers; break; case TextTypeYear: - ss << selectedItem->year; + if (selectedItem->leaf) // item is a leaf + text = selectedItem->year; + else // item is a collection + (void)config_.getProperty("collections." + selectedItem->name + ".year", text ); + ss << text; break; case TextTypeTitle: ss << selectedItem->title; break; case TextTypeManufacturer: - ss << selectedItem->manufacturer; + if (selectedItem->leaf) // item is a leaf + text = selectedItem->manufacturer; + else // item is a collection + (void)config_.getProperty("collections." + selectedItem->name + ".manufacturer", text ); + ss << text; break; case TextTypeGenre: - ss << selectedItem->genre; + if (selectedItem->leaf) // item is a leaf + text = selectedItem->genre; + else // item is a collection + (void)config_.getProperty("collections." + selectedItem->name + ".genre", text ); + ss << text; break; case TextTypePlaylist: ss << playlistName; diff --git a/RetroFE/Source/Graphics/Component/ReloadableText.h b/RetroFE/Source/Graphics/Component/ReloadableText.h index d0dfcb4..5f059f3 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableText.h +++ b/RetroFE/Source/Graphics/Component/ReloadableText.h @@ -25,7 +25,7 @@ class ReloadableText : public Component { public: - ReloadableText(std::string type, Page &page, Font *font, std::string layoutKey, float scaleX, float scaleY); + ReloadableText(std::string type, Page &page, Configuration &config, Font *font, std::string layoutKey, float scaleX, float scaleY); virtual ~ReloadableText(); void update(float dt); void draw(); @@ -52,6 +52,7 @@ private: void ReloadTexture(); + Configuration &config_; Text *imageInst_; TextType type_; std::string layoutKey_; diff --git a/RetroFE/Source/Graphics/PageBuilder.cpp b/RetroFE/Source/Graphics/PageBuilder.cpp index 5f0c52c..7e9e7b8 100644 --- a/RetroFE/Source/Graphics/PageBuilder.cpp +++ b/RetroFE/Source/Graphics/PageBuilder.cpp @@ -446,7 +446,7 @@ void PageBuilder::loadReloadableImages(xml_node<> *layout, std::string tagName, if(type) { Font *font = addFont(componentXml, NULL); - c = new ReloadableText(type->value(), *page, font, layoutKey, scaleX_, scaleY_); + c = new ReloadableText(type->value(), *page, config_, font, layoutKey, scaleX_, scaleY_); } } else From 6189ba6d058119ca63e9ea71a2516d9dadf097c8 Mon Sep 17 00:00:00 2001 From: Pieter Hulshoff Date: Wed, 4 May 2016 10:33:02 +0200 Subject: [PATCH 34/43] Added autoFavorites switch in main settings.conf to automaticaly switch to the favorites playlist if it is available. --- Package/Environment/Common/settings.conf | 3 +++ RetroFE/Source/RetroFE.cpp | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/Package/Environment/Common/settings.conf b/Package/Environment/Common/settings.conf index 38c073f..c001c15 100644 --- a/Package/Environment/Common/settings.conf +++ b/Package/Environment/Common/settings.conf @@ -22,6 +22,9 @@ showSquareBrackets = yes # specify the name of the first collection to load on start firstCollection = Main +# specify whether RetroFE should switch to Favorites list if it exists. +autoFavorites = true + ####################################### # Video playback settings ####################################### diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index 394d596..5b0e35e 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -529,6 +529,12 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) page->setScrollOffsetIndex(lastMenuOffsets_[nextPageItem_->name]); } + bool autoFavorites = true; + config_.getProperty("autoFavorites", autoFavorites); + + if (autoFavorites) + page->nextPlaylist(); // Switch to favorites if it exists + state = RETROFE_NEXT_PAGE_REQUEST; } } From 84d301dd5a08fdf7a11bfe119c2bd7bf26c7e755 Mon Sep 17 00:00:00 2001 From: Pieter Hulshoff Date: Tue, 10 May 2016 08:12:23 +0200 Subject: [PATCH 35/43] Added random seed initialisation for proper random game selection. --- RetroFE/Source/Main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/RetroFE/Source/Main.cpp b/RetroFE/Source/Main.cpp index d14bb6a..21d3b6a 100644 --- a/RetroFE/Source/Main.cpp +++ b/RetroFE/Source/Main.cpp @@ -24,12 +24,16 @@ #include #include #include +#include static bool ImportConfiguration(Configuration *c); static bool StartLogging(); int main(int argc, char **argv) { + // Initialize random seed + srand( time( NULL ) ); + Configuration::initialize(); Configuration config; From 9c47adc9cc4458d12e8d20beb989e19d1827fc31 Mon Sep 17 00:00:00 2001 From: Pieter Hulshoff Date: Wed, 11 May 2016 09:00:55 +0200 Subject: [PATCH 36/43] Corrected switching to favorites list by adding a separate function for that purpose. Restricted playlist add/remove to games for now. Fixed not writing playlist if the playlists directory does not exist; directory is now created. --- RetroFE/Source/Collection/CollectionInfo.cpp | 33 ++++++++++++++++++++ RetroFE/Source/Graphics/Page.cpp | 30 ++++++++++++++++++ RetroFE/Source/Graphics/Page.h | 1 + RetroFE/Source/RetroFE.cpp | 2 +- 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/RetroFE/Source/Collection/CollectionInfo.cpp b/RetroFE/Source/Collection/CollectionInfo.cpp index 59f8f0c..725c767 100644 --- a/RetroFE/Source/Collection/CollectionInfo.cpp +++ b/RetroFE/Source/Collection/CollectionInfo.cpp @@ -23,6 +23,13 @@ #include #include +#ifdef __linux +#include +#include +#include +#include +#endif + CollectionInfo::CollectionInfo(std::string name, std::string listPath, std::string extensions, @@ -76,12 +83,38 @@ bool CollectionInfo::Save() bool retval = true; if(saveRequest) { + std::string dir = Utils::combinePath(Configuration::absolutePath, "collections", name, "playlists"); std::string file = Utils::combinePath(Configuration::absolutePath, "collections", name, "playlists/favorites.txt"); Logger::write(Logger::ZONE_INFO, "Collection", "Saving " + file); std::ofstream filestream; try { + // Create playlists directory if it does not exist yet. + struct stat info; + if ( stat( dir.c_str(), &info ) != 0 && (info.st_mode & S_IFDIR) ) + { +#if defined(_WIN32) && !defined(__GNUC__) + if(!CreateDirectory(dir, NULL)) + { + if(ERROR_ALREADY_EXISTS != GetLastError()) + { + std::cout << "Could not create folder \"" << *it << "\"" << std::endl; + return false; + } + } +#else +#if defined(__MINGW32__) + if(mkdir(dir.c_str()) == -1) +#else + if(mkdir(dir.c_str(), 0755) == -1) +#endif + { + std::cout << "Could not create folder \"" << dir << "\":" << errno << std::endl; + } +#endif + } + filestream.open(file.c_str()); std::vector *saveitems = playlists["favorites"]; for(std::vector::iterator it = saveitems->begin(); it != saveitems->end(); it++) diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index a6ab599..6dd8eb5 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -606,6 +606,34 @@ void Page::nextPlaylist() playlistChanged_ = true; } +void Page::favPlaylist() +{ + MenuInfo_S &info = collections_.back(); + info.collection->Save(); + unsigned int numlists = info.collection->playlists.size(); + + // Store current playlist + CollectionInfo::Playlists_T::iterator playlist_store = playlist_; + + for(unsigned int i = 0; i <= numlists; ++i) + { + 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; + } + + // Do not change playlist if favorites does not exist + if ( playlist_->first != "favorites" ) + playlist_ = playlist_store; + + activeMenu_->setItems(playlist_->second); + activeMenu_->triggerMenuEnterEvent(); + playlistChanged_ = true; +} + void Page::update(float dt) { for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++) @@ -690,6 +718,7 @@ void Page::draw() void Page::removePlaylist() { if(!selectedItem_) return; + if(!selectedItem_->leaf) return; MenuInfo_S &info = collections_.back(); CollectionInfo *collection = info.collection; @@ -713,6 +742,7 @@ void Page::removePlaylist() void Page::addPlaylist() { if(!selectedItem_) return; + if(!selectedItem_->leaf) return; MenuInfo_S &info = collections_.back(); CollectionInfo *collection = info.collection; diff --git a/RetroFE/Source/Graphics/Page.h b/RetroFE/Source/Graphics/Page.h index 8594aee..77c2082 100644 --- a/RetroFE/Source/Graphics/Page.h +++ b/RetroFE/Source/Graphics/Page.h @@ -48,6 +48,7 @@ public: bool pushCollection(CollectionInfo *collection); bool popCollection(); void nextPlaylist(); + void favPlaylist(); void pushMenu(ScrollingList *s); bool isMenusFull(); void setLoadSound(Sound *chunk); diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index 5b0e35e..ca26ed6 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -533,7 +533,7 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) config_.getProperty("autoFavorites", autoFavorites); if (autoFavorites) - page->nextPlaylist(); // Switch to favorites if it exists + page->favPlaylist(); // Switch to favorites if it exists state = RETROFE_NEXT_PAGE_REQUEST; } From 725e340d41a42c768bd1e4424bfca5f4a333f11b Mon Sep 17 00:00:00 2001 From: Pieter Hulshoff Date: Wed, 11 May 2016 09:02:07 +0200 Subject: [PATCH 37/43] Standard directory access should be 755 in stead of 744. --- RetroFE/Source/Collection/CollectionInfoBuilder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp index bcd7707..2843f54 100644 --- a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp +++ b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp @@ -81,7 +81,7 @@ bool CollectionInfoBuilder::createCollectionDirectory(std::string name) #if defined(__MINGW32__) if(mkdir(it->c_str()) == -1) #else - if(mkdir(it->c_str(), 0744) == -1) + if(mkdir(it->c_str(), 0755) == -1) #endif { std::cout << "Could not create folder \"" << *it << "\":" << errno << std::endl; From 5bd357c78ab5a6f857ce3fdb4cdb57c319e05093 Mon Sep 17 00:00:00 2001 From: Pieter Hulshoff Date: Wed, 11 May 2016 11:53:59 +0200 Subject: [PATCH 38/43] Do not switch to an empty favorites list. --- RetroFE/Source/Graphics/Page.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index 6dd8eb5..b88bb09 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -625,8 +625,8 @@ void Page::favPlaylist() if(playlist_->second->size() != 0 && playlist_->first == "favorites") break; } - // Do not change playlist if favorites does not exist - if ( playlist_->first != "favorites" ) + // Do not change playlist if favorites does not exist or if it's empty + if ( playlist_->second->size() == 0 || playlist_->first != "favorites") playlist_ = playlist_store; activeMenu_->setItems(playlist_->second); From 784dfdca169e2b1756b778e65c651acbcf683a6b Mon Sep 17 00:00:00 2001 From: Pieter Hulshoff Date: Wed, 11 May 2016 12:06:43 +0200 Subject: [PATCH 39/43] Added support for manufacturer's graphics for collections. --- RetroFE/Source/Graphics/Component/ReloadableMedia.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp b/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp index 2343c1e..e927835 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp +++ b/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp @@ -255,7 +255,10 @@ void ReloadableMedia::reloadTexture() } else if(typeLC == "manufacturer") { + if ( selectedItem->leaf ) // item is a leaf basename = selectedItem->manufacturer; + else // item is a collection + (void)config_.getProperty("collections." + selectedItem->name + ".manufacturer", basename ); } else if(typeLC == "genre") { From 9150ec2079752ea4e1a44a449da3dd45cc1bdacf Mon Sep 17 00:00:00 2001 From: Pieter Hulshoff Date: Wed, 11 May 2016 12:54:50 +0200 Subject: [PATCH 40/43] Only draw scrollinglist at the requested layer index. --- RetroFE/Source/Graphics/Component/ScrollingList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index dfcbdae..ced3368 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -685,7 +685,7 @@ void ScrollingList::draw(unsigned int layer) for(unsigned int i = 0; i < components_.size(); ++i) { Component *c = components_.at(i); - if(c) c->draw(); + if(c && c->baseViewInfo.Layer == layer) c->draw(); } } From 4e2cc30cc0043ea5de9ef570e9477143edb9fddd Mon Sep 17 00:00:00 2001 From: Pieter Hulshoff Date: Wed, 11 May 2016 13:37:48 +0200 Subject: [PATCH 41/43] Added layer check when drawing components. Increased maximum number of layers to 20. --- RetroFE/Source/Graphics/Page.cpp | 2 +- RetroFE/Source/Graphics/Page.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index b88bb09..b889fff 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -703,7 +703,7 @@ void Page::draw() { for(std::vector::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) { - if(*it) (*it)->draw(); + if(*it && (*it)->baseViewInfo.Layer == i) (*it)->draw(); } for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++) diff --git a/RetroFE/Source/Graphics/Page.h b/RetroFE/Source/Graphics/Page.h index 77c2082..a53e28c 100644 --- a/RetroFE/Source/Graphics/Page.h +++ b/RetroFE/Source/Graphics/Page.h @@ -111,7 +111,7 @@ private: CollectionVector_T collections_; CollectionVector_T deleteCollections_; - static const unsigned int NUM_LAYERS = 8; + static const unsigned int NUM_LAYERS = 20; std::vector LayerComponents[NUM_LAYERS]; std::list deleteMenuList_; std::list deleteCollectionList_; From 11c04d6fbc27ec1f2bd4329012925b3e7459af95 Mon Sep 17 00:00:00 2001 From: Pieter Hulshoff Date: Wed, 11 May 2016 14:22:54 +0200 Subject: [PATCH 42/43] Fixed issues with playlists directory, and added warning messages. --- RetroFE/Source/Collection/CollectionInfo.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/RetroFE/Source/Collection/CollectionInfo.cpp b/RetroFE/Source/Collection/CollectionInfo.cpp index 725c767..45ce6b9 100644 --- a/RetroFE/Source/Collection/CollectionInfo.cpp +++ b/RetroFE/Source/Collection/CollectionInfo.cpp @@ -92,14 +92,14 @@ bool CollectionInfo::Save() { // Create playlists directory if it does not exist yet. struct stat info; - if ( stat( dir.c_str(), &info ) != 0 && (info.st_mode & S_IFDIR) ) + if ( stat( dir.c_str(), &info ) != 0 ) { #if defined(_WIN32) && !defined(__GNUC__) if(!CreateDirectory(dir, NULL)) { if(ERROR_ALREADY_EXISTS != GetLastError()) { - std::cout << "Could not create folder \"" << *it << "\"" << std::endl; + Logger::write(Logger::ZONE_WARNING, "Collection", "Could not create directory " + dir); return false; } } @@ -110,10 +110,16 @@ bool CollectionInfo::Save() if(mkdir(dir.c_str(), 0755) == -1) #endif { - std::cout << "Could not create folder \"" << dir << "\":" << errno << std::endl; + Logger::write(Logger::ZONE_WARNING, "Collection", "Could not create directory " + dir); + return false; } #endif } + else if ( !(info.st_mode & S_IFDIR) ) + { + Logger::write(Logger::ZONE_WARNING, "Collection", dir + " exists, but is not a directory."); + return false; + } filestream.open(file.c_str()); std::vector *saveitems = playlists["favorites"]; From 1061205d4faa5c96793a75ebacd851145d2d5426 Mon Sep 17 00:00:00 2001 From: Pieter Hulshoff Date: Sat, 14 May 2016 08:20:46 +0200 Subject: [PATCH 43/43] Fixed Windows compile errors. --- RetroFE/Source/Collection/CollectionInfo.cpp | 10 +++++++--- RetroFE/Source/Main.cpp | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/RetroFE/Source/Collection/CollectionInfo.cpp b/RetroFE/Source/Collection/CollectionInfo.cpp index 45ce6b9..9071728 100644 --- a/RetroFE/Source/Collection/CollectionInfo.cpp +++ b/RetroFE/Source/Collection/CollectionInfo.cpp @@ -22,10 +22,14 @@ #include #include #include - -#ifdef __linux #include #include + +#ifdef _WIN32 +#include +#endif + +#ifdef __linux #include #include #endif @@ -95,7 +99,7 @@ bool CollectionInfo::Save() if ( stat( dir.c_str(), &info ) != 0 ) { #if defined(_WIN32) && !defined(__GNUC__) - if(!CreateDirectory(dir, NULL)) + if(!CreateDirectory(dir.c_str(), NULL)) { if(ERROR_ALREADY_EXISTS != GetLastError()) { diff --git a/RetroFE/Source/Main.cpp b/RetroFE/Source/Main.cpp index 21d3b6a..0915f38 100644 --- a/RetroFE/Source/Main.cpp +++ b/RetroFE/Source/Main.cpp @@ -32,7 +32,7 @@ static bool StartLogging(); int main(int argc, char **argv) { // Initialize random seed - srand( time( NULL ) ); + srand(static_cast(time(0))); Configuration::initialize();