diff --git a/RetroFE/Source/CMakeLists.txt b/RetroFE/Source/CMakeLists.txt index a4449b9..c9e14f6 100755 --- a/RetroFE/Source/CMakeLists.txt +++ b/RetroFE/Source/CMakeLists.txt @@ -131,6 +131,7 @@ set(RETROFE_HEADERS "${RETROFE_DIR}/Source/Graphics/FontCache.h" "${RETROFE_DIR}/Source/Graphics/PageBuilder.h" "${RETROFE_DIR}/Source/Graphics/Page.h" + "${RETROFE_DIR}/Source/Menu/Menu.h" "${RETROFE_DIR}/Source/Sound/Sound.h" "${RETROFE_DIR}/Source/Utility/Log.h" "${RETROFE_DIR}/Source/Utility/Utils.h" @@ -183,6 +184,7 @@ set(RETROFE_SOURCES "${RETROFE_DIR}/Source/Graphics/Component/VideoBuilder.cpp" "${RETROFE_DIR}/Source/Graphics/Component/VideoComponent.cpp" "${RETROFE_DIR}/Source/Graphics/Component/Video.cpp" + "${RETROFE_DIR}/Source/Menu/Menu.cpp" "${RETROFE_DIR}/Source/Sound/Sound.cpp" "${RETROFE_DIR}/Source/Utility/Log.cpp" "${RETROFE_DIR}/Source/Utility/Utils.cpp" diff --git a/RetroFE/Source/Collection/CollectionInfoBuilder.h b/RetroFE/Source/Collection/CollectionInfoBuilder.h index 7ad7c4c..0323224 100644 --- a/RetroFE/Source/Collection/CollectionInfoBuilder.h +++ b/RetroFE/Source/Collection/CollectionInfoBuilder.h @@ -34,12 +34,12 @@ public: void addPlaylists(CollectionInfo *info); void injectMetadata(CollectionInfo *info); static bool createCollectionDirectory(std::string collectionName); + bool ImportBasicList(CollectionInfo *info, std::string file, std::vector &list); private: Configuration &conf_; MetadataDatabase &metaDB_; bool ImportBasicList(CollectionInfo *info, std::string file, std::map &list); - bool ImportBasicList(CollectionInfo *info, std::string file, std::vector &list); bool ImportDirectory(CollectionInfo *info, std::string mergedCollectionName); void ImportRomDirectory(std::string path, CollectionInfo *info, std::map includeFilter, std::map excludeFilter, bool romHierarchy); }; diff --git a/RetroFE/Source/Control/UserInput.cpp b/RetroFE/Source/Control/UserInput.cpp index 2e06c83..4378cbc 100644 --- a/RetroFE/Source/Control/UserInput.cpp +++ b/RetroFE/Source/Control/UserInput.cpp @@ -63,6 +63,7 @@ bool UserInput::initialize() MapKey("addPlaylist", KeyCodeAddPlaylist, false); MapKey("removePlaylist", KeyCodeRemovePlaylist, false); MapKey("random", KeyCodeRandom, false); + MapKey("menu", KeyCodeMenu, true); bool retVal = true; @@ -86,8 +87,9 @@ bool UserInput::initialize() // These keys are mandatory retVal = MapKey("select", KeyCodeSelect) && retVal; - retVal = MapKey("back", KeyCodeBack) && retVal; - retVal = MapKey("quit", KeyCodeQuit) && retVal; + retVal = MapKey("back", KeyCodeBack) && retVal; + retVal = MapKey("quit", KeyCodeQuit) && retVal; + retVal = MapKey("menu", KeyCodeMenu) && retVal; return retVal; } diff --git a/RetroFE/Source/Control/UserInput.h b/RetroFE/Source/Control/UserInput.h index 10ebd4c..3fc0e7e 100644 --- a/RetroFE/Source/Control/UserInput.h +++ b/RetroFE/Source/Control/UserInput.h @@ -45,6 +45,7 @@ public: KeyCodeNextPlaylist, KeyCodePrevPlaylist, KeyCodeRandom, + KeyCodeMenu, KeyCodeAddPlaylist, KeyCodeRemovePlaylist, KeyCodeAdminMode, diff --git a/RetroFE/Source/Graphics/Component/Component.h b/RetroFE/Source/Graphics/Component/Component.h index a5e0d1a..2b0aa2a 100644 --- a/RetroFE/Source/Graphics/Component/Component.h +++ b/RetroFE/Source/Graphics/Component/Component.h @@ -50,6 +50,7 @@ public: std::string collectionName; void setMenuScrollReload(bool menuScrollReload); bool getMenuScrollReload(); + virtual void setInput(std::string text) {}; protected: Page &page; diff --git a/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp b/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp index 93b6168..b493de9 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp +++ b/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp @@ -28,12 +28,13 @@ #include #include -ReloadableMedia::ReloadableMedia(Configuration &config, bool systemMode, bool layoutMode, bool commonMode, std::string type, Page &p, int displayOffset, bool isVideo, Font *font, float scaleX, float scaleY) +ReloadableMedia::ReloadableMedia(Configuration &config, bool systemMode, bool layoutMode, bool commonMode, bool menuMode, std::string type, Page &p, int displayOffset, bool isVideo, Font *font, float scaleX, float scaleY) : Component(p) , config_(config) , systemMode_(systemMode) , layoutMode_(layoutMode) , commonMode_(commonMode) + , menuMode_(menuMode) , loadedComponent_(NULL) , videoInst_(NULL) , isVideo_(isVideo) diff --git a/RetroFE/Source/Graphics/Component/ReloadableMedia.h b/RetroFE/Source/Graphics/Component/ReloadableMedia.h index ac4a84d..cdf69ea 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, bool layoutMode, bool commonMode, std::string type, Page &page, int displayOffset, bool isVideo, Font *font, float scaleX, float scaleY); + ReloadableMedia(Configuration &config, bool systemMode, bool layoutMode, bool commonMode, bool menuMode, std::string type, Page &page, int displayOffset, bool isVideo, Font *font, float scaleX, float scaleY); virtual ~ReloadableMedia(); void update(float dt); void draw(); @@ -43,6 +43,7 @@ private: bool systemMode_; bool layoutMode_; bool commonMode_; + bool menuMode_; Component *loadedComponent_; IVideo *videoInst_; bool isVideo_; diff --git a/RetroFE/Source/Graphics/Component/ReloadableScrollingText.cpp b/RetroFE/Source/Graphics/Component/ReloadableScrollingText.cpp index b4ce42b..2a4bb14 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableScrollingText.cpp +++ b/RetroFE/Source/Graphics/Component/ReloadableScrollingText.cpp @@ -28,11 +28,12 @@ #include -ReloadableScrollingText::ReloadableScrollingText(Configuration &config, bool systemMode, bool layoutMode, std::string type, std::string textFormat, std::string singlePrefix, std::string singlePostfix, std::string pluralPrefix, std::string pluralPostfix, std::string alignment, Page &p, int displayOffset, Font *font, float scaleX, float scaleY, std::string direction, float scrollingSpeed, float startPosition, float startTime, float endTime ) +ReloadableScrollingText::ReloadableScrollingText(Configuration &config, bool systemMode, bool layoutMode, bool menuMode, std::string type, std::string textFormat, std::string singlePrefix, std::string singlePostfix, std::string pluralPrefix, std::string pluralPostfix, std::string alignment, Page &p, int displayOffset, Font *font, float scaleX, float scaleY, std::string direction, float scrollingSpeed, float startPosition, float startTime, float endTime ) : Component(p) , config_(config) , systemMode_(systemMode) , layoutMode_(layoutMode) + , menuMode_(menuMode) , fontInst_(font) , type_(type) , textFormat_(textFormat) diff --git a/RetroFE/Source/Graphics/Component/ReloadableScrollingText.h b/RetroFE/Source/Graphics/Component/ReloadableScrollingText.h index 70cf5a9..e3577ed 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableScrollingText.h +++ b/RetroFE/Source/Graphics/Component/ReloadableScrollingText.h @@ -24,7 +24,7 @@ class ReloadableScrollingText : public Component { public: - ReloadableScrollingText(Configuration &config, bool systemMode, bool layoutMode, std::string type, std::string textFormat, std::string singlePrefix, std::string singlePostfix, std::string pluralPrefix, std::string pluralPostfix, std::string alignment, Page &page, int displayOffset, Font *font, float scaleX, float scaleY, std::string direction, float scrollingSpeed, float startPosition, float startTime, float endTime ); + ReloadableScrollingText(Configuration &config, bool systemMode, bool layoutMode, bool menuMode, std::string type, std::string textFormat, std::string singlePrefix, std::string singlePostfix, std::string pluralPrefix, std::string pluralPostfix, std::string alignment, Page &page, int displayOffset, Font *font, float scaleX, float scaleY, std::string direction, float scrollingSpeed, float startPosition, float startTime, float endTime ); virtual ~ReloadableScrollingText( ); void update(float dt); void draw( ); @@ -39,6 +39,7 @@ private: Configuration &config_; bool systemMode_; bool layoutMode_; + bool menuMode_; Font *fontInst_; std::string type_; std::string textFormat_; diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index 628cbd1..992d4d5 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -43,50 +43,53 @@ ScrollingList::ScrollingList( Configuration &c, Page &p, bool layoutMode, + bool commonMode, float scaleX, float scaleY, Font *font, std::string layoutKey, std::string imageType ) - : Component(p ) - , horizontalScroll(false ) - , layoutMode_(layoutMode ) - , spriteList_(NULL ) - , scrollPoints_(NULL ) - , tweenPoints_(NULL ) - , itemIndex_(0 ) - , selectedOffsetIndex_(0 ) - , scrollAcceleration_(0 ) - , startScrollTime_(0.500 ) - , scrollPeriod_(0 ) - , config_(c ) - , scaleX_(scaleX ) - , scaleY_(scaleY ) - , fontInst_(font ) - , layoutKey_(layoutKey ) - , imageType_(imageType ) - , items_(NULL ) + : Component( p ) + , horizontalScroll( false ) + , layoutMode_( layoutMode ) + , commonMode_( commonMode ) + , spriteList_( NULL ) + , scrollPoints_( NULL ) + , tweenPoints_( NULL ) + , itemIndex_( 0 ) + , selectedOffsetIndex_( 0 ) + , scrollAcceleration_( 0 ) + , startScrollTime_( 0.500 ) + , scrollPeriod_( 0 ) + , config_( c ) + , scaleX_( scaleX ) + , scaleY_( scaleY ) + , fontInst_( font ) + , layoutKey_( layoutKey ) + , imageType_( imageType ) + , items_( NULL ) { } ScrollingList::ScrollingList( const ScrollingList © ) - : Component(copy ) - , horizontalScroll(copy.horizontalScroll ) - , layoutMode_(copy.layoutMode_ ) - , spriteList_(NULL ) - , itemIndex_(0 ) - , selectedOffsetIndex_(copy.selectedOffsetIndex_ ) - , scrollAcceleration_(copy.scrollAcceleration_ ) - , startScrollTime_(copy.startScrollTime_ ) - , scrollPeriod_(copy.startScrollTime_ ) - , config_(copy.config_ ) - , scaleX_(copy.scaleX_ ) - , scaleY_(copy.scaleY_ ) - , fontInst_(copy.fontInst_ ) - , layoutKey_(copy.layoutKey_ ) - , imageType_(copy.imageType_ ) - , items_(NULL ) + : Component( copy ) + , horizontalScroll( copy.horizontalScroll ) + , layoutMode_( copy.layoutMode_ ) + , commonMode_( copy.commonMode_ ) + , spriteList_( NULL ) + , itemIndex_( 0 ) + , selectedOffsetIndex_( copy.selectedOffsetIndex_ ) + , scrollAcceleration_( copy.scrollAcceleration_ ) + , startScrollTime_( copy.startScrollTime_ ) + , scrollPeriod_( copy.startScrollTime_ ) + , config_( copy.config_ ) + , scaleX_( copy.scaleX_ ) + , scaleY_( copy.scaleY_ ) + , fontInst_( copy.fontInst_ ) + , layoutKey_( copy.layoutKey_ ) + , imageType_( copy.imageType_ ) + , items_( NULL ) { scrollPoints_ = NULL; tweenPoints_ = NULL; @@ -530,91 +533,82 @@ bool ScrollingList::allocateTexture( unsigned int index, Item *item ) std::string layoutName; config_.getProperty( "layout", layoutName ); - // check collection path for art based on gamename - if ( layoutMode_ ) - { - imagePath = Utils::combinePath( Configuration::absolutePath, "layouts", layoutName, "collections", collectionName ); - imagePath = Utils::combinePath( imagePath, "medium_artwork", imageType_ ); - } - else - { - config_.getMediaPropertyAbsolutePath( collectionName, imageType_, false, imagePath ); - } - t = imageBuild.CreateImage( imagePath, page, item->name, scaleX_, scaleY_ ); + std::string typeLC = Utils::toLower( imageType_ ); - // check sub-collection path for art based on gamename - if ( !t ) + std::vector names; + names.push_back( item->name ); + names.push_back( item->fullTitle ); + if ( item->cloneof != "" ) + names.push_back( item->cloneof ); + if ( typeLC == "numberbuttons" ) + names.push_back( item->numberButtons ); + if ( typeLC == "numberplayers" ) + names.push_back( item->numberPlayers ); + if ( typeLC == "year" ) + names.push_back( item->year ); + if ( typeLC == "title" ) + names.push_back( item->title ); + if ( typeLC == "developer" ) { + if ( item->developer == "" ) + { + names.push_back( item->manufacturer ); + } + else + { + names.push_back( item->developer ); + } + } + if ( typeLC == "manufacturer" ) + names.push_back( item->manufacturer ); + if ( typeLC == "genre" ) + names.push_back( item->genre ); + if ( typeLC == "ctrltype" ) + names.push_back( item->ctrlType ); + if ( typeLC == "joyways" ) + names.push_back( item->joyWays ); + if ( typeLC == "rating" ) + names.push_back( item->rating ); + if ( typeLC == "score" ) + names.push_back( item->score ); + names.push_back("default"); + + for ( unsigned int n = 0; n < names.size() && !t; ++n ) + { + // check collection path for art if ( layoutMode_ ) { - imagePath = Utils::combinePath( Configuration::absolutePath, "layouts", layoutName, "collections", item->collectionInfo->name ); + if ( commonMode_ ) + imagePath = Utils::combinePath(Configuration::absolutePath, "layouts", layoutName, "collections", "_common"); + else + imagePath = Utils::combinePath( Configuration::absolutePath, "layouts", layoutName, "collections", collectionName ); imagePath = Utils::combinePath( imagePath, "medium_artwork", imageType_ ); } else { - config_.getMediaPropertyAbsolutePath( item->collectionInfo->name, imageType_, false, imagePath ); + if ( commonMode_ ) + { + imagePath = Utils::combinePath(Configuration::absolutePath, "collections", "_common" ); + imagePath = Utils::combinePath( imagePath, "medium_artwork", imageType_ ); + } + else + config_.getMediaPropertyAbsolutePath( collectionName, imageType_, false, imagePath ); } - 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 ) - { - if ( layoutMode_ ) + t = imageBuild.CreateImage( imagePath, page, names[n], scaleX_, scaleY_ ); + // check sub-collection path for art + if ( !t && !commonMode_ ) { - imagePath = Utils::combinePath( Configuration::absolutePath, "layouts", layoutName, "collections", collectionName ); - imagePath = Utils::combinePath( imagePath, "medium_artwork", imageType_ ); + if ( layoutMode_ ) + { + imagePath = Utils::combinePath( Configuration::absolutePath, "layouts", layoutName, "collections", item->collectionInfo->name ); + imagePath = Utils::combinePath( imagePath, "medium_artwork", imageType_ ); + } + else + { + config_.getMediaPropertyAbsolutePath( item->collectionInfo->name, imageType_, false, imagePath ); + } + t = imageBuild.CreateImage( imagePath, page, names[n], scaleX_, scaleY_ ); } - else - { - config_.getMediaPropertyAbsolutePath( collectionName, imageType_, false, imagePath ); - } - 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 ) - { - if ( layoutMode_ ) - { - imagePath = Utils::combinePath( Configuration::absolutePath, "layouts", layoutName, "collections", item->collectionInfo->name ); - imagePath = Utils::combinePath( imagePath, "medium_artwork", imageType_ ); - } - else - { - config_.getMediaPropertyAbsolutePath( item->collectionInfo->name, imageType_, false, imagePath ); - } - t = imageBuild.CreateImage( imagePath, page, item->fullTitle, scaleX_, scaleY_ ); - } - - // check collection path for art based on parent game name - if ( !t && item->cloneof != "" ) - { - if ( layoutMode_ ) - { - imagePath = Utils::combinePath( Configuration::absolutePath, "layouts", layoutName, "collections", collectionName ); - imagePath = Utils::combinePath( imagePath, "medium_artwork", imageType_ ); - } - else - { - config_.getMediaPropertyAbsolutePath( collectionName, imageType_, false, imagePath ); - } - t = imageBuild.CreateImage( imagePath, page, item->cloneof, scaleX_, scaleY_ ); - } - - // check sub-collection path for art based on parent game name - if ( !t && item->cloneof != "" ) - { - if ( layoutMode_ ) - { - imagePath = Utils::combinePath( Configuration::absolutePath, "layouts", layoutName, "collections", item->collectionInfo->name ); - imagePath = Utils::combinePath( imagePath, "medium_artwork", imageType_ ); - } - else - { - config_.getMediaPropertyAbsolutePath( item->collectionInfo->name, imageType_, false, imagePath ); - } - t = imageBuild.CreateImage( imagePath, page, item->cloneof, scaleX_, scaleY_ ); } // check collection path for art based on system name @@ -622,12 +616,21 @@ bool ScrollingList::allocateTexture( unsigned int index, Item *item ) { if ( layoutMode_ ) { - imagePath = Utils::combinePath( Configuration::absolutePath, "layouts", layoutName, "collections", item->name ); + if ( commonMode_ ) + imagePath = Utils::combinePath(Configuration::absolutePath, "layouts", layoutName, "collections", "_common"); + else + imagePath = Utils::combinePath( Configuration::absolutePath, "layouts", layoutName, "collections", item->name ); imagePath = Utils::combinePath( imagePath, "system_artwork" ); } else { - config_.getMediaPropertyAbsolutePath( item->name, imageType_, true, imagePath ); + if ( commonMode_ ) + { + imagePath = Utils::combinePath(Configuration::absolutePath, "collections", "_common" ); + imagePath = Utils::combinePath( imagePath, "system_artwork" ); + } + else + config_.getMediaPropertyAbsolutePath( item->name, imageType_, true, imagePath ); } t = imageBuild.CreateImage( imagePath, page, imageType_, scaleX_, scaleY_ ); } diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.h b/RetroFE/Source/Graphics/Component/ScrollingList.h index 12a7246..bb3aeb0 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.h +++ b/RetroFE/Source/Graphics/Component/ScrollingList.h @@ -36,6 +36,7 @@ public: ScrollingList( Configuration &c, Page &p, bool layoutMode, + bool commonMode, float scaleX, float scaleY, Font *font, @@ -94,6 +95,7 @@ private: unsigned int loopDecrement( unsigned int offset, unsigned int i, unsigned int size ); bool layoutMode_; + bool commonMode_; std::vector *spriteList_; std::vector *scrollPoints_; std::vector *tweenPoints_; diff --git a/RetroFE/Source/Graphics/Component/Text.cpp b/RetroFE/Source/Graphics/Component/Text.cpp index 7b66723..5aa156c 100644 --- a/RetroFE/Source/Graphics/Component/Text.cpp +++ b/RetroFE/Source/Graphics/Component/Text.cpp @@ -14,64 +14,72 @@ * along with RetroFE. If not, see . */ + #include "Text.h" #include "../../Utility/Log.h" #include "../../SDL.h" #include "../Font.h" #include -Text::Text(std::string text, Page &p, Font *font, float scaleX, float scaleY) + +Text::Text( std::string text, Page &p, Font *font, float scaleX, float scaleY, bool input ) : Component(p) , textData_(text) , fontInst_(font) , scaleX_(scaleX) , scaleY_(scaleY) + , input_(input) { - allocateGraphicsMemory(); + allocateGraphicsMemory( ); } -Text::~Text() +Text::~Text( ) { - freeGraphicsMemory(); + freeGraphicsMemory( ); } -void Text::freeGraphicsMemory() +void Text::freeGraphicsMemory( ) { - Component::freeGraphicsMemory(); + Component::freeGraphicsMemory( ); } -void Text::allocateGraphicsMemory() +void Text::allocateGraphicsMemory( ) { - //todo: make the font blend color a parameter that is passed in - Component::allocateGraphicsMemory(); + Component::allocateGraphicsMemory( ); } -void Text::deInitializeFonts() +void Text::deInitializeFonts( ) { - fontInst_->deInitialize(); + fontInst_->deInitialize( ); } -void Text::initializeFonts() +void Text::initializeFonts( ) { - fontInst_->initialize(); + fontInst_->initialize( ); } -void Text::setText(std::string text) +void Text::setText( std::string text ) { textData_ = text; } -void Text::draw() +void Text::setInput( std::string text ) { - Component::draw(); + if ( input_ ) + textData_ = text; +} + +void Text::draw( ) +{ + Component::draw( ); Font *font; - if (baseViewInfo.font) // Use font of this specific item if available + if ( baseViewInfo.font ) // Use font of this specific item if available font = baseViewInfo.font; - else // If not, use the general font settings + else // If not, use the general font settings font = fontInst_; - SDL_Texture *t = font->getTexture(); + SDL_Texture *t = font->getTexture( ); float imageHeight = 0; float imageWidth = 0; @@ -85,23 +93,23 @@ void Text::draw() imageMaxWidth = baseViewInfo.MaxWidth; } - imageHeight = (float)font->getHeight(); + imageHeight = (float)font->getHeight( ); float scale = (float)baseViewInfo.FontSize / (float)imageHeight; unsigned int textIndexMax = 0; // determine image width - for(unsigned int i = 0; i < textData_.size(); ++i) + for ( unsigned int i = 0; i < textData_.size( ); ++i ) { Font::GlyphInfo glyph; - if(font->getRect(textData_[i], glyph)) + if ( font->getRect( textData_[i], glyph ) ) { - if(glyph.minX < 0) + if ( glyph.minX < 0 ) { imageWidth += glyph.minX; } - if ((imageWidth + glyph.advance)*scale > imageMaxWidth ) + if ( (imageWidth + glyph.advance)*scale > imageMaxWidth ) { break; } @@ -112,56 +120,55 @@ void Text::draw() } - float oldWidth = baseViewInfo.Width; - float oldHeight = baseViewInfo.Height; - float oldImageWidth = baseViewInfo.ImageHeight; + float oldWidth = baseViewInfo.Width; + float oldHeight = baseViewInfo.Height; + float oldImageWidth = baseViewInfo.ImageHeight; float oldImageHeight = baseViewInfo.ImageWidth; - baseViewInfo.Width = imageWidth*scale; - baseViewInfo.Height = baseViewInfo.FontSize; - baseViewInfo.ImageWidth = imageWidth; + baseViewInfo.Width = imageWidth*scale; + baseViewInfo.Height = baseViewInfo.FontSize; + baseViewInfo.ImageWidth = imageWidth; baseViewInfo.ImageHeight = imageHeight; - float xOrigin = baseViewInfo.XRelativeToOrigin(); - float yOrigin = baseViewInfo.YRelativeToOrigin(); + float xOrigin = baseViewInfo.XRelativeToOrigin( ); + float yOrigin = baseViewInfo.YRelativeToOrigin( ); - baseViewInfo.Width = oldWidth; - baseViewInfo.Height = oldHeight; - baseViewInfo.ImageWidth = oldImageWidth; + baseViewInfo.Width = oldWidth; + baseViewInfo.Height = oldHeight; + baseViewInfo.ImageWidth = oldImageWidth; baseViewInfo.ImageHeight = oldImageHeight; SDL_Rect rect; - rect.x = static_cast(xOrigin); + rect.x = static_cast( xOrigin ); - for(unsigned int i = 0; i <= textIndexMax; ++i) + for ( unsigned int i = 0; i <= textIndexMax; ++i ) { Font::GlyphInfo glyph; - if(font->getRect(textData_[i], glyph) && glyph.rect.h > 0) + if ( font->getRect(textData_[i], glyph) && glyph.rect.h > 0 ) { SDL_Rect charRect = glyph.rect; - float h = static_cast(charRect.h * scale); - float w = static_cast(charRect.w * scale); - rect.h = static_cast(h); - rect.w = static_cast(w); - rect.y = static_cast(yOrigin); + float h = static_cast( charRect.h * scale ); + float w = static_cast( charRect.w * scale ); + rect.h = static_cast( h ); + rect.w = static_cast( w ); + rect.y = static_cast( yOrigin ); if(glyph.minX < 0) { - rect.x += static_cast((float)(glyph.minX) * scale); + rect.x += static_cast( (float)(glyph.minX) * scale ); } - if(font->getAscent() < glyph.maxY) + if ( font->getAscent( ) < glyph.maxY ) { - rect.y += static_cast((font->getAscent() - glyph.maxY)*scale); + rect.y += static_cast( (font->getAscent( ) - glyph.maxY)*scale ); } - SDL::renderCopy(t, baseViewInfo.Alpha, &charRect, &rect, baseViewInfo); + SDL::renderCopy( t, baseViewInfo.Alpha, &charRect, &rect, baseViewInfo ); - rect.x += static_cast(glyph.advance * scale); + rect.x += static_cast( glyph.advance * scale ); } } } - diff --git a/RetroFE/Source/Graphics/Component/Text.h b/RetroFE/Source/Graphics/Component/Text.h index bdb0765..411a5cf 100644 --- a/RetroFE/Source/Graphics/Component/Text.h +++ b/RetroFE/Source/Graphics/Component/Text.h @@ -15,29 +15,34 @@ */ #pragma once + #include "Component.h" #include "../Page.h" #include #include + class Font; + class Text : public Component { + public: - //todo: should have a Font flass that references fontcache, pass that in as an argument - Text(std::string text, Page &p, Font *font, float scaleX, float scaleY); - virtual ~Text(); - void setText(std::string text); - void allocateGraphicsMemory(); - void freeGraphicsMemory(); - void deInitializeFonts(); - void initializeFonts(); - void draw(); + Text( std::string text, Page &p, Font *font, float scaleX, float scaleY, bool input = false ); + virtual ~Text( ); + void setText( std::string text ); + void setInput( std::string text ); + void allocateGraphicsMemory( ); + void freeGraphicsMemory( ); + void deInitializeFonts( ); + void initializeFonts( ); + void draw( ); private: std::string textData_; - Font *fontInst_; - float scaleX_; - float scaleY_; + Font *fontInst_; + float scaleX_; + float scaleY_; + bool input_; }; diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index c14664e..bef02d8 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -483,6 +483,24 @@ void Page::highlightExit() } +void Page::menuAction( std::string action ) +{ + for(std::vector::iterator it = LayerComponents.begin(); it != LayerComponents.end(); ++it) + { + (*it)->triggerEvent( action ); + } +} + + +void Page::menuInput( std::string text ) +{ + for(std::vector::iterator it = LayerComponents.begin(); it != LayerComponents.end(); ++it) + { + (*it)->setInput( text ); + } +} + + void Page::setScrolling(ScrollDirection direction) { switch(direction) @@ -1042,10 +1060,13 @@ void Page::allocateGraphicsMemory() for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++) { - for(std::vector::iterator it2 = menus_[std::distance(menus_.begin(), it)].begin(); it2 != menus_[std::distance(menus_.begin(), it)].end(); it2++) + if ( std::distance(menus_.begin(), it) < menuDepth_ ) { - ScrollingList *menu = *it2; - menu->allocateGraphicsMemory(); + for(std::vector::iterator it2 = menus_[std::distance(menus_.begin(), it)].begin(); it2 != menus_[std::distance(menus_.begin(), it)].end(); it2++) + { + ScrollingList *menu = *it2; + menu->allocateGraphicsMemory(); + } } } diff --git a/RetroFE/Source/Graphics/Page.h b/RetroFE/Source/Graphics/Page.h index bbb2247..d25e072 100644 --- a/RetroFE/Source/Graphics/Page.h +++ b/RetroFE/Source/Graphics/Page.h @@ -98,6 +98,8 @@ public: void menuScroll(); void highlightEnter(); void highlightExit(); + void menuAction( std::string action ); + void menuInput( std::string text ); void addPlaylist(); void removePlaylist(); void reallocateMenuSpritePoints(); diff --git a/RetroFE/Source/Graphics/PageBuilder.cpp b/RetroFE/Source/Graphics/PageBuilder.cpp index 506ab04..26da4b5 100644 --- a/RetroFE/Source/Graphics/PageBuilder.cpp +++ b/RetroFE/Source/Graphics/PageBuilder.cpp @@ -49,7 +49,7 @@ static const int MENU_END = -2; // last item transitions here after it scroll static const int MENU_CENTER = -4; //todo: this file is starting to become a god class of building. Consider splitting into sub-builders -PageBuilder::PageBuilder(std::string layoutKey, std::string layoutPage, Configuration &c, FontCache *fc) +PageBuilder::PageBuilder(std::string layoutKey, std::string layoutPage, Configuration &c, FontCache *fc, bool isMenu) : layoutKey(layoutKey) , layoutPage(layoutPage) , config_(c) @@ -59,6 +59,7 @@ PageBuilder::PageBuilder(std::string layoutKey, std::string layoutPage, Configur , screenWidth_(0) , fontSize_(24) , fontCache_(fc) + , isMenu_(isMenu) { screenWidth_ = SDL::getWindowWidth(); screenHeight_ = SDL::getWindowHeight(); @@ -80,7 +81,11 @@ Page *PageBuilder::buildPage( std::string collectionName ) std::string layoutFileAspect; std::string layoutName = layoutKey; - if ( collectionName == "" ) + if ( isMenu_ ) + { + layoutPath = Utils::combinePath(Configuration::absolutePath, "menu"); + } + else if ( collectionName == "" ) { layoutPath = Utils::combinePath(Configuration::absolutePath, "layouts", layoutName); } @@ -523,6 +528,7 @@ void PageBuilder::loadReloadableImages(xml_node<> *layout, std::string tagName, bool systemMode = false; bool layoutMode = false; bool commonMode = false; + bool menuMode = false; int selectedOffset = 0; if(tagName == "reloadableVideo") { @@ -569,6 +575,10 @@ void PageBuilder::loadReloadableImages(xml_node<> *layout, std::string tagName, systemMode = true; layoutMode = true; } + if(sysMode == "menu") + { + menuMode = true; + } } if(selectedOffsetXml) @@ -686,7 +696,7 @@ void PageBuilder::loadReloadableImages(xml_node<> *layout, std::string tagName, { pluralPostfix = pluralPostfixXml->value(); } - c = new ReloadableScrollingText(config_, systemMode, layoutMode, type->value(), singlePrefix, singlePostfix, pluralPrefix, pluralPostfix, textFormat, alignment, *page, selectedOffset, font, scaleX_, scaleY_, direction, scrollingSpeed, startPosition, startTime, endTime); + c = new ReloadableScrollingText(config_, systemMode, layoutMode, menuMode, type->value(), singlePrefix, singlePostfix, pluralPrefix, pluralPostfix, textFormat, alignment, *page, selectedOffset, font, scaleX_, scaleY_, direction, scrollingSpeed, startPosition, startTime, endTime); xml_attribute<> *menuScrollReload = componentXml->first_attribute("menuScrollReload"); if (menuScrollReload && (Utils::toLower(menuScrollReload->value()) == "true" || @@ -699,7 +709,7 @@ void PageBuilder::loadReloadableImages(xml_node<> *layout, std::string tagName, else { Font *font = addFont(componentXml, NULL); - c = new ReloadableMedia(config_, systemMode, layoutMode, commonMode, type->value(), *page, selectedOffset, (tagName == "reloadableVideo"), font, scaleX_, scaleY_); + c = new ReloadableMedia(config_, systemMode, layoutMode, commonMode, menuMode, type->value(), *page, selectedOffset, (tagName == "reloadableVideo"), font, scaleX_, scaleY_); xml_attribute<> *menuScrollReload = componentXml->first_attribute("menuScrollReload"); if (menuScrollReload && (Utils::toLower(menuScrollReload->value()) == "true" || @@ -812,6 +822,11 @@ AnimationEvents *PageBuilder::createTweenInstance(xml_node<> *componentXml) buildTweenSet(tweens, componentXml, "onGameEnter", "gameEnter"); buildTweenSet(tweens, componentXml, "onGameExit", "gameExit"); + buildTweenSet(tweens, componentXml, "onMenuActionInputEnter", "menuActionInputEnter"); + buildTweenSet(tweens, componentXml, "onMenuActionInputExit", "menuActionInputExit"); + buildTweenSet(tweens, componentXml, "onMenuActionSelectEnter", "menuActionSelectEnter"); + buildTweenSet(tweens, componentXml, "onMenuActionSelectExit", "menuActionSelectExit"); + return tweens; } @@ -921,6 +936,7 @@ ScrollingList * PageBuilder::buildMenu(xml_node<> *menuXml, Page &page) } bool layoutMode = false; + bool commonMode = false; if(modeXml) { std::string sysMode = modeXml->value(); @@ -928,12 +944,21 @@ ScrollingList * PageBuilder::buildMenu(xml_node<> *menuXml, Page &page) { layoutMode = true; } + if(sysMode == "common") + { + commonMode = true; + } + if(sysMode == "commonlayout") + { + layoutMode = true; + commonMode = true; + } } // on default, text will be rendered to the menu. Preload it into cache. Font *font = addFont(itemDefaults, NULL); - menu = new ScrollingList(config_, page, layoutMode, scaleX_, scaleY_, font, layoutKey, imageType); + menu = new ScrollingList(config_, page, layoutMode, commonMode, scaleX_, scaleY_, font, layoutKey, imageType); if(scrollTimeXml) { diff --git a/RetroFE/Source/Graphics/PageBuilder.h b/RetroFE/Source/Graphics/PageBuilder.h index 5386f56..87451fd 100644 --- a/RetroFE/Source/Graphics/PageBuilder.h +++ b/RetroFE/Source/Graphics/PageBuilder.h @@ -33,7 +33,7 @@ class Font; class PageBuilder { public: - PageBuilder(std::string layoutKey, std::string layoutPage, Configuration &c, FontCache *fc); + PageBuilder(std::string layoutKey, std::string layoutPage, Configuration &c, FontCache *fc, bool isMenu = false); virtual ~PageBuilder(); Page *buildPage( std::string collectionName = "" ); @@ -50,6 +50,7 @@ private: std::string fontName_; int fontSize_; FontCache *fontCache_; + bool isMenu_; Font *addFont(rapidxml::xml_node<> *component, rapidxml::xml_node<> *defaults); void loadReloadableImages(rapidxml::xml_node<> *layout, std::string tagName, Page *page); diff --git a/RetroFE/Source/Menu/Menu.cpp b/RetroFE/Source/Menu/Menu.cpp new file mode 100644 index 0000000..16051a3 --- /dev/null +++ b/RetroFE/Source/Menu/Menu.cpp @@ -0,0 +1,46 @@ +/* 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 "Menu.h" +#include "../Collection/Item.h" +#include + + +Menu::Menu( Configuration &c ) + : config_( c ) +{ + page_ = nullptr; +} + + +void Menu::handleEntry( Item *item ) +{ + std::cout << "Handling " + item->ctrlType + "." << std::endl; + return; +} + + +void Menu::setPage( Page *page ) +{ + page_ = page; +} + + +void Menu::clearPage( ) +{ + page_ = nullptr; +} diff --git a/RetroFE/Source/Menu/Menu.h b/RetroFE/Source/Menu/Menu.h new file mode 100644 index 0000000..e17e76f --- /dev/null +++ b/RetroFE/Source/Menu/Menu.h @@ -0,0 +1,37 @@ +/* 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 + + +class Configuration; +class Item; +class Page; + + +class Menu +{ + +public: + Menu( Configuration &c ); + void handleEntry( Item *item ); + void setPage( Page *page ); + void clearPage( ); + +private: + Configuration &config_; + Page *page_; + +}; diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index 7e8690e..1a3b9fe 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -21,6 +21,7 @@ #include "Database/Configuration.h" #include "Collection/Item.h" #include "Execute/Launcher.h" +#include "Menu/Menu.h" #include "Utility/Log.h" #include "Utility/Utils.h" #include "Collection/MenuParser.h" @@ -35,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +70,7 @@ RetroFE::RetroFE( Configuration &c ) , keyLastTime_(0) , keyDelayTime_(.3f) { + menuMode_ = false; } @@ -274,21 +277,8 @@ void RetroFE::run( ) std::string controlsConfPath = Utils::combinePath( Configuration::absolutePath, "controls.conf" ); if ( !config_.import( "controls", controlsConfPath ) ) { - - // Let the user input new controls - get_controls_config( ); - - // Re-initialize SDL to reset the controller situation - SDL::deInitialize( ); - if(! SDL::initialize( config_ ) ) return; - - // Retry reading the control configuration - if ( !config_.import( "controls", controlsConfPath ) ) - { - Logger::write( Logger::ZONE_ERROR, "RetroFE", "Could not import \"" + controlsConfPath + "\"" ); - return; - } - + Logger::write( Logger::ZONE_ERROR, "RetroFE", "Could not import \"" + controlsConfPath + "\"" ); + return; } float preloadTime = 0; @@ -330,6 +320,7 @@ void RetroFE::run( ) bool exitSplashMode = false; Launcher l( config_ ); + Menu m( config_ ); preloadTime = static_cast( SDL_GetTicks( ) ) / 1000; while ( running ) @@ -472,6 +463,7 @@ void RetroFE::run( ) case RETROFE_PLAYLIST_LOAD_ART: if (currentPage_->isIdle( )) { + currentPage_->onNewItemSelected( ); currentPage_->reallocateMenuSpritePoints( ); currentPage_->highlightEnter( ); state = RETROFE_PLAYLIST_ENTER; @@ -555,22 +547,29 @@ void RetroFE::run( ) { lastMenuOffsets_[currentPage_->getCollectionName( )] = currentPage_->getScrollOffsetIndex( ); lastMenuPlaylists_[currentPage_->getCollectionName( )] = currentPage_->getPlaylistName( ); - // Load new layout if available - std::string layoutName; - config_.getProperty( "layout", layoutName ); - PageBuilder pb(layoutName, "layout", config_, &fontcache_); - Page *page = pb.buildPage( nextPageItem_->name); std::string nextPageName = nextPageItem_->name; - if ( page ) + if ( !menuMode_ ) { - currentPage_->freeGraphicsMemory( ); - pages_.push( currentPage_ ); - currentPage_ = page; + // Load new layout if available + std::string layoutName; + config_.getProperty( "layout", layoutName ); + PageBuilder pb( layoutName, "layout", config_, &fontcache_ ); + Page *page = pb.buildPage( nextPageItem_->name ); + if ( page ) + { + currentPage_->freeGraphicsMemory( ); + pages_.push( currentPage_ ); + currentPage_ = page; + } } config_.setProperty( "currentCollection", nextPageName ); - CollectionInfo *info = getCollection( nextPageName ); + CollectionInfo *info; + if ( menuMode_ ) + info = getMenuCollection( nextPageName ); + else + info = getCollection( nextPageName ); currentPage_->pushCollection(info); @@ -635,6 +634,24 @@ void RetroFE::run( ) } break; + // Launching a menu entry + case RETROFE_HANDLE_MENUENTRY: + + // Empty event queue + SDL_Event e; + while ( SDL_PollEvent( &e ) ); + input_.resetStates( ); + + // Handle menu entry + m.handleEntry( currentPage_->getSelectedItem( ) ); + + // Empty event queue + while ( SDL_PollEvent( &e ) ); + input_.resetStates( ); + + state = RETROFE_IDLE; + break; + // Launching game; start onGameEnter animation case RETROFE_LAUNCH_ENTER: currentPage_->enterGame( ); // Start onGameEnter animation @@ -668,6 +685,8 @@ void RetroFE::run( ) if (currentPage_->getMenuDepth( ) == 1 ) { currentPage_->stop( ); + m.clearPage( ); + menuMode_ = false; } else { @@ -749,6 +768,48 @@ void RetroFE::run( ) } break; + // Start menu mode + case RETROFE_MENUMODE_START_REQUEST: + if ( currentPage_->isIdle( ) ) + { + lastMenuOffsets_[currentPage_->getCollectionName( )] = currentPage_->getScrollOffsetIndex( ); + lastMenuPlaylists_[currentPage_->getCollectionName( )] = currentPage_->getPlaylistName( ); + std::string layoutName; + config_.getProperty( "layout", layoutName ); + PageBuilder pb( layoutName, "layout", config_, &fontcache_, true ); + Page *page = pb.buildPage( ); + if ( page ) + { + currentPage_->freeGraphicsMemory( ); + pages_.push( currentPage_ ); + currentPage_ = page; + menuMode_ = true; + m.setPage( page ); + } + config_.setProperty( "currentCollection", "menu" ); + CollectionInfo *info = getMenuCollection( "menu" ); + currentPage_->pushCollection(info); + currentPage_->onNewItemSelected( ); + currentPage_->reallocateMenuSpritePoints( ); + state = RETROFE_MENUMODE_START_LOAD_ART; + } + break; + + case RETROFE_MENUMODE_START_LOAD_ART: + currentPage_->start(); + state = RETROFE_MENUMODE_START_ENTER; + break; + + case RETROFE_MENUMODE_START_ENTER: + if ( currentPage_->isIdle( ) ) + { + SDL_Event e; + while ( SDL_PollEvent( &e ) ); + input_.resetStates( ); + state = RETROFE_IDLE; + } + break; + // Wait for splash mode animation to finish case RETROFE_NEW: if ( currentPage_->isIdle( ) ) @@ -796,6 +857,10 @@ void RetroFE::run( ) { attract_.update( deltaTime, *currentPage_ ); } + if ( menuMode_ ) + { + attract_.reset( ); + } currentPage_->update( deltaTime ); } @@ -883,7 +948,13 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput( Page *page ) if ( page->isMenuIdle( ) ) { - if (!input_.keystate(UserInput::KeyCodePageUp) && + if ( input_.keystate(UserInput::KeyCodeMenu) && !menuMode_) + { + state = RETROFE_MENUMODE_START_REQUEST; + } + + if ( menuMode_ || ( + !input_.keystate(UserInput::KeyCodePageUp) && !input_.keystate(UserInput::KeyCodePageDown) && !input_.keystate(UserInput::KeyCodeLetterUp) && !input_.keystate(UserInput::KeyCodeLetterDown) && @@ -892,7 +963,8 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput( Page *page ) !input_.keystate(UserInput::KeyCodePrevPlaylist) && !input_.keystate(UserInput::KeyCodeAddPlaylist) && !input_.keystate(UserInput::KeyCodeRemovePlaylist) && - !input_.keystate(UserInput::KeyCodeRandom)) + !input_.keystate(UserInput::KeyCodeRandom) && + !input_.keystate(UserInput::KeyCodeMenu)) ) { keyLastTime_ = 0; keyDelayTime_= 0.3f; @@ -908,6 +980,7 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput( Page *page ) { attract_.reset( ); page->pageScroll(Page::ScrollDirectionBack); + page->onNewItemSelected( ); page->reallocateMenuSpritePoints( ); state = RETROFE_MENUJUMP_REQUEST; } @@ -915,6 +988,7 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput( Page *page ) { attract_.reset( ); page->pageScroll(Page::ScrollDirectionForward); + page->onNewItemSelected( ); page->reallocateMenuSpritePoints( ); state = RETROFE_MENUJUMP_REQUEST; } @@ -922,6 +996,7 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput( Page *page ) { attract_.reset( ); page->letterScroll(Page::ScrollDirectionBack); + page->onNewItemSelected( ); page->reallocateMenuSpritePoints( ); state = RETROFE_MENUJUMP_REQUEST; } @@ -929,6 +1004,7 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput( Page *page ) { attract_.reset( ); page->letterScroll(Page::ScrollDirectionForward); + page->onNewItemSelected( ); page->reallocateMenuSpritePoints( ); state = RETROFE_MENUJUMP_REQUEST; } @@ -966,6 +1042,7 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput( Page *page ) { attract_.reset( ); page->selectRandom( ); + page->onNewItemSelected( ); page->reallocateMenuSpritePoints( ); state = RETROFE_HIGHLIGHT_REQUEST; } @@ -985,7 +1062,14 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput( Page *page ) { if ( nextPageItem_->leaf ) { - state = RETROFE_LAUNCH_ENTER; + if ( menuMode_ ) + { + state = RETROFE_HANDLE_MENUENTRY; + } + else + { + state = RETROFE_LAUNCH_ENTER; + } } else { @@ -1040,7 +1124,7 @@ Page *RetroFE::loadPage( ) config_.getProperty( "layout", layoutName ); - PageBuilder pb(layoutName, "layout", config_, &fontcache_); + PageBuilder pb( layoutName, "layout", config_, &fontcache_ ); Page *page = pb.buildPage( ); if ( !page ) @@ -1058,7 +1142,7 @@ Page *RetroFE::loadSplashPage( ) std::string layoutName; config_.getProperty( "layout", layoutName ); - PageBuilder pb(layoutName, "splash", config_, &fontcache_); + PageBuilder pb( layoutName, "splash", config_, &fontcache_ ); Page * page = pb.buildPage( ); page->start( ); @@ -1178,199 +1262,30 @@ CollectionInfo *RetroFE::getCollection(std::string collectionName) } -std::string RetroFE::get_key( ) -{ - - SDL_Event event; - std::string return_value; - - while ( SDL_PollEvent( &event ) ) - { - switch (event.type) - { - case SDL_JOYDEVICEADDED: - if ( !SDL_JoystickOpen( event.jdevice.which ) ) - Logger::write( Logger::ZONE_INFO, "RetroFE", "Unable to open SDL joystick." ); - else - Logger::write( Logger::ZONE_INFO, "RetroFE", "SDL joystick opened." ); - break; - case SDL_KEYDOWN: - if ( return_value.empty( ) ) - return_value = SDL_GetKeyName( event.key.keysym.sym); - break; - case SDL_JOYBUTTONDOWN: - if ( return_value.empty( ) ) - return_value = "joyButton" + std::to_string( int( event.jbutton.button ) ); - break; - case SDL_JOYAXISMOTION: - if ((event.jaxis.value > 30000 || event.jaxis.value < -30000) && event.jaxis.axis <= 3) - { - if ( event.jaxis.value > 0 ) - { - if ( return_value.empty( ) ) - return_value = "joyAxis" + std::to_string( int( event.jaxis.axis ) ) + "+"; - } - else - { - if ( return_value.empty( ) ) - return_value = "joyAxis" + std::to_string( int( event.jaxis.axis ) ) + "-"; - } - } - break; - case SDL_JOYHATMOTION: - switch( event.jhat.value ) - { - case SDL_HAT_UP: - if ( return_value.empty( ) ) - return_value = "joyHat" + std::to_string( int( event.jhat.hat ) ) + "Up"; - break; - case SDL_HAT_DOWN: - if ( return_value.empty( ) ) - return_value = "joyHat" + std::to_string( int( event.jhat.hat ) ) + "Down"; - break; - case SDL_HAT_LEFT: - if ( return_value.empty( ) ) - return_value = "joyHat" + std::to_string( int( event.jhat.hat ) ) + "Left"; - break; - case SDL_HAT_RIGHT: - if ( return_value.empty( ) ) - return_value = "joyHat" + std::to_string( int( event.jhat.hat ) ) + "Right"; - break; - } - break; - default: - break; - } - } - - return return_value; - -} - - -void RetroFE::print_string( std::string message, TTF_Font *font ) -{ - - SDL_Surface *surfaceMessage; - SDL_Texture *messageTexture; - SDL_Rect messageRect; - SDL_Color color = {255, 255, 255, 0}; - - surfaceMessage = TTF_RenderText_Solid( font, message.c_str( ), color ); - - if ( !surfaceMessage ) - Logger::write( Logger::ZONE_INFO, "RetroFE", "Could not render print_string text." ); - - messageTexture = SDL_CreateTextureFromSurface( SDL::getRenderer( ), surfaceMessage ); - - if ( !messageTexture ) - Logger::write( Logger::ZONE_INFO, "RetroFE", "Could not create print_string texture." ); - - messageRect.w = SDL::getWindowWidth( ) * 8 / 10; - messageRect.h = SDL::getWindowWidth( ) * 8 * surfaceMessage->h / (10 * surfaceMessage->w); - messageRect.x = SDL::getWindowWidth( )/2 - messageRect.w/2; - messageRect.y = SDL::getWindowHeight( )/2 - messageRect.h/2; - - SDL_LockMutex( SDL::getMutex( ) ); - SDL_SetRenderDrawColor( SDL::getRenderer( ), 0, 0, 0, 0xFF ); - SDL_RenderClear( SDL::getRenderer( ) ); - SDL_RenderCopy( SDL::getRenderer( ), messageTexture, NULL, &messageRect); - SDL_RenderPresent( SDL::getRenderer( ) ); - SDL_UnlockMutex( SDL::getMutex( ) ); - - SDL_FreeSurface( surfaceMessage); - SDL_DestroyTexture( messageTexture ); - -} - - -void RetroFE::get_controls_config( ) +// Load a menu +CollectionInfo *RetroFE::getMenuCollection( std::string collectionName ) { - - Logger::write( Logger::ZONE_INFO, "RetroFE", std::to_string( SDL_NumJoysticks( ) ) + " joysticks were found." ); - - TTF_Font *font = TTF_OpenFont( Utils::combinePath( "core", "OpenSans.ttf" ).c_str( ), 48 ); - if ( !font ) - { - Logger::write( Logger::ZONE_INFO, "RetroFE", "SDL could not open font OpenSans.ttf" ); - return; - } - - std::ofstream controls_file; - controls_file.open( "controls.conf" ); - - std::vector> controls; - controls.push_back( std::make_tuple( "up", "go up in the games/collection menu", true ) ); - controls.push_back( std::make_tuple( "down", "go down in the games/collection menu", true ) ); - controls.push_back( std::make_tuple( "left", "go left in the games/collection menu", true ) ); - controls.push_back( std::make_tuple( "right", "go right in the games/collection menu", true ) ); - controls.push_back( std::make_tuple( "pageUp", "go to the next page in your games/collection menu", false ) ); - controls.push_back( std::make_tuple( "pageDown", "go to the previous page in your games/collection menu", false ) ); - controls.push_back( std::make_tuple( "letterUp", "go to the next letter in your games/collection menu", false ) ); - controls.push_back( std::make_tuple( "letterDown", "go to the previous letter in your games/collection menu", false ) ); - controls.push_back( std::make_tuple( "favPlaylist", "switch to your Favorites playlist", false ) ); - controls.push_back( std::make_tuple( "nextPlaylist", "switch to the next playlist", false ) ); - controls.push_back( std::make_tuple( "prevPlaylist", "switch to the previous playlist", false ) ); - controls.push_back( std::make_tuple( "addPlaylist", "add the selected game/collection to your Favorites playlist", false ) ); - controls.push_back( std::make_tuple( "removePlaylist", "remove the selected game/collection from your Favorites playlist", false ) ); - controls.push_back( std::make_tuple( "random", "select a random game/collection from the menu", false ) ); - controls.push_back( std::make_tuple( "select", "enter the collection/start the game", true ) ); - controls.push_back( std::make_tuple( "back", "go back to the previous menu", true ) ); - controls.push_back( std::make_tuple( "quit", "quit RetroFE", true ) ); - - std::string key; - std::vector keys; - - // Clear input queue before we start, but do attach joysticks - get_key( ); - - for ( unsigned int c = 0; c < controls.size( ); c++ ) - { - - keys.clear( ); - int time_out = 0; - while ( true ) - { - key = ""; - while ( key.empty( ) ) - { - if ( !keys.size( ) ) - { - if ( std::get<2>( controls[c] ) ) - print_string( "Please enter your control to " + std::get<1>( controls[c] ) + ". This key is mandatory for proper RetroFE usage.", font ); - else - print_string( "Please enter your control to " + std::get<1>( controls[c] ) + " or wait " + std::to_string( 10 - time_out / 10 ) + " second(s) to not make a selection for this control.", font ); - } - else - { - print_string( "Please enter another control to " + std::get<1>( controls[c] ) + " or wait " + std::to_string( 10 - time_out / 10 ) + " second(s) to continue with the next control.", font ); - } - SDL_Delay( 100 ); - key = get_key( ); - time_out++; - if ( (!std::get<2>( controls[c] ) || keys.size( )) && time_out > 100 ) - break; - } - if ( key.empty( ) || (keys.size( ) && std::find( keys.begin( ), keys.end( ), key ) != keys.end( )) ) - break; - keys.push_back( key ); - time_out = 0; - + std::string menuPath = Utils::combinePath( Configuration::absolutePath, "menu" ); + std::string menuFile = Utils::combinePath( menuPath, collectionName + ".txt" ); + std::vector menuVector; + CollectionInfoBuilder cib( config_, *metadb_ ); + CollectionInfo *collection = new CollectionInfo( collectionName, menuPath, "", "", "" ); + cib.ImportBasicList( collection, menuFile, menuVector ); + for ( std::vector::iterator it = menuVector.begin( ); it != menuVector.end( ); ++it) + { + (*it)->leaf = false; + size_t position = (*it)->name.find( "=" ); + if ( position != std::string::npos ) + { + (*it)->ctrlType = Utils::trimEnds( (*it)->name.substr( position+1, (*it)->name.size( )-1 ) ); + (*it)->name = Utils::trimEnds( (*it)->name.substr( 0, position ) ); + (*it)->title = (*it)->name; + (*it)->fullTitle = (*it)->name; + (*it)->leaf = true; } - if ( keys.size( ) ) - { - controls_file << std::get<0>( controls[c] ) + " = "; - for ( unsigned int i = 0; i < keys.size( ); i++ ) - if ( i == 0 ) - controls_file << keys[i]; - else - controls_file << ", " << keys[i]; - controls_file << std::endl; - } - - } - - controls_file.close( ); - TTF_CloseFont( font ); - + (*it)->collectionInfo = collection; + collection->items.push_back( *it ); + } + collection->playlists["all"] = &collection->items; + return collection; } diff --git a/RetroFE/Source/RetroFE.h b/RetroFE/Source/RetroFE.h index 9c5993c..189110f 100644 --- a/RetroFE/Source/RetroFE.h +++ b/RetroFE/Source/RetroFE.h @@ -76,6 +76,7 @@ private: RETROFE_NEXT_PAGE_MENU_EXIT, RETROFE_NEXT_PAGE_MENU_LOAD_ART, RETROFE_NEXT_PAGE_MENU_ENTER, + RETROFE_HANDLE_MENUENTRY, RETROFE_LAUNCH_ENTER, RETROFE_LAUNCH_REQUEST, RETROFE_LAUNCH_EXIT, @@ -83,6 +84,9 @@ private: RETROFE_BACK_MENU_EXIT, RETROFE_BACK_MENU_LOAD_ART, RETROFE_BACK_MENU_ENTER, + RETROFE_MENUMODE_START_REQUEST, + RETROFE_MENUMODE_START_LOAD_ART, + RETROFE_MENUMODE_START_ENTER, RETROFE_NEW, RETROFE_QUIT_REQUEST, RETROFE_QUIT, @@ -96,6 +100,7 @@ private: RETROFE_STATE processUserInput( Page *page ); void update( float dt, bool scrollActive ); CollectionInfo *getCollection( std::string collectionName ); + CollectionInfo *getMenuCollection( std::string collectionName ); Configuration &config_; DB *db_; @@ -111,12 +116,8 @@ private: Item *nextPageItem_; FontCache fontcache_; AttractMode attract_; + bool menuMode_; std::map lastMenuOffsets_; std::map lastMenuPlaylists_; - - std::string get_key( ); - void print_string( std::string message, TTF_Font *font ); - void get_controls_config( ); - }; diff --git a/RetroFE/Source/Version.cpp b/RetroFE/Source/Version.cpp index 9149898..fc3933e 100644 --- a/RetroFE/Source/Version.cpp +++ b/RetroFE/Source/Version.cpp @@ -21,7 +21,7 @@ std::string retrofe_version_major = "0"; std::string retrofe_version_minor = "8"; -std::string retrofe_version_build = "15b1"; +std::string retrofe_version_build = "15b2"; std::string Version::getString( )