Fixed certain menu related graphics loading issues.

Partly implemented menu structure; getting bugs fixed took priority.
This commit is contained in:
Pieter Hulshoff 2018-04-01 21:42:31 +02:00
parent 65aa165404
commit da45a04ae8
22 changed files with 491 additions and 416 deletions

View File

@ -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"

View File

@ -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<Item *> &list);
private:
Configuration &conf_;
MetadataDatabase &metaDB_;
bool ImportBasicList(CollectionInfo *info, std::string file, std::map<std::string, Item *> &list);
bool ImportBasicList(CollectionInfo *info, std::string file, std::vector<Item *> &list);
bool ImportDirectory(CollectionInfo *info, std::string mergedCollectionName);
void ImportRomDirectory(std::string path, CollectionInfo *info, std::map<std::string, Item *> includeFilter, std::map<std::string, Item *> excludeFilter, bool romHierarchy);
};

View File

@ -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;
}

View File

@ -45,6 +45,7 @@ public:
KeyCodeNextPlaylist,
KeyCodePrevPlaylist,
KeyCodeRandom,
KeyCodeMenu,
KeyCodeAddPlaylist,
KeyCodeRemovePlaylist,
KeyCodeAdminMode,

View File

@ -50,6 +50,7 @@ public:
std::string collectionName;
void setMenuScrollReload(bool menuScrollReload);
bool getMenuScrollReload();
virtual void setInput(std::string text) {};
protected:
Page &page;

View File

@ -28,12 +28,13 @@
#include <vector>
#include <iostream>
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)

View File

@ -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_;

View File

@ -28,11 +28,12 @@
#include <algorithm>
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)

View File

@ -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_;

View File

@ -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 &copy )
: 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<std::string> 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_ );
}

View File

@ -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<Component *> *spriteList_;
std::vector<ViewInfo *> *scrollPoints_;
std::vector<AnimationEvents *> *tweenPoints_;

View File

@ -14,64 +14,72 @@
* along with RetroFE. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Text.h"
#include "../../Utility/Log.h"
#include "../../SDL.h"
#include "../Font.h"
#include <sstream>
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<int>(xOrigin);
rect.x = static_cast<int>( 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<float>(charRect.h * scale);
float w = static_cast<float>(charRect.w * scale);
rect.h = static_cast<int>(h);
rect.w = static_cast<int>(w);
rect.y = static_cast<int>(yOrigin);
float h = static_cast<float>( charRect.h * scale );
float w = static_cast<float>( charRect.w * scale );
rect.h = static_cast<int>( h );
rect.w = static_cast<int>( w );
rect.y = static_cast<int>( yOrigin );
if(glyph.minX < 0)
{
rect.x += static_cast<int>((float)(glyph.minX) * scale);
rect.x += static_cast<int>( (float)(glyph.minX) * scale );
}
if(font->getAscent() < glyph.maxY)
if ( font->getAscent( ) < glyph.maxY )
{
rect.y += static_cast<int>((font->getAscent() - glyph.maxY)*scale);
rect.y += static_cast<int>( (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<int>(glyph.advance * scale);
rect.x += static_cast<int>( glyph.advance * scale );
}
}
}

View File

@ -15,29 +15,34 @@
*/
#pragma once
#include "Component.h"
#include "../Page.h"
#include <SDL2/SDL.h>
#include <vector>
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_;
};

View File

@ -483,6 +483,24 @@ void Page::highlightExit()
}
void Page::menuAction( std::string action )
{
for(std::vector<Component *>::iterator it = LayerComponents.begin(); it != LayerComponents.end(); ++it)
{
(*it)->triggerEvent( action );
}
}
void Page::menuInput( std::string text )
{
for(std::vector<Component *>::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<ScrollingList *>::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<ScrollingList *>::iterator it2 = menus_[std::distance(menus_.begin(), it)].begin(); it2 != menus_[std::distance(menus_.begin(), it)].end(); it2++)
{
ScrollingList *menu = *it2;
menu->allocateGraphicsMemory();
}
}
}

View File

@ -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();

View File

@ -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)
{

View File

@ -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);

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include "Menu.h"
#include "../Collection/Item.h"
#include <iostream>
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;
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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_;
};

View File

@ -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 <dirent.h>
#include <fstream>
#include <sstream>
#include <string>
#include <tuple>
#include <vector>
#include <SDL2/SDL_ttf.h>
@ -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<float>( 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<std::tuple<std::string, std::string, bool>> 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<std::string> 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<Item *> menuVector;
CollectionInfoBuilder cib( config_, *metadb_ );
CollectionInfo *collection = new CollectionInfo( collectionName, menuPath, "", "", "" );
cib.ImportBasicList( collection, menuFile, menuVector );
for ( std::vector<Item *>::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;
}

View File

@ -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<std::string, unsigned int> lastMenuOffsets_;
std::map<std::string, std::string> lastMenuPlaylists_;
std::string get_key( );
void print_string( std::string message, TTF_Font *font );
void get_controls_config( );
};

View File

@ -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( )