diff --git a/Package/Environment/Common/controls.conf b/Package/Environment/Common/controls.conf index b24885b..9c5e503 100644 --- a/Package/Environment/Common/controls.conf +++ b/Package/Environment/Common/controls.conf @@ -1,72 +1,24 @@ -up = Up -down = Down -left = Left -right = Right +up = Keypad 8,Up +down = Keypad 2,Down +left = Keypad 4,Left,joy0Button7 +right = Keypad 6,Right,joy0Button5 pageUp = A pageDown = B letterUp = N letterDown = M -nextPlaylist = P +favPlaylist = F +nextPlaylist = F2 +prevPlaylist = F1 addPlaylist = I removePlaylist = O random = R -select = Space -back = Escape +select = 1,Return,joy0Button3 +back = 2,Escape,joy0Button0 quit = Q -# Define controller analogue dead zone. Default (when not configured) is 3%. -# deadZone = 3 -############################################################################## -# MOUSE CODES -###################### ###################################################### -# Code # Description -###################### ###################################################### -# mouseButtonLeft Left mouse click -# mouseButtonMiddle Middle mouse click -# mouseButtonRight Right mouse click -# mouseButtonX1 ? -# mouseButtonX2 ? +# See below for a list of key codes that can be used for configuring the controls: -############################################################################## -# JOYSTICK/GAMEPAD CODES -###################### ###################################################### -# Code # Description -###################### ###################################################### -# X is joypad number (0 is first joystick/gamepad) -# joyXHatYLeftUp Y=hat number (0 is the first dpad) (example joy0Hat0Up) -# joyXHatYLeft -# joyXHatYLeftDown -# joyXHatYUp -# joyXHatYDown -# joyXHatYRightUp -# joyXHatYRight -# joyXHatYRightDown -# joyXButtonY Y is button number (0 is first button) -# Example: joy1button7 -> second joystick, 8th button -# Open up the gamepad control panel in windows or use -# "jstest" in linux -# -# joyXAxis0+ First POV stick, first axis positive direction -# (axis 0 is usually x) -# joyXAxis0- First POV stick, first axis positive direction -# (axis 0 is usually x) -# joyXAxis1+ First POV stick, second axis positive direction -# (axis 0 is usually y) -#joyXAxis1- First POV stick, second axis positive direction -# (axis 0 is usually y) -# -# joyXAxis2+ Second POV stick, first axis positive direction -# (axis 2 is usually x) -# joyXAxis2- Second POV stick, first axis positive direction -# (axis 2 is usually x) -# joyXAxis3+ Second POV stick, second axis positive direction -# (axis 3 is usually y) -# joyXAxis3- Second POV stick, second axis positive direction -# (axis 3 is usually y) - -############################################################################## -# KEYBOARD CODES ###################### ###################################################### # Code # Description ###################### ###################################################### diff --git a/Package/Environment/Common/settings.conf b/Package/Environment/Common/settings.conf index 1ba7994..82df411 100644 --- a/Package/Environment/Common/settings.conf +++ b/Package/Environment/Common/settings.conf @@ -15,9 +15,13 @@ fullscreen = no horizontal = stretch # or enter in the screen pixel width (i.e 1024) vertical = stretch # or enter in the screen pixel width (i.e 768) layout = Aeon Nox -hideMouse = yes -showParenthesis = yes -showSquareBrackets = yes + +# Hide the mouse +hideMouse = yes + +# Hide () and [] from game titles +showParenthesis = no +showSquareBrackets = no # specify the name of the first collection to load on start firstCollection = Main @@ -25,12 +29,15 @@ firstCollection = Main # specify whether RetroFE should switch to Favorites list if it exists. autoFavorites = true +# specify whether RetroFE should remember the last selected game +rememberMenu = true + ####################################### # Video playback settings ####################################### - + # set to "no" for very old/slow systems -videoEnable = yes +videoEnable = yes # Number of times to loop video playback (enter 0 to continuously loop) videoLoop = 0 @@ -38,17 +45,27 @@ videoLoop = 0 ####################################### # General ####################################### -# exit the frontend when the back button is pressed on the first page -exitOnFirstPageBack = yes +# specify whether RetroFE should close when pressing back on the main menu +exitOnFirstPageBack = no # enter 0 attract mode, otherwise enter the number of seconds to wait before enabling attract mode -attractModeTime = 45 +attractModeTime = 45 -# remember the last highlighted menu when re-entering a menu +# specify whether RetroFE should remember the last highlighted menu when re-entering a menu rememberMenu = yes -# Clear the input on entering/exiting a collection -collectionInputClear = false +# specify whether RetroFE should clear the input queue on entering/exiting a collection +collectionInputClear = true + +# specify whether RetroFE should minimize when running in full-screen mode +minimize_on_focus_loss = no + +# specify whether RetroFE should unload SDL when running a program/game +# This is needed to prevent emulators from launching behind the front-end, e.g. on RetroPie. +# Set to false or comment out to prevent briefly seeing your Windows environment if you don't +# need this feature. +unloadSDL = true + ####################################### # Base folders of media and ROM files diff --git a/RetroFE/Source/Execute/Launcher.cpp b/RetroFE/Source/Execute/Launcher.cpp index 3dafc1a..b215687 100644 --- a/RetroFE/Source/Execute/Launcher.cpp +++ b/RetroFE/Source/Execute/Launcher.cpp @@ -30,9 +30,8 @@ #include #endif -Launcher::Launcher(RetroFE &p, Configuration &c) +Launcher::Launcher(Configuration &c) : config_(c) - , retrofe_(p) { } @@ -153,9 +152,6 @@ bool Launcher::execute(std::string executable, std::string args, std::string cur Logger::write(Logger::ZONE_INFO, "Launcher", "Attempting to launch: " + executionString); Logger::write(Logger::ZONE_INFO, "Launcher", " from within folder: " + currentDirectory); - //todo: use delegation instead of depending on knowing the RetroFE class (tie to an interface) - retrofe_.launchEnter(); - #ifdef WIN32 STARTUPINFO startupInfo; PROCESS_INFORMATION processInfo; @@ -205,7 +201,6 @@ bool Launcher::execute(std::string executable, std::string args, std::string cur } Logger::write(Logger::ZONE_INFO, "Launcher", "Completed"); - retrofe_.launchExit(); return retVal; } diff --git a/RetroFE/Source/Execute/Launcher.h b/RetroFE/Source/Execute/Launcher.h index 6551c79..8ae3b37 100644 --- a/RetroFE/Source/Execute/Launcher.h +++ b/RetroFE/Source/Execute/Launcher.h @@ -24,7 +24,7 @@ class RetroFE; class Launcher { public: - Launcher(RetroFE &p, Configuration &c); + Launcher(Configuration &c); bool run(std::string collection, Item *collectionItem); private: @@ -48,5 +48,4 @@ private: std::string itemCollectionName); Configuration &config_; - RetroFE &retrofe_; }; diff --git a/RetroFE/Source/Graphics/Component/Component.h b/RetroFE/Source/Graphics/Component/Component.h index a2d8c79..6dd45ed 100644 --- a/RetroFE/Source/Graphics/Component/Component.h +++ b/RetroFE/Source/Graphics/Component/Component.h @@ -31,8 +31,6 @@ public: virtual ~Component(); virtual void freeGraphicsMemory(); virtual void allocateGraphicsMemory(); - virtual void launchEnter() {} - virtual void launchExit() {} void triggerEvent(std::string event, int menuIndex = -1); void setPlaylist(std::string name ); void setNewItemSelected(); diff --git a/RetroFE/Source/Graphics/Component/Image.cpp b/RetroFE/Source/Graphics/Component/Image.cpp index b077e90..c145a12 100644 --- a/RetroFE/Source/Graphics/Component/Image.cpp +++ b/RetroFE/Source/Graphics/Component/Image.cpp @@ -53,8 +53,6 @@ void Image::allocateGraphicsMemory() int width; int height; - Component::allocateGraphicsMemory(); - if(!texture_) { SDL_LockMutex(SDL::getMutex()); @@ -74,8 +72,12 @@ void Image::allocateGraphicsMemory() SDL_UnlockMutex(SDL::getMutex()); } + + Component::allocateGraphicsMemory(); + } + void Image::draw() { Component::draw(); diff --git a/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp b/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp index e7bb8f0..1c8cbd8 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp +++ b/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp @@ -99,21 +99,6 @@ void ReloadableMedia::allocateGraphicsMemory() Component::allocateGraphicsMemory(); } -void ReloadableMedia::launchEnter() -{ - if(loadedComponent_) - { - loadedComponent_->launchEnter(); - } -} - -void ReloadableMedia::launchExit() -{ - if(loadedComponent_) - { - loadedComponent_->launchExit(); - } -} void ReloadableMedia::freeGraphicsMemory() { diff --git a/RetroFE/Source/Graphics/Component/ReloadableMedia.h b/RetroFE/Source/Graphics/Component/ReloadableMedia.h index 47bd789..ac4a84d 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableMedia.h +++ b/RetroFE/Source/Graphics/Component/ReloadableMedia.h @@ -33,8 +33,6 @@ public: void draw(); void freeGraphicsMemory(); void allocateGraphicsMemory(); - void launchEnter(); - void launchExit(); Component *findComponent(std::string collection, std::string type, std::string basename, bool systemMode); void enableTextFallback_(bool value); diff --git a/RetroFE/Source/Graphics/Component/ReloadableScrollingText.cpp b/RetroFE/Source/Graphics/Component/ReloadableScrollingText.cpp index 6978b4d..d3f67ea 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableScrollingText.cpp +++ b/RetroFE/Source/Graphics/Component/ReloadableScrollingText.cpp @@ -98,8 +98,10 @@ void ReloadableScrollingText::update(float dt) } -void ReloadableScrollingText::launchExit( ) +void ReloadableScrollingText::allocateGraphicsMemory( ) { + Component::allocateGraphicsMemory( ); + fontInst_->initialize( ); reloadTexture( ); } @@ -107,6 +109,7 @@ void ReloadableScrollingText::launchExit( ) void ReloadableScrollingText::freeGraphicsMemory( ) { Component::freeGraphicsMemory( ); + fontInst_->deInitialize( ); text_.clear( ); } diff --git a/RetroFE/Source/Graphics/Component/ReloadableScrollingText.h b/RetroFE/Source/Graphics/Component/ReloadableScrollingText.h index a827980..cbaf5c6 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableScrollingText.h +++ b/RetroFE/Source/Graphics/Component/ReloadableScrollingText.h @@ -28,8 +28,8 @@ public: virtual ~ReloadableScrollingText( ); void update(float dt); void draw( ); + void allocateGraphicsMemory( ); void freeGraphicsMemory( ); - void launchExit(); private: void reloadTexture( ); diff --git a/RetroFE/Source/Graphics/Component/ReloadableText.cpp b/RetroFE/Source/Graphics/Component/ReloadableText.cpp index 75703f3..bcb2ca0 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableText.cpp +++ b/RetroFE/Source/Graphics/Component/ReloadableText.cpp @@ -71,17 +71,12 @@ void ReloadableText::allocateGraphicsMemory() { ReloadTexture(); + fontInst_->initialize(); + // NOTICE! needs to be done last to prevent flags from being missed Component::allocateGraphicsMemory(); } -void ReloadableText::launchEnter() -{ -} - -void ReloadableText::launchExit() -{ -} void ReloadableText::freeGraphicsMemory() { @@ -92,7 +87,11 @@ void ReloadableText::freeGraphicsMemory() delete imageInst_; imageInst_ = NULL; } + + fontInst_->deInitialize(); } + + void ReloadableText::ReloadTexture() { if (imageInst_ != NULL) diff --git a/RetroFE/Source/Graphics/Component/ReloadableText.h b/RetroFE/Source/Graphics/Component/ReloadableText.h index 9e81225..b5735fa 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableText.h +++ b/RetroFE/Source/Graphics/Component/ReloadableText.h @@ -31,8 +31,6 @@ public: void draw(); void freeGraphicsMemory(); void allocateGraphicsMemory(); - void launchEnter(); - void launchExit(); private: void ReloadTexture(); diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index 86f4759..8ed3545 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -140,8 +140,6 @@ void ScrollingList::deallocateSpritePoints() { deallocateTexture(i); } - - componentIndex_ = 0; } void ScrollingList::allocateSpritePoints() @@ -152,26 +150,41 @@ void ScrollingList::allocateSpritePoints() for(unsigned int i = 0; i < scrollPoints_->size(); ++i) { - componentIndex_ = 0; - unsigned int index = loopIncrement(itemIndex_, i, items_->size()); + unsigned int index = loopIncrement(itemIndex_, i, items_->size()); + unsigned int oindex = loopIncrement(componentIndex_, i, components_.size()); Item *item = items_->at(index); - allocateTexture(i, item); - Component *c = components_.at(i); + Component *o = components_.at(oindex); - ViewInfo *current = scrollPoints_->at(i); + allocateTexture(oindex, item); - unsigned int nextI = loopIncrement(i, 1, scrollPoints_->size()); + Component *c = components_.at(oindex); + + ViewInfo *current = scrollPoints_->at(oindex); + + unsigned int nextI = loopIncrement(oindex, 1, scrollPoints_->size()); ViewInfo *next = scrollPoints_->at(nextI); resetTweens(c, tweenPoints_->at(i), current, next, 0); + + if(o) + { + c->baseViewInfo = o->baseViewInfo; + delete o; + } + } } void ScrollingList::destroyItems() { - deallocateSpritePoints(); -//todo: who deletes the CollectionInfo? + for(unsigned int i = 0; i < components_.size(); ++i) + { + delete components_.at(i); + components_.at(i) = NULL; + } + + componentIndex_ = 0; } @@ -307,6 +320,15 @@ void ScrollingList::letterChange(bool increment) } +void ScrollingList::allocateGraphicsMemory() +{ + Component::allocateGraphicsMemory(); + scrollPeriod_ = startScrollTime_; + + allocateSpritePoints(); +} + + void ScrollingList::freeGraphicsMemory() { Component::freeGraphicsMemory(); @@ -612,8 +634,7 @@ void ScrollingList::deallocateTexture(unsigned int index) if(s) { - delete s; - components_.at(index) = NULL; + s->freeGraphicsMemory(); } } @@ -704,7 +725,8 @@ void ScrollingList::scroll(bool forward) ViewInfo *currentvi = scrollPoints_->at(i); ViewInfo *nextvi = scrollPoints_->at(nextI); - resetTweens(c, tweenPoints_->at(nextI), currentvi, nextvi, scrollPeriod_); + resetTweens + (c, tweenPoints_->at(nextI), currentvi, nextvi, scrollPeriod_); c->baseViewInfo.font = nextvi->font; // Use the font settings of the next index c->triggerEvent( "menuScroll" ); } diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.h b/RetroFE/Source/Graphics/Component/ScrollingList.h index 941f509..5d88d9c 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.h +++ b/RetroFE/Source/Graphics/Component/ScrollingList.h @@ -74,6 +74,7 @@ public: void setSelectedIndex(int selectedIndex); Item *getItemByOffset(int offset); Item *getSelectedItem(); + void allocateGraphicsMemory(); void freeGraphicsMemory(); void update(float dt); void draw(); diff --git a/RetroFE/Source/Graphics/Component/Text.cpp b/RetroFE/Source/Graphics/Component/Text.cpp index 35704ec..8bcf907 100644 --- a/RetroFE/Source/Graphics/Component/Text.cpp +++ b/RetroFE/Source/Graphics/Component/Text.cpp @@ -38,12 +38,14 @@ Text::~Text() void Text::freeGraphicsMemory() { Component::freeGraphicsMemory(); + fontInst_->deInitialize(); } void Text::allocateGraphicsMemory() { //todo: make the font blend color a parameter that is passed in Component::allocateGraphicsMemory(); + fontInst_->initialize(); } void Text::setText(std::string text) diff --git a/RetroFE/Source/Graphics/Component/Video.cpp b/RetroFE/Source/Graphics/Component/Video.cpp index d48b7e4..7cbee4d 100644 --- a/RetroFE/Source/Graphics/Component/Video.cpp +++ b/RetroFE/Source/Graphics/Component/Video.cpp @@ -39,16 +39,6 @@ Video::Video(std::string file, std::string altFile, int numLoops, Page &p, float allocateGraphicsMemory( ); } -void Video::launchEnter() -{ - freeGraphicsMemory(); -} - -void Video::launchExit() -{ - allocateGraphicsMemory(); -} - Video::~Video( ) { if (video_ != NULL) diff --git a/RetroFE/Source/Graphics/Component/Video.h b/RetroFE/Source/Graphics/Component/Video.h index 49c2644..ff81822 100644 --- a/RetroFE/Source/Graphics/Component/Video.h +++ b/RetroFE/Source/Graphics/Component/Video.h @@ -28,8 +28,6 @@ public: void update(float dt); void freeGraphicsMemory( ); void allocateGraphicsMemory( ); - void launchEnter(); - void launchExit(); void draw( ); virtual bool isPlaying( ); diff --git a/RetroFE/Source/Graphics/Component/VideoComponent.cpp b/RetroFE/Source/Graphics/Component/VideoComponent.cpp index 1e5bfa9..da80846 100644 --- a/RetroFE/Source/Graphics/Component/VideoComponent.cpp +++ b/RetroFE/Source/Graphics/Component/VideoComponent.cpp @@ -82,14 +82,6 @@ void VideoComponent::freeGraphicsMemory() Component::freeGraphicsMemory(); } -void VideoComponent::launchEnter() -{ - freeGraphicsMemory(); -} -void VideoComponent::launchExit() -{ - allocateGraphicsMemory(); -} void VideoComponent::draw() { diff --git a/RetroFE/Source/Graphics/Component/VideoComponent.h b/RetroFE/Source/Graphics/Component/VideoComponent.h index 22bce43..7b486fb 100644 --- a/RetroFE/Source/Graphics/Component/VideoComponent.h +++ b/RetroFE/Source/Graphics/Component/VideoComponent.h @@ -31,8 +31,6 @@ public: void draw(); void freeGraphicsMemory(); void allocateGraphicsMemory(); - void launchEnter(); - void launchExit(); virtual bool isPlaying(); private: diff --git a/RetroFE/Source/Graphics/Font.cpp b/RetroFE/Source/Graphics/Font.cpp index 3d1e70b..fbf17bc 100644 --- a/RetroFE/Source/Graphics/Font.cpp +++ b/RetroFE/Source/Graphics/Font.cpp @@ -21,8 +21,11 @@ #include #include -Font::Font() +Font::Font(std::string fontPath, int fontSize, SDL_Color color) : texture(NULL) + , fontPath_(fontPath) + , fontSize_(fontSize) + , color_(color) { } @@ -60,9 +63,9 @@ bool Font::getRect(unsigned int charCode, GlyphInfo &glyph) return false; } -bool Font::initialize(std::string fontPath, int fontSize, SDL_Color color) +bool Font::initialize() { - TTF_Font *font = TTF_OpenFont(fontPath.c_str(), fontSize); + TTF_Font *font = TTF_OpenFont(fontPath_.c_str(), fontSize_); if (!font) { @@ -84,8 +87,8 @@ bool Font::initialize(std::string fontPath, int fontSize, SDL_Color color) GlyphInfoBuild *info = new GlyphInfoBuild; memset(info, 0, sizeof(GlyphInfoBuild)); - color.a = 255; - info->surface = TTF_RenderGlyph_Blended(font, i, color); + color_.a = 255; + info->surface = TTF_RenderGlyph_Blended(font, i, color_); TTF_GlyphMetrics(font, i, &info->glyph.minX, &info->glyph.maxX, &info->glyph.minY, &info->glyph.maxY, diff --git a/RetroFE/Source/Graphics/Font.h b/RetroFE/Source/Graphics/Font.h index d150336..65d50f7 100644 --- a/RetroFE/Source/Graphics/Font.h +++ b/RetroFE/Source/Graphics/Font.h @@ -32,9 +32,9 @@ public: SDL_Rect rect; }; - Font(); + Font(std::string fontPath, int fontSize, SDL_Color color); virtual ~Font(); - bool initialize(std::string fontPath, int fontSize, SDL_Color color); + bool initialize(); void deInitialize(); SDL_Texture *getTexture(); bool getRect(unsigned int charCode, GlyphInfo &glyph); @@ -52,4 +52,7 @@ private: int height; int ascent; std::map atlas; + std::string fontPath_; + int fontSize_; + SDL_Color color_; }; diff --git a/RetroFE/Source/Graphics/FontCache.cpp b/RetroFE/Source/Graphics/FontCache.cpp index edc2acc..ae9432d 100644 --- a/RetroFE/Source/Graphics/FontCache.cpp +++ b/RetroFE/Source/Graphics/FontCache.cpp @@ -81,8 +81,8 @@ bool FontCache::loadFont(std::string fontPath, int fontSize, SDL_Color color) if(it == fontFaceMap_.end()) { - Font *f = new Font(); - f->initialize(fontPath, fontSize, color); + Font *f = new Font(fontPath, fontSize, color); + f->initialize(); fontFaceMap_[key] = f; } diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index ac7adb8..aadebee 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -48,7 +48,7 @@ Page::~Page() } -void Page::DeInitialize() +void Page::deInitialize() { MenuVector_T::iterator it = menus_.begin(); while(it != menus_.end()) @@ -418,7 +418,7 @@ void Page::highlightEnter() for(std::vector::iterator it2 = menus_[std::distance(menus_.begin(), it)].begin(); it2 != menus_[std::distance(menus_.begin(), it)].end(); it2++) { ScrollingList *menu = *it2; - if(menuDepth_-1 == distance(menus_.begin(), it)) + if(menuDepth_-1 == static_cast(distance(menus_.begin(), it))) { // Also trigger animations for index i for active menu menu->triggerEvent( "highlightEnter", MENU_INDEX_HIGH + menuDepth_ - 1 ); @@ -449,7 +449,7 @@ void Page::highlightExit() for(std::vector::iterator it2 = menus_[std::distance(menus_.begin(), it)].begin(); it2 != menus_[std::distance(menus_.begin(), it)].end(); it2++) { ScrollingList *menu = *it2; - if(menuDepth_-1 == distance(menus_.begin(), it)) + if(menuDepth_-1 == static_cast(distance(menus_.begin(), it))) { // Also trigger animations for index i for active menu menu->triggerEvent( "highlightExit", MENU_INDEX_HIGH + menuDepth_ - 1 ); @@ -657,7 +657,7 @@ void Page::enterMenu() for(std::vector::iterator it2 = menus_[std::distance(menus_.begin(), it)].begin(); it2 != menus_[std::distance(menus_.begin(), it)].end(); it2++) { ScrollingList *menu = *it2; - if(menuDepth_-1 == distance(menus_.begin(), it)) + if(menuDepth_-1 == static_cast(distance(menus_.begin(), it))) { // Also trigger animations for index i for active menu menu->triggerEvent( "menuEnter", MENU_INDEX_HIGH + menuDepth_ - 1 ); @@ -688,7 +688,7 @@ void Page::exitMenu() for(std::vector::iterator it2 = menus_[std::distance(menus_.begin(), it)].begin(); it2 != menus_[std::distance(menus_.begin(), it)].end(); it2++) { ScrollingList *menu = *it2; - if(menuDepth_-1 == distance(menus_.begin(), it)) + if(menuDepth_-1 == static_cast(distance(menus_.begin(), it))) { // Also trigger animations for index i for active menu menu->triggerEvent( "menuExit", MENU_INDEX_HIGH + menuDepth_ - 1 ); @@ -719,7 +719,7 @@ void Page::enterGame() for(std::vector::iterator it2 = menus_[std::distance(menus_.begin(), it)].begin(); it2 != menus_[std::distance(menus_.begin(), it)].end(); it2++) { ScrollingList *menu = *it2; - if(menuDepth_-1 == distance(menus_.begin(), it)) + if(menuDepth_-1 == static_cast(distance(menus_.begin(), it))) { // Also trigger animations for index i for active menu menu->triggerEvent( "gameEnter", MENU_INDEX_HIGH + menuDepth_ - 1 ); @@ -750,7 +750,7 @@ void Page::exitGame() for(std::vector::iterator it2 = menus_[std::distance(menus_.begin(), it)].begin(); it2 != menus_[std::distance(menus_.begin(), it)].end(); it2++) { ScrollingList *menu = *it2; - if(menuDepth_-1 == distance(menus_.begin(), it)) + if(menuDepth_-1 == static_cast(distance(menus_.begin(), it))) { // Also trigger animations for index i for active menu menu->triggerEvent( "gameExit", MENU_INDEX_HIGH + menuDepth_ - 1 ); @@ -1051,17 +1051,6 @@ void Page::allocateGraphicsMemory() void Page::launchEnter() { - for(std::vector::iterator it = activeMenu_.begin(); it != activeMenu_.end(); it++) - { - ScrollingList *menu = *it; - if(menu) menu->launchEnter(); - } - - for(std::vector::iterator it = LayerComponents.begin(); it != LayerComponents.end(); ++it) - { - (*it)->launchEnter(); - } - if(selectSoundChunk_) { selectSoundChunk_->play(); @@ -1069,21 +1058,6 @@ void Page::launchEnter() } -void Page::launchExit() -{ - for(std::vector::iterator it = activeMenu_.begin(); it != activeMenu_.end(); it++) - { - ScrollingList *menu = *it; - if(menu) menu->launchExit(); - } - - for(std::vector::iterator it = LayerComponents.begin(); it != LayerComponents.end(); ++it) - { - (*it)->launchExit(); - } -} - - void Page::reallocateMenuSpritePoints() { for(std::vector::iterator it = activeMenu_.begin(); it != activeMenu_.end(); it++) diff --git a/RetroFE/Source/Graphics/Page.h b/RetroFE/Source/Graphics/Page.h index a68248f..f1f4346 100644 --- a/RetroFE/Source/Graphics/Page.h +++ b/RetroFE/Source/Graphics/Page.h @@ -42,7 +42,7 @@ public: Page(Configuration &c); virtual ~Page(); - void DeInitialize(); + void deInitialize(); virtual void onNewItemSelected(); void highlightLoadArt(); bool pushCollection(CollectionInfo *collection); @@ -88,7 +88,6 @@ public: void freeGraphicsMemory(); void allocateGraphicsMemory(); void launchEnter(); - void launchExit(); std::string getCollectionName(); void setMinShowTime(float value); float getMinShowTime(); diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index 9dca19e..cecdbe7 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -14,6 +14,7 @@ * along with RetroFE. If not, see . */ + #include "RetroFE.h" #include "Collection/CollectionInfoBuilder.h" #include "Collection/CollectionInfo.h" @@ -48,7 +49,8 @@ #include #endif -RetroFE::RetroFE(Configuration &c) + +RetroFE::RetroFE( Configuration &c ) : initialized(false) , initializeError(false) , initializeThread(NULL) @@ -65,169 +67,214 @@ RetroFE::RetroFE(Configuration &c) { } -RetroFE::~RetroFE() + +RetroFE::~RetroFE( ) { - deInitialize(); + deInitialize( ); } -void RetroFE::render() -{ - SDL_LockMutex(SDL::getMutex()); - SDL_SetRenderDrawColor(SDL::getRenderer(), 0x0, 0x0, 0x00, 0xFF); - SDL_RenderClear(SDL::getRenderer()); - if(currentPage_) +// Render the current page to the screen +void RetroFE::render( ) +{ + + SDL_LockMutex( SDL::getMutex( ) ); + SDL_SetRenderDrawColor( SDL::getRenderer( ), 0x0, 0x0, 0x00, 0xFF ); + SDL_RenderClear( SDL::getRenderer( ) ); + + if ( currentPage_ ) { - currentPage_->draw(); + currentPage_->draw( ); } - SDL_RenderPresent(SDL::getRenderer()); - SDL_UnlockMutex(SDL::getMutex()); + SDL_RenderPresent( SDL::getRenderer( ) ); + SDL_UnlockMutex( SDL::getMutex( ) ); + } -int RetroFE::initialize(void *context) + +// Initialize the configuration and database +int RetroFE::initialize( void *context ) { + RetroFE *instance = static_cast(context); - Logger::write(Logger::ZONE_INFO, "RetroFE", "Initializing"); + Logger::write( Logger::ZONE_INFO, "RetroFE", "Initializing" ); - if(!instance->input_.initialize()) + if ( !instance->input_.initialize( ) ) { - Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not initialize user controls"); + Logger::write( Logger::ZONE_ERROR, "RetroFE", "Could not initialize user controls" ); instance->initializeError = true; return -1; } - instance->db_ = new DB(Utils::combinePath(Configuration::absolutePath, "meta.db")); + instance->db_ = new DB( Utils::combinePath( Configuration::absolutePath, "meta.db" ) ); - if(!instance->db_->initialize()) + if ( !instance->db_->initialize( ) ) { - Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not initialize database"); + Logger::write( Logger::ZONE_ERROR, "RetroFE", "Could not initialize database" ); instance->initializeError = true; return -1; } - instance->metadb_ = new MetadataDatabase(*(instance->db_), instance->config_); + instance->metadb_ = new MetadataDatabase( *(instance->db_), instance->config_ ); - if(!instance->metadb_->initialize()) + if ( !instance->metadb_->initialize( ) ) { - Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not initialize meta database"); + Logger::write( Logger::ZONE_ERROR, "RetroFE", "Could not initialize meta database" ); instance->initializeError = true; return -1; } instance->initialized = true; return 0; + } -void RetroFE::launchEnter() -{ - if(currentPage_) - { - currentPage_->launchEnter(); - } - SDL_SetWindowGrab(SDL::getWindow(), SDL_FALSE); +// Launch a game/program +void RetroFE::launchEnter( ) +{ + + // Play launch sound + currentPage_->launchEnter( ); + + // Free the textures, and optionally take down SDL + freeGraphicsMemory( ); + } -void RetroFE::launchExit() + +// Return from the launch of a game/program +void RetroFE::launchExit( ) { - SDL_RestoreWindow(SDL::getWindow()); - SDL_RaiseWindow(SDL::getWindow()); - SDL_SetWindowGrab(SDL::getWindow(), SDL_TRUE); + + // Optionally set up SDL, and load the textures + allocateGraphicsMemory( ); + + // Restore the SDL settings + SDL_RestoreWindow( SDL::getWindow( ) ); + SDL_RaiseWindow( SDL::getWindow( ) ); + SDL_SetWindowGrab( SDL::getWindow( ), SDL_TRUE ); // Empty event queue SDL_Event e; - while (SDL_PollEvent(&e)); + while ( SDL_PollEvent( &e ) ); + input_.resetStates( ); + attract_.reset( ); - input_.resetStates(); - attract_.reset(); - - currentTime_ = static_cast(SDL_GetTicks()) / 1000; - if(currentPage_) - { - currentPage_->launchExit(); - } + // Restore time settings + currentTime_ = static_cast( SDL_GetTicks( ) ) / 1000; lastLaunchReturnTime_ = currentTime_; } -void RetroFE::freeGraphicsMemory() -{ - if(currentPage_) - { - currentPage_->freeGraphicsMemory(); - } - fontcache_.deInitialize(); - SDL::deInitialize(); +// Free the textures, and optionall take down SDL +void RetroFE::freeGraphicsMemory( ) +{ + + // Free textures + if ( currentPage_ ) + { + currentPage_->freeGraphicsMemory( ); + } + + // Close down SDL + bool unloadSDL = false; + config_.getProperty( "unloadSDL", unloadSDL ); + if ( unloadSDL ) + { + SDL::deInitialize( ); + } + } -void RetroFE::allocateGraphicsMemory() + +// Optionally set up SDL, and load the textures +void RetroFE::allocateGraphicsMemory( ) { - SDL::initialize(config_); - fontcache_.initialize(); - - if(currentPage_) + // Reopen SDL + bool unloadSDL = false; + config_.getProperty( "unloadSDL", unloadSDL ); + if ( unloadSDL ) { - currentPage_->allocateGraphicsMemory(); + SDL::initialize( config_ ); } + + // Allocate textures + if ( currentPage_ ) + { + currentPage_->allocateGraphicsMemory( ); + } + } -bool RetroFE::deInitialize() + +// Deinitialize RetroFE +bool RetroFE::deInitialize( ) { + bool retVal = true; - freeGraphicsMemory(); - if(currentPage_) + // Free textures + freeGraphicsMemory( ); + + // Delete page + if ( currentPage_ ) { - currentPage_->DeInitialize(); + currentPage_->deInitialize( ); delete currentPage_; currentPage_ = NULL; } - if(metadb_) + + // Delete databases + if ( metadb_ ) { delete metadb_; metadb_ = NULL; } - if(db_) + if ( db_ ) { delete db_; db_ = NULL; } initialized = false; - //todo: handle video deallocation - Logger::write(Logger::ZONE_INFO, "RetroFE", "Exiting"); + Logger::write( Logger::ZONE_INFO, "RetroFE", "Exiting" ); return retVal; } -void RetroFE::run() + +// Run RetroFE +void RetroFE::run( ) { - if(!SDL::initialize(config_)) return; - fontcache_.initialize(); + // Initialize SDL + if(! SDL::initialize( config_ ) ) return; + fontcache_.initialize( ); + float preloadTime = 0; + + // Initialize video bool videoEnable = true; - int videoLoop = 0; - config_.getProperty("videoEnable", videoEnable); - config_.getProperty("videoLoop", videoLoop); + int videoLoop = 0; + config_.getProperty( "videoEnable", videoEnable ); + config_.getProperty( "videoLoop", videoLoop ); + VideoFactory::setEnabled( videoEnable ); + VideoFactory::setNumLoops( videoLoop ); + VideoFactory::createVideo( ); // pre-initialize the gstreamer engine + Video::setEnabled( videoEnable ); - VideoFactory::setEnabled(videoEnable); - VideoFactory::setNumLoops(videoLoop); - VideoFactory::createVideo(); // pre-initialize the gstreamer engine - Video::setEnabled(videoEnable); + initializeThread = SDL_CreateThread( initialize, "RetroFEInit", (void *)this ); - - initializeThread = SDL_CreateThread(initialize, "RetroFEInit", (void *)this); - - if(!initializeThread) + if ( !initializeThread ) { - Logger::write(Logger::ZONE_INFO, "RetroFE", "Could not initialize RetroFE"); + Logger::write( Logger::ZONE_INFO, "RetroFE", "Could not initialize RetroFE" ); return; } @@ -236,108 +283,120 @@ void RetroFE::run() bool running = true; RETROFE_STATE state = RETROFE_NEW; - config_.getProperty("attractModeTime", attractModeTime); - config_.getProperty("firstCollection", firstCollection); + config_.getProperty( "attractModeTime", attractModeTime ); + config_.getProperty( "firstCollection", firstCollection ); attract_.idleTime = static_cast(attractModeTime); int initializeStatus = 0; // load the initial splash screen, unload it once it is complete - currentPage_ = loadSplashPage(); + currentPage_ = loadSplashPage( ); state = RETROFE_ENTER; bool splashMode = true; bool exitSplashMode = false; - Launcher l(*this, config_); - preloadTime = static_cast(SDL_GetTicks()) / 1000; + Launcher l( config_ ); + preloadTime = static_cast( SDL_GetTicks( ) ) / 1000; - while (running) + while ( running ) { + float lastTime = 0; float deltaTime = 0; + + // Exit splash mode when an active key is pressed SDL_Event e; - if (splashMode && SDL_PollEvent(&e)) + if ( splashMode && SDL_PollEvent( &e ) ) { - if(input_.update(e)) + if ( input_.update( e ) ) { exitSplashMode = true; - attract_.reset(); + attract_.reset( ); } } - if(!currentPage_) + if ( !currentPage_ ) { - Logger::write(Logger::ZONE_WARNING, "RetroFE", "Could not load page"); + Logger::write( Logger::ZONE_WARNING, "RetroFE", "Could not load page" ); running = false; break; } + switch(state) { + + // Idle state; waiting for input case RETROFE_IDLE: - if(currentPage_ && !splashMode) + + // Not in splash mode + if ( currentPage_ && !splashMode ) { // account for when returning from a menu and the previous key was still "stuck" - if(lastLaunchReturnTime_ == 0 || (currentTime_ - lastLaunchReturnTime_ > .3)) + if ( lastLaunchReturnTime_ == 0 || (currentTime_ - lastLaunchReturnTime_ > .3) ) { - if(currentPage_->isIdle()) + if ( currentPage_->isIdle( ) ) { - state = processUserInput(currentPage_); + state = processUserInput( currentPage_ ); } lastLaunchReturnTime_ = 0; } } - if((initialized || initializeError) && splashMode && (exitSplashMode || (currentPage_->getMinShowTime() <= (currentTime_ - preloadTime) && !(currentPage_->isPlaying())))) + // Handle end of splash mode + if ( (initialized || initializeError) && splashMode && (exitSplashMode || (currentPage_->getMinShowTime( ) <= (currentTime_ - preloadTime) && !(currentPage_->isPlaying( )))) ) { - SDL_WaitThread(initializeThread, &initializeStatus); + SDL_WaitThread( initializeThread, &initializeStatus ); - if(initializeError) + if ( initializeError ) { state = RETROFE_QUIT_REQUEST; break; } - currentPage_->stop(); + currentPage_->stop( ); state = RETROFE_SPLASH_EXIT; } break; + // Load art on entering RetroFE case RETROFE_LOAD_ART: - currentPage_->start(); + currentPage_->start( ); state = RETROFE_ENTER; break; + // Wait for onEnter animation to finish case RETROFE_ENTER: - if(currentPage_->isIdle()) + if ( currentPage_->isIdle( ) ) { state = RETROFE_IDLE; } break; + // Handle end of splash mode case RETROFE_SPLASH_EXIT: - if(currentPage_->isIdle()) + if ( currentPage_->isIdle( ) ) { // delete the splash screen and use the standard menu - currentPage_->DeInitialize(); + currentPage_->deInitialize( ); delete currentPage_; - currentPage_ = loadPage(); + currentPage_ = loadPage( ); splashMode = false; - if(currentPage_) + if ( currentPage_ ) { std::string firstCollection = "Main"; - config_.getProperty("firstCollection", firstCollection); - config_.setProperty("currentCollection", firstCollection); + config_.getProperty( "firstCollection", firstCollection ); + config_.setProperty( "currentCollection", firstCollection ); CollectionInfo *info = getCollection(firstCollection); currentPage_->pushCollection(info); bool autoFavorites = true; - config_.getProperty("autoFavorites", autoFavorites); + config_.getProperty( "autoFavorites", autoFavorites ); if (autoFavorites) { @@ -348,8 +407,8 @@ void RetroFE::run() currentPage_->selectPlaylist("all"); // Switch to all games playlist } - currentPage_->onNewItemSelected(); - currentPage_->reallocateMenuSpritePoints(); + currentPage_->onNewItemSelected( ); + currentPage_->reallocateMenuSpritePoints( ); state = RETROFE_LOAD_ART; } @@ -360,350 +419,367 @@ void RetroFE::run() } break; + // Switch playlist; start onHighlightExit animation case RETROFE_PLAYLIST_REQUEST: - currentPage_->highlightExit(); + currentPage_->highlightExit( ); currentPage_->setScrolling(Page::ScrollDirectionIdle); state = RETROFE_PLAYLIST_EXIT; break; + // Switch playlist; wait for onHighlightExit animation to finish; load art case RETROFE_PLAYLIST_EXIT: - if (currentPage_->isIdle()) + if (currentPage_->isIdle( )) { - currentPage_->onNewItemSelected(); + currentPage_->onNewItemSelected( ); state = RETROFE_PLAYLIST_LOAD_ART; } break; + // Switch playlist; start onHighlightEnter animation case RETROFE_PLAYLIST_LOAD_ART: - if (currentPage_->isIdle()) + if (currentPage_->isIdle( )) { - currentPage_->reallocateMenuSpritePoints(); - currentPage_->highlightEnter(); + currentPage_->reallocateMenuSpritePoints( ); + currentPage_->highlightEnter( ); state = RETROFE_PLAYLIST_ENTER; } break; + // Switch playlist; wait for onHighlightEnter animation to finish case RETROFE_PLAYLIST_ENTER: - if (currentPage_->isIdle()) + if (currentPage_->isIdle( )) { state = RETROFE_IDLE; } break; - case RETROFE_HIGHLIGHT_MENU_IDLE: - currentPage_->setScrolling(Page::ScrollDirectionIdle); - if (currentPage_->isIdle()) - { - state = RETROFE_HIGHLIGHT_REQUEST; - } - break; - + // Make a jump in the menu; start onHighlightExit animation case RETROFE_MENUJUMP_REQUEST: currentPage_->setScrolling(Page::ScrollDirectionIdle); - currentPage_->highlightExit(); + currentPage_->highlightExit( ); state = RETROFE_MENUJUMP_EXIT; break; + // Make a jump in the menu; wait for onHighlightExit animation to finish; load art case RETROFE_MENUJUMP_EXIT: - if (currentPage_->isMenuIdle() && processUserInput(currentPage_) == RETROFE_MENUJUMP_REQUEST) + if (currentPage_->isMenuIdle( ) && processUserInput( currentPage_ ) == RETROFE_MENUJUMP_REQUEST) { state = RETROFE_MENUJUMP_REQUEST; } - if (currentPage_->isIdle()) + if (currentPage_->isIdle( )) { - currentPage_->highlightLoadArt(); + currentPage_->highlightLoadArt( ); state = RETROFE_HIGHLIGHT_LOAD_ART; } break; + // Start onHighlightExit animation case RETROFE_HIGHLIGHT_REQUEST: currentPage_->setScrolling(Page::ScrollDirectionIdle); - currentPage_->highlightExit(); + currentPage_->highlightExit( ); state = RETROFE_HIGHLIGHT_EXIT; break; + // Wait for onHighlightExit animation to finish; load art case RETROFE_HIGHLIGHT_EXIT: - if (currentPage_->isIdle()) + if (currentPage_->isIdle( )) { - currentPage_->highlightLoadArt(); + currentPage_->highlightLoadArt( ); state = RETROFE_HIGHLIGHT_LOAD_ART; } break; + // Start onHighlightEnter animation case RETROFE_HIGHLIGHT_LOAD_ART: - currentPage_->highlightEnter(); + currentPage_->highlightEnter( ); state = RETROFE_HIGHLIGHT_ENTER; break; + // Wait for onHighlightEnter animation to finish case RETROFE_HIGHLIGHT_ENTER: RETROFE_STATE state_tmp; - if (currentPage_->isMenuIdle() && - ((state_tmp = processUserInput(currentPage_)) == RETROFE_HIGHLIGHT_REQUEST || - state_tmp == RETROFE_MENUJUMP_REQUEST) ) + if (currentPage_->isMenuIdle( ) && + ((state_tmp = processUserInput( currentPage_ )) == RETROFE_HIGHLIGHT_REQUEST || + state_tmp == RETROFE_MENUJUMP_REQUEST) ) { state = state_tmp; } - else if (currentPage_->isIdle()) + else if (currentPage_->isIdle( )) { state = RETROFE_IDLE; } break; + // Next page; start onMenuExit animation case RETROFE_NEXT_PAGE_REQUEST: - currentPage_->exitMenu(); + currentPage_->exitMenu( ); state = RETROFE_NEXT_PAGE_MENU_EXIT; break; + // Wait for onMenuExit animation to finish; load new page if applicable; load art case RETROFE_NEXT_PAGE_MENU_EXIT: - if(currentPage_->isIdle()) + if ( currentPage_->isIdle( ) ) { - lastMenuOffsets_[currentPage_->getCollectionName()] = currentPage_->getScrollOffsetIndex(); - lastMenuPlaylists_[currentPage_->getCollectionName()] = currentPage_->getPlaylistName(); + lastMenuOffsets_[currentPage_->getCollectionName( )] = currentPage_->getScrollOffsetIndex( ); + lastMenuPlaylists_[currentPage_->getCollectionName( )] = currentPage_->getPlaylistName( ); // Load new layout if available std::string layoutName; - config_.getProperty("layout", 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 ( page ) { - currentPage_->freeGraphicsMemory(); + currentPage_->freeGraphicsMemory( ); pages_.push( currentPage_ ); currentPage_ = page; } - config_.setProperty("currentCollection", nextPageName); + config_.setProperty( "currentCollection", nextPageName ); - CollectionInfo *info = getCollection(nextPageName); + CollectionInfo *info = getCollection( nextPageName ); currentPage_->pushCollection(info); bool rememberMenu = false; - config_.getProperty("rememberMenu", rememberMenu); + config_.getProperty( "rememberMenu", rememberMenu ); bool autoFavorites = true; - config_.getProperty("autoFavorites", autoFavorites); + config_.getProperty( "autoFavorites", autoFavorites ); - if (rememberMenu && lastMenuPlaylists_.find(nextPageName) != lastMenuPlaylists_.end()) + if (rememberMenu && lastMenuPlaylists_.find( nextPageName ) != lastMenuPlaylists_.end( )) { - currentPage_->selectPlaylist(lastMenuPlaylists_[nextPageName]); // Switch to last playlist + currentPage_->selectPlaylist( lastMenuPlaylists_[nextPageName] ); // Switch to last playlist } else if (autoFavorites) { - currentPage_->selectPlaylist("favorites"); // Switch to favorites playlist + currentPage_->selectPlaylist( "favorites" ); // Switch to favorites playlist } else { - currentPage_->selectPlaylist("all"); // Switch to all games playlist + currentPage_->selectPlaylist( "all" ); // Switch to all games playlist } - if(rememberMenu && lastMenuOffsets_.find(nextPageName) != lastMenuOffsets_.end()) + if ( rememberMenu && lastMenuOffsets_.find( nextPageName ) != lastMenuOffsets_.end( ) ) { - currentPage_->setScrollOffsetIndex(lastMenuOffsets_[nextPageName]); + currentPage_->setScrollOffsetIndex( lastMenuOffsets_[nextPageName] ); } - currentPage_->onNewItemSelected(); - currentPage_->reallocateMenuSpritePoints(); + currentPage_->onNewItemSelected( ); + currentPage_->reallocateMenuSpritePoints( ); state = RETROFE_NEXT_PAGE_MENU_LOAD_ART; } break; + // Start onMenuEnter animation case RETROFE_NEXT_PAGE_MENU_LOAD_ART: - if (currentPage_->getMenuDepth() != 1 ) + if (currentPage_->getMenuDepth( ) != 1 ) { - currentPage_->enterMenu(); + currentPage_->enterMenu( ); } else { - currentPage_->start(); + currentPage_->start( ); } state = RETROFE_NEXT_PAGE_MENU_ENTER; break; + // Wait for onMenuEnter animation to finish case RETROFE_NEXT_PAGE_MENU_ENTER: - if(currentPage_->isIdle()) + if ( currentPage_->isIdle( ) ) { bool collectionInputClear = false; config_.getProperty( "collectionInputClear", collectionInputClear ); - if( collectionInputClear ) + if ( collectionInputClear ) { // Empty event queue SDL_Event e; - while (SDL_PollEvent(&e)); - input_.resetStates(); + while ( SDL_PollEvent( &e ) ); + input_.resetStates( ); } state = RETROFE_IDLE; } break; + // Launching game; start onGameEnter animation case RETROFE_LAUNCH_ENTER: - currentPage_->enterGame(); + currentPage_->enterGame( ); state = RETROFE_LAUNCH_REQUEST; break; + // Wait for onGameEnter animation to finish; launch game; start onGameExit animation case RETROFE_LAUNCH_REQUEST: - if(currentPage_->isIdle()) + if ( currentPage_->isIdle( ) ) { - nextPageItem_ = currentPage_->getSelectedItem(); - launchEnter(); + nextPageItem_ = currentPage_->getSelectedItem( ); + launchEnter( ); l.run(nextPageItem_->collectionInfo->name, nextPageItem_); - launchExit(); - currentPage_->exitGame(); + launchExit( ); + currentPage_->exitGame( ); state = RETROFE_LAUNCH_EXIT; } break; + // Wait for onGameExit animation to finish case RETROFE_LAUNCH_EXIT: - if(currentPage_->isIdle()) + if ( currentPage_->isIdle( ) ) { state = RETROFE_IDLE; } break; + // Go back a page; start onMenuExit animation case RETROFE_BACK_REQUEST: - if (currentPage_->getMenuDepth() == 1 ) + if (currentPage_->getMenuDepth( ) == 1 ) { - currentPage_->stop(); + currentPage_->stop( ); } else { - currentPage_->exitMenu(); + currentPage_->exitMenu( ); } state = RETROFE_BACK_MENU_EXIT; break; + // Wait for onMenuExit animation to finish; load previous page; load art case RETROFE_BACK_MENU_EXIT: - if(currentPage_->isIdle()) + if ( currentPage_->isIdle( ) ) { - lastMenuOffsets_[currentPage_->getCollectionName()] = currentPage_->getScrollOffsetIndex(); - lastMenuPlaylists_[currentPage_->getCollectionName()] = currentPage_->getPlaylistName(); - if (currentPage_->getMenuDepth() == 1) + lastMenuOffsets_[currentPage_->getCollectionName( )] = currentPage_->getScrollOffsetIndex( ); + lastMenuPlaylists_[currentPage_->getCollectionName( )] = currentPage_->getPlaylistName( ); + if (currentPage_->getMenuDepth( ) == 1) { - currentPage_->DeInitialize(); + currentPage_->deInitialize( ); delete currentPage_; - currentPage_ = pages_.top(); - pages_.pop(); - currentPage_->allocateGraphicsMemory(); + currentPage_ = pages_.top( ); + pages_.pop( ); + currentPage_->allocateGraphicsMemory( ); } else { - currentPage_->popCollection(); + currentPage_->popCollection( ); } - config_.setProperty("currentCollection", currentPage_->getCollectionName()); + config_.setProperty( "currentCollection", currentPage_->getCollectionName( ) ); bool rememberMenu = false; - config_.getProperty("rememberMenu", rememberMenu); + config_.getProperty( "rememberMenu", rememberMenu ); bool autoFavorites = true; - config_.getProperty("autoFavorites", autoFavorites); + config_.getProperty( "autoFavorites", autoFavorites ); - if (rememberMenu && lastMenuPlaylists_.find(currentPage_->getCollectionName()) != lastMenuPlaylists_.end()) + if (rememberMenu && lastMenuPlaylists_.find( currentPage_->getCollectionName( ) ) != lastMenuPlaylists_.end( )) { - currentPage_->selectPlaylist(lastMenuPlaylists_[currentPage_->getCollectionName()]); // Switch to last playlist + currentPage_->selectPlaylist( lastMenuPlaylists_[currentPage_->getCollectionName( )] ); // Switch to last playlist } - else if (autoFavorites) + else if ( autoFavorites ) { - currentPage_->selectPlaylist("favorites"); // Switch to favorites playlist + currentPage_->selectPlaylist( "favorites" ); // Switch to favorites playlist } else { - currentPage_->selectPlaylist("all"); // Switch to all games playlist + currentPage_->selectPlaylist( "all" ); // Switch to all games playlist } - if(rememberMenu && lastMenuOffsets_.find(currentPage_->getCollectionName()) != lastMenuOffsets_.end()) + if ( rememberMenu && lastMenuOffsets_.find( currentPage_->getCollectionName( ) ) != lastMenuOffsets_.end( ) ) { - currentPage_->setScrollOffsetIndex(lastMenuOffsets_[currentPage_->getCollectionName()]); + currentPage_->setScrollOffsetIndex( lastMenuOffsets_[currentPage_->getCollectionName( )] ); } - currentPage_->onNewItemSelected(); - currentPage_->reallocateMenuSpritePoints(); + currentPage_->onNewItemSelected( ); + currentPage_->reallocateMenuSpritePoints( ); state = RETROFE_BACK_MENU_LOAD_ART; } break; + // Start onMenuEnter animation case RETROFE_BACK_MENU_LOAD_ART: - currentPage_->enterMenu(); + currentPage_->enterMenu( ); state = RETROFE_BACK_MENU_ENTER; break; + // Wait for onMenuEnter animation to finish case RETROFE_BACK_MENU_ENTER: - if(currentPage_->isIdle()) + if ( currentPage_->isIdle( ) ) { - currentPage_->cleanup(); + currentPage_->cleanup( ); bool collectionInputClear = false; config_.getProperty( "collectionInputClear", collectionInputClear ); - if( collectionInputClear ) + if ( collectionInputClear ) { // Empty event queue SDL_Event e; - while (SDL_PollEvent(&e)); - input_.resetStates(); + while ( SDL_PollEvent( &e ) ); + input_.resetStates( ); } state = RETROFE_IDLE; } break; + // Wait for splash mode animation to finish case RETROFE_NEW: - if(currentPage_->isIdle()) + if ( currentPage_->isIdle( ) ) { state = RETROFE_IDLE; } break; + // Start the onExit animation case RETROFE_QUIT_REQUEST: - currentPage_->stop(); + currentPage_->stop( ); state = RETROFE_QUIT; break; + // Wait for onExit animation to finish before quitting RetroFE case RETROFE_QUIT: - if(currentPage_->isGraphicsIdle()) + if ( currentPage_->isGraphicsIdle( ) ) { running = false; } break; } - // the logic below could be done in a helper method - if(running) + // Handle screen updates and attract mode + if ( running ) { lastTime = currentTime_; - currentTime_ = static_cast(SDL_GetTicks()) / 1000; + currentTime_ = static_cast( SDL_GetTicks( ) ) / 1000; - if (currentTime_ < lastTime) + if ( currentTime_ < lastTime ) { currentTime_ = lastTime; } deltaTime = currentTime_ - lastTime; double sleepTime = 1000.0/60.0 - deltaTime*1000; - if(sleepTime > 0) + if ( sleepTime > 0 ) { - SDL_Delay(static_cast(sleepTime)); + SDL_Delay( static_cast( sleepTime ) ); } - if(currentPage_) + if ( currentPage_ ) { if (!splashMode) { - attract_.update(deltaTime, *currentPage_); + attract_.update( deltaTime, *currentPage_ ); } - currentPage_->update(deltaTime); + currentPage_->update( deltaTime ); } - render(); + render( ); } } } +// Check if we can go back a page or quite RetroFE bool RetroFE::back(bool &exit) { - bool canGoBack = false; + bool canGoBack = false; bool exitOnBack = false; - config_.getProperty("exitOnFirstPageBack", exitOnBack); + config_.getProperty( "exitOnFirstPageBack", exitOnBack ); exit = false; - if(currentPage_->getMenuDepth() <= 1 && pages_.empty()) + if ( currentPage_->getMenuDepth( ) <= 1 && pages_.empty( ) ) { exit = exitOnBack; } @@ -716,57 +792,61 @@ bool RetroFE::back(bool &exit) } -RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) +// Process the user input +RetroFE::RETROFE_STATE RetroFE::processUserInput( Page *page ) { bool exit = false; RETROFE_STATE state = RETROFE_IDLE; + // Poll all events until we find an active one SDL_Event e; - while (SDL_PollEvent(&e)) + while ( SDL_PollEvent( &e ) ) { input_.update(e); - if(e.type == SDL_KEYDOWN && !e.key.repeat) + if ( e.type == SDL_KEYDOWN && !e.key.repeat ) { break; } } - if(page->isHorizontalScroll()) + // Handle next/previous game inputs + if ( page->isHorizontalScroll( ) ) { if (input_.keystate(UserInput::KeyCodeLeft)) { - attract_.reset(); + attract_.reset( ); page->setScrolling(Page::ScrollDirectionBack); page->scroll(false); - page->updateScrollPeriod(); + page->updateScrollPeriod( ); } if (input_.keystate(UserInput::KeyCodeRight)) { - attract_.reset(); + attract_.reset( ); page->setScrolling(Page::ScrollDirectionForward); page->scroll(true); - page->updateScrollPeriod(); + page->updateScrollPeriod( ); } } else { if (input_.keystate(UserInput::KeyCodeUp)) { - attract_.reset(); + attract_.reset( ); page->setScrolling(Page::ScrollDirectionBack); page->scroll(false); - page->updateScrollPeriod(); + page->updateScrollPeriod( ); } if (input_.keystate(UserInput::KeyCodeDown)) { - attract_.reset(); + attract_.reset( ); page->setScrolling(Page::ScrollDirectionForward); page->scroll(true); - page->updateScrollPeriod(); + page->updateScrollPeriod( ); } } - if(page->isMenuIdle()) + // Ignore other keys while the menu is scrolling + if ( page->isMenuIdle( ) ) { if (!input_.keystate(UserInput::KeyCodePageUp) && @@ -784,75 +864,75 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) keyDelayTime_= 0.3f; } - else if((currentTime_ - keyLastTime_) > keyDelayTime_ || keyLastTime_ == 0) + else if ( (currentTime_ - keyLastTime_) > keyDelayTime_ || keyLastTime_ == 0 ) { keyLastTime_ = currentTime_; keyDelayTime_-= .05f; - if(keyDelayTime_< 0.1f) keyDelayTime_= 0.1f; + if ( keyDelayTime_< 0.1f ) keyDelayTime_= 0.1f; if (input_.keystate(UserInput::KeyCodePageUp)) { - attract_.reset(); + attract_.reset( ); page->pageScroll(Page::ScrollDirectionBack); - page->reallocateMenuSpritePoints(); + page->reallocateMenuSpritePoints( ); state = RETROFE_MENUJUMP_REQUEST; } if (input_.keystate(UserInput::KeyCodePageDown)) { - attract_.reset(); + attract_.reset( ); page->pageScroll(Page::ScrollDirectionForward); - page->reallocateMenuSpritePoints(); + page->reallocateMenuSpritePoints( ); state = RETROFE_MENUJUMP_REQUEST; } if (input_.keystate(UserInput::KeyCodeLetterUp)) { - attract_.reset(); + attract_.reset( ); page->letterScroll(Page::ScrollDirectionBack); - page->reallocateMenuSpritePoints(); + page->reallocateMenuSpritePoints( ); state = RETROFE_MENUJUMP_REQUEST; } if (input_.keystate(UserInput::KeyCodeLetterDown)) { - attract_.reset(); + attract_.reset( ); page->letterScroll(Page::ScrollDirectionForward); - page->reallocateMenuSpritePoints(); + page->reallocateMenuSpritePoints( ); state = RETROFE_MENUJUMP_REQUEST; } - if(input_.newKeyPressed(UserInput::KeyCodeFavPlaylist)) + if ( input_.newKeyPressed(UserInput::KeyCodeFavPlaylist) ) { - attract_.reset(); - page->favPlaylist(); + attract_.reset( ); + page->favPlaylist( ); state = RETROFE_PLAYLIST_REQUEST; } - if(input_.newKeyPressed(UserInput::KeyCodeNextPlaylist)) + if ( input_.newKeyPressed(UserInput::KeyCodeNextPlaylist) ) { - attract_.reset(); - page->nextPlaylist(); + attract_.reset( ); + page->nextPlaylist( ); state = RETROFE_PLAYLIST_REQUEST; } - if(input_.newKeyPressed(UserInput::KeyCodePrevPlaylist)) + if ( input_.newKeyPressed(UserInput::KeyCodePrevPlaylist) ) { - attract_.reset(); - page->prevPlaylist(); + attract_.reset( ); + page->prevPlaylist( ); state = RETROFE_PLAYLIST_REQUEST; } - if(input_.newKeyPressed(UserInput::KeyCodeRemovePlaylist)) + if ( input_.newKeyPressed(UserInput::KeyCodeRemovePlaylist) ) { - attract_.reset(); - page->removePlaylist(); + attract_.reset( ); + page->removePlaylist( ); state = RETROFE_PLAYLIST_REQUEST; } - if(input_.newKeyPressed(UserInput::KeyCodeAddPlaylist)) + if ( input_.newKeyPressed(UserInput::KeyCodeAddPlaylist) ) { - attract_.reset(); - page->addPlaylist(); + attract_.reset( ); + page->addPlaylist( ); state = RETROFE_PLAYLIST_REQUEST; } - if(input_.keystate(UserInput::KeyCodeRandom)) + if ( input_.keystate(UserInput::KeyCodeRandom) ) { - attract_.reset(); - page->selectRandom(); - page->reallocateMenuSpritePoints(); + attract_.reset( ); + page->selectRandom( ); + page->reallocateMenuSpritePoints( ); state = RETROFE_HIGHLIGHT_REQUEST; } } @@ -861,14 +941,15 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) { //todo: add admin mode support } + if (input_.keystate(UserInput::KeyCodeSelect)) { - attract_.reset(); - nextPageItem_ = page->getSelectedItem(); + attract_.reset( ); + nextPageItem_ = page->getSelectedItem( ); - if(nextPageItem_) + if ( nextPageItem_ ) { - if(nextPageItem_->leaf) + if ( nextPageItem_->leaf ) { state = RETROFE_LAUNCH_ENTER; } @@ -881,8 +962,8 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) if (input_.keystate(UserInput::KeyCodeBack)) { - attract_.reset(); - if(back(exit) || exit) + attract_.reset( ); + if ( back( exit ) || exit ) { state = (exit) ? RETROFE_QUIT_REQUEST : RETROFE_BACK_REQUEST; } @@ -890,25 +971,26 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) if (input_.keystate(UserInput::KeyCodeQuit)) { - attract_.reset(); + attract_.reset( ); state = RETROFE_QUIT_REQUEST; } } - if(!input_.keystate(UserInput::KeyCodeUp) && - !input_.keystate(UserInput::KeyCodeLeft) && - !input_.keystate(UserInput::KeyCodeDown) && - !input_.keystate(UserInput::KeyCodeRight) && - !input_.keystate(UserInput::KeyCodePageUp) && - !input_.keystate(UserInput::KeyCodePageDown) && - !input_.keystate(UserInput::KeyCodeLetterUp) && - !input_.keystate(UserInput::KeyCodeLetterDown) && - !attract_.isActive()) + // Check if we're done scrolling + if ( !input_.keystate(UserInput::KeyCodeUp) && + !input_.keystate(UserInput::KeyCodeLeft) && + !input_.keystate(UserInput::KeyCodeDown) && + !input_.keystate(UserInput::KeyCodeRight) && + !input_.keystate(UserInput::KeyCodePageUp) && + !input_.keystate(UserInput::KeyCodePageDown) && + !input_.keystate(UserInput::KeyCodeLetterUp) && + !input_.keystate(UserInput::KeyCodeLetterDown) && + !attract_.isActive( ) ) { - page->resetScrollPeriod(); - if (page->isMenuScrolling()) + page->resetScrollPeriod( ); + if (page->isMenuScrolling( )) { - attract_.reset(); + attract_.reset( ); state = RETROFE_HIGHLIGHT_REQUEST; } } @@ -916,129 +998,135 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) return state; } -Page *RetroFE::loadPage() + +// Load a page +Page *RetroFE::loadPage( ) { std::string layoutName; - config_.getProperty("layout", layoutName); + config_.getProperty( "layout", layoutName ); PageBuilder pb(layoutName, "layout", config_, &fontcache_); - Page *page = pb.buildPage(); + Page *page = pb.buildPage( ); - if(!page) + if ( !page ) { - Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not create page"); + Logger::write( Logger::ZONE_ERROR, "RetroFE", "Could not create page" ); } return page; } -Page *RetroFE::loadSplashPage() + +// Load the splash page +Page *RetroFE::loadSplashPage( ) { std::string layoutName; - config_.getProperty("layout", layoutName); + config_.getProperty( "layout", layoutName ); PageBuilder pb(layoutName, "splash", config_, &fontcache_); - Page * page = pb.buildPage(); - page->start(); + Page * page = pb.buildPage( ); + page->start( ); return page; } +// Load a collection CollectionInfo *RetroFE::getCollection(std::string collectionName) { - // the page will deallocate this once its done + // Build the collection CollectionInfoBuilder cib(config_, *metadb_); - CollectionInfo *collection = cib.buildCollection(collectionName); - cib.injectMetadata(collection); + CollectionInfo *collection = cib.buildCollection( collectionName ); + cib.injectMetadata( collection ); DIR *dp; struct dirent *dirp; - std::string path = Utils::combinePath(Configuration::absolutePath, "collections", collectionName); - dp = opendir(path.c_str()); + std::string path = Utils::combinePath( Configuration::absolutePath, "collections", collectionName ); + dp = opendir( path.c_str( ) ); - while((dirp = readdir(dp)) != NULL) + // Loading sub collection files + while ( (dirp = readdir( dp )) != NULL ) { std::string file = dirp->d_name; - size_t position = file.find_last_of("."); - std::string basename = (std::string::npos == position)? file : file.substr(0, position); + size_t position = file.find_last_of( "." ); + std::string basename = (std::string::npos == position)? file : file.substr( 0, position ); std::string comparator = ".sub"; - int start = file.length() - comparator.length(); + int start = file.length( ) - comparator.length( ); - if(start >= 0) + if ( start >= 0 ) { - if(file.compare(start, comparator.length(), comparator) == 0) + if ( file.compare( start, comparator.length( ), comparator ) == 0 ) { - Logger::write(Logger::ZONE_INFO, "RetroFE", "Loading subcollection into menu: " + basename); + Logger::write( Logger::ZONE_INFO, "RetroFE", "Loading subcollection into menu: " + basename ); - CollectionInfo *subcollection = cib.buildCollection(basename, collectionName); - collection->addSubcollection(subcollection); - cib.injectMetadata(subcollection); + CollectionInfo *subcollection = cib.buildCollection( basename, collectionName ); + collection->addSubcollection( subcollection ); + cib.injectMetadata( subcollection ); } } } - closedir(dp); + closedir( dp ); bool menuSort = true; - config_.getProperty("collections." + collectionName + ".list.menuSort", menuSort); + config_.getProperty( "collections." + collectionName + ".list.menuSort", menuSort ); - if (menuSort) + if ( menuSort ) { - collection->sortItems(); + collection->sortItems( ); } MenuParser mp; - mp.buildMenuItems(collection, menuSort); + mp.buildMenuItems( collection, menuSort ); - cib.addPlaylists(collection); - collection->sortFavoriteItems(); + cib.addPlaylists( collection ); + collection->sortFavoriteItems( ); // Remove parenthesis and brackets, if so configured - bool showParenthesis = true; + bool showParenthesis = true; bool showSquareBrackets = true; - (void)config_.getProperty("showParenthesis", showParenthesis); - (void)config_.getProperty("showSquareBrackets", showSquareBrackets); + (void)config_.getProperty( "showParenthesis", showParenthesis ); + (void)config_.getProperty( "showSquareBrackets", showSquareBrackets ); typedef std::map *> Playlists_T; - for(Playlists_T::iterator itP = collection->playlists.begin(); itP != collection->playlists.end(); itP++) + for ( Playlists_T::iterator itP = collection->playlists.begin( ); itP != collection->playlists.end( ); itP++ ) { - for(std::vector ::iterator itI = itP->second->begin(); itI != itP->second->end(); itI++) + for ( std::vector ::iterator itI = itP->second->begin( ); itI != itP->second->end( ); itI++ ) { - if(!showParenthesis) + if ( !showParenthesis ) { - std::string::size_type firstPos = (*itI)->title.find_first_of("("); - std::string::size_type secondPos = (*itI)->title.find_first_of(")", firstPos); + std::string::size_type firstPos = (*itI)->title.find_first_of( "(" ); + std::string::size_type secondPos = (*itI)->title.find_first_of( ")", firstPos ); - while(firstPos != std::string::npos && secondPos != std::string::npos) + while ( firstPos != std::string::npos && secondPos != std::string::npos ) { - firstPos = (*itI)->title.find_first_of("("); - secondPos = (*itI)->title.find_first_of(")", firstPos); + firstPos = (*itI)->title.find_first_of( "(" ); + secondPos = (*itI)->title.find_first_of( ")", firstPos ); - if (firstPos != std::string::npos) + if ( firstPos != std::string::npos ) { - (*itI)->title.erase(firstPos, (secondPos - firstPos) + 1); + (*itI)->title.erase( firstPos, (secondPos - firstPos) + 1 ); } } } - if(!showSquareBrackets) + if ( !showSquareBrackets ) { - std::string::size_type firstPos = (*itI)->title.find_first_of("["); - std::string::size_type secondPos = (*itI)->title.find_first_of("]", firstPos); + std::string::size_type firstPos = (*itI)->title.find_first_of( "[" ); + std::string::size_type secondPos = (*itI)->title.find_first_of( "]", firstPos ); - while(firstPos != std::string::npos && secondPos != std::string::npos) + while ( firstPos != std::string::npos && secondPos != std::string::npos ) { - firstPos = (*itI)->title.find_first_of("["); - secondPos = (*itI)->title.find_first_of("]", firstPos); + firstPos = (*itI)->title.find_first_of( "[" ); + secondPos = (*itI)->title.find_first_of( "]", firstPos ); - if (firstPos != std::string::npos && secondPos != std::string::npos) + if ( firstPos != std::string::npos && secondPos != std::string::npos ) { - (*itI)->title.erase(firstPos, (secondPos - firstPos) + 1); + (*itI)->title.erase( firstPos, (secondPos - firstPos) + 1 ); } } } @@ -1047,16 +1135,3 @@ CollectionInfo *RetroFE::getCollection(std::string collectionName) return collection; } - -std::string RetroFE::getLayout(std::string collectionName) -{ - std::string layoutKeyName = "collections." + collectionName + ".layout"; - std::string layoutName = "Default 16x9"; - - if(!config_.getProperty(layoutKeyName, layoutName)) - { - config_.getProperty("layout", layoutName); - } - - return layoutName; -} diff --git a/RetroFE/Source/RetroFE.h b/RetroFE/Source/RetroFE.h index 911ff0c..8bc0d89 100644 --- a/RetroFE/Source/RetroFE.h +++ b/RetroFE/Source/RetroFE.h @@ -15,6 +15,7 @@ */ #pragma once + #include "Collection/Item.h" #include "Control/UserInput.h" #include "Database/DB.h" @@ -28,26 +29,30 @@ #include #include + class CollectionInfo; class Configuration; class Page; + class RetroFE { + public: - RetroFE(Configuration &c); - virtual ~RetroFE(); - bool deInitialize(); - void run(); - void freeGraphicsMemory(); - void allocateGraphicsMemory(); - void launchEnter(); - void launchExit(); + RetroFE( Configuration &c ); + virtual ~RetroFE( ); + bool deInitialize( ); + void run( ); + void freeGraphicsMemory( ); + void allocateGraphicsMemory( ); + void launchEnter( ); + void launchExit( ); + private: volatile bool initialized; volatile bool initializeError; - SDL_Thread *initializeThread; - static int initialize(void *context); + SDL_Thread *initializeThread; + static int initialize( void *context ); enum RETROFE_STATE { @@ -65,7 +70,6 @@ private: RETROFE_HIGHLIGHT_EXIT, RETROFE_HIGHLIGHT_LOAD_ART, RETROFE_HIGHLIGHT_ENTER, - RETROFE_HIGHLIGHT_MENU_IDLE, RETROFE_NEXT_PAGE_REQUEST, RETROFE_NEXT_PAGE_MENU_EXIT, RETROFE_NEXT_PAGE_MENU_LOAD_ART, @@ -82,30 +86,31 @@ private: RETROFE_QUIT, }; - void render(); - bool back(bool &exit); - void quit(); - Page *loadPage(); - Page *loadSplashPage(); - RETROFE_STATE processUserInput(Page *page); - void update(float dt, bool scrollActive); - std::string getLayout(std::string collectionName); - CollectionInfo *getCollection(std::string collectionName); - Configuration &config_; - DB *db_; - MetadataDatabase *metadb_; - UserInput input_; - Page *currentPage_; + void render( ); + bool back( bool &exit ); + void quit( ); + Page *loadPage( ); + Page *loadSplashPage( ); + RETROFE_STATE processUserInput( Page *page ); + void update( float dt, bool scrollActive ); + CollectionInfo *getCollection( std::string collectionName ); + + Configuration &config_; + DB *db_; + MetadataDatabase *metadb_; + UserInput input_; + Page *currentPage_; std::stack pages_; - float keyInputDisable_; - float currentTime_; - float lastLaunchReturnTime_; - float keyLastTime_; - float keyDelayTime_; - Item *nextPageItem_; - FontCache fontcache_; - AttractMode attract_; + float keyInputDisable_; + float currentTime_; + float lastLaunchReturnTime_; + float keyLastTime_; + float keyDelayTime_; + Item *nextPageItem_; + FontCache fontcache_; + AttractMode attract_; + std::map lastMenuOffsets_; - std::map lastMenuPlaylists_; + std::map lastMenuPlaylists_; }; diff --git a/RetroFE/Source/SDL.cpp b/RetroFE/Source/SDL.cpp index c58e2b0..e8739ac 100644 --- a/RetroFE/Source/SDL.cpp +++ b/RetroFE/Source/SDL.cpp @@ -14,122 +14,125 @@ * along with RetroFE. If not, see . */ + #include "SDL.h" #include "Database/Configuration.h" #include "Utility/Log.h" #include -SDL_Window *SDL::window_ = NULL; -SDL_Renderer *SDL::renderer_ = NULL; -SDL_mutex *SDL::mutex_ = NULL; -int SDL::displayWidth_ = 0; -int SDL::displayHeight_ = 0; -int SDL::windowWidth_ = 0; -int SDL::windowHeight_ = 0; -bool SDL::fullscreen_ = false; + +SDL_Window *SDL::window_ = NULL; +SDL_Renderer *SDL::renderer_ = NULL; +SDL_mutex *SDL::mutex_ = NULL; +int SDL::displayWidth_ = 0; +int SDL::displayHeight_ = 0; +int SDL::windowWidth_ = 0; +int SDL::windowHeight_ = 0; +bool SDL::fullscreen_ = false; -bool SDL::initialize(Configuration &config) +// Initialize SDL +bool SDL::initialize( Configuration &config ) { - bool retVal = true; + + bool retVal = true; std::string hString; std::string vString; - Uint32 windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS; - int audioRate = MIX_DEFAULT_FREQUENCY; - Uint16 audioFormat = MIX_DEFAULT_FORMAT; /* 16-bit stereo */ - int audioChannels = 1; - int audioBuffers = 4096; - bool hideMouse; + Uint32 windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS; + int audioRate = MIX_DEFAULT_FREQUENCY; + Uint16 audioFormat = MIX_DEFAULT_FORMAT; /* 16-bit stereo */ + int audioChannels = 1; + int audioBuffers = 4096; + bool hideMouse; - Logger::write(Logger::ZONE_INFO, "SDL", "Initializing"); - if (retVal && SDL_Init(SDL_INIT_EVERYTHING) != 0) + Logger::write( Logger::ZONE_INFO, "SDL", "Initializing" ); + if (retVal && SDL_Init( SDL_INIT_EVERYTHING ) != 0) { - std::string error = SDL_GetError(); - Logger::write(Logger::ZONE_ERROR, "SDL", "Initialize failed: " + error); + std::string error = SDL_GetError( ); + Logger::write( Logger::ZONE_ERROR, "SDL", "Initialize failed: " + error ); retVal = false; } - if(retVal && config.getProperty("hideMouse", hideMouse)) + if ( retVal && config.getProperty( "hideMouse", hideMouse ) ) { - if(hideMouse) + if ( hideMouse ) { - SDL_ShowCursor(SDL_FALSE); + SDL_ShowCursor( SDL_FALSE ); } else { - SDL_ShowCursor(SDL_TRUE); + SDL_ShowCursor( SDL_TRUE ); } } // check for a few other necessary Configurations - if(retVal) + if ( retVal ) { // Get current display mode of all displays. - for(int i = 0; i < SDL_GetNumVideoDisplays(); ++i) + for(int i = 0; i < SDL_GetNumVideoDisplays( ); ++i) { SDL_DisplayMode mode; - if(SDL_GetCurrentDisplayMode(i, &mode) == 0) + if ( SDL_GetCurrentDisplayMode( i, &mode ) == 0 ) { - displayWidth_ = mode.w; + displayWidth_ = mode.w; displayHeight_ = mode.h; break; } } - - if(!config.getProperty("horizontal", hString)) + if ( !config.getProperty( "horizontal", hString ) ) { - Logger::write(Logger::ZONE_ERROR, "Configuration", "Missing property \"horizontal\""); + Logger::write( Logger::ZONE_ERROR, "Configuration", "Missing property \"horizontal\"" ); retVal = false; } - else if(hString == "stretch") + else if ( hString == "stretch" ) { // Get current display mode of all displays. - for(int i = 0; i < SDL_GetNumVideoDisplays(); ++i) + for(int i = 0; i < SDL_GetNumVideoDisplays( ); ++i) { SDL_DisplayMode mode; - if(SDL_GetCurrentDisplayMode(i, &mode) == 0) + if ( SDL_GetCurrentDisplayMode( i, &mode ) == 0 ) { windowWidth_ = mode.w; break; } } } - else if(!config.getProperty("horizontal", windowWidth_)) + else if ( !config.getProperty( "horizontal", windowWidth_ ) ) { - Logger::write(Logger::ZONE_ERROR, "Configuration", "Invalid property value for \"horizontal\""); + Logger::write( Logger::ZONE_ERROR, "Configuration", "Invalid property value for \"horizontal\"" ); } } - if(retVal) + if ( retVal ) { - if(!config.getProperty("vertical", vString)) + if ( !config.getProperty( "vertical", vString ) ) { - Logger::write(Logger::ZONE_ERROR, "Configuration", "Missing property \"vertical\""); + Logger::write( Logger::ZONE_ERROR, "Configuration", "Missing property \"vertical\"" ); retVal = false; } - else if(vString == "stretch") + else if ( vString == "stretch" ) { // Get current display mode of all displays. - for(int i = 0; i < SDL_GetNumVideoDisplays(); ++i) + for(int i = 0; i < SDL_GetNumVideoDisplays( ); ++i) { SDL_DisplayMode mode; - if(SDL_GetDesktopDisplayMode(i, &mode) == 0) + if ( SDL_GetDesktopDisplayMode( i, &mode ) == 0 ) { windowHeight_ = mode.h; break; } } } - else if(!config.getProperty("vertical", windowHeight_)) + else if ( !config.getProperty( "vertical", windowHeight_ ) ) { - Logger::write(Logger::ZONE_ERROR, "Configuration", "Invalid property value for \"vertical\""); + Logger::write( Logger::ZONE_ERROR, "Configuration", "Invalid property value for \"vertical\"" ); } } - if(retVal && !config.getProperty("fullscreen", fullscreen_)) + if ( retVal && !config.getProperty( "fullscreen", fullscreen_ ) ) { - Logger::write(Logger::ZONE_ERROR, "Configuration", "Missing property: \"fullscreen\""); + Logger::write( Logger::ZONE_ERROR, "Configuration", "Missing property: \"fullscreen\"" ); retVal = false; } @@ -142,133 +145,137 @@ bool SDL::initialize(Configuration &config) #endif } - if(retVal) + if ( retVal ) { std::string fullscreenStr = fullscreen_ ? "yes" : "no"; std::stringstream ss; - ss << "Creating "<< windowWidth_ << "x" << windowHeight_ << " window (fullscreen: " - << fullscreenStr << ")"; + ss << "Creating "<< windowWidth_ << "x" << windowHeight_ << " window (fullscreen: " << fullscreenStr << ")"; - Logger::write(Logger::ZONE_INFO, "SDL", ss.str()); + Logger::write( Logger::ZONE_INFO, "SDL", ss.str( )); - window_ = SDL_CreateWindow("RetroFE", - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - windowWidth_, - windowHeight_, - windowFlags); + window_ = SDL_CreateWindow( "RetroFE", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, windowWidth_, windowHeight_, windowFlags ); - if (window_ == NULL) + if ( window_ == NULL ) { - std::string error = SDL_GetError(); - Logger::write(Logger::ZONE_ERROR, "SDL", "Create window failed: " + error); + std::string error = SDL_GetError( ); + Logger::write( Logger::ZONE_ERROR, "SDL", "Create window failed: " + error ); retVal = false; } } - if(retVal) + if ( retVal ) { - renderer_ = SDL_CreateRenderer(window_, - -1, - SDL_RENDERER_ACCELERATED); + renderer_ = SDL_CreateRenderer( window_, -1, SDL_RENDERER_ACCELERATED ); - if (renderer_ == NULL) + if ( renderer_ == NULL ) { - std::string error = SDL_GetError(); - Logger::write(Logger::ZONE_ERROR, "SDL", "Create renderer failed: " + error); + std::string error = SDL_GetError( ); + Logger::write( Logger::ZONE_ERROR, "SDL", "Create renderer failed: " + error ); retVal = false; } } - if(SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1") != SDL_TRUE) + if ( SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1") != SDL_TRUE ) { - Logger::write(Logger::ZONE_ERROR, "SDL", "Improve scale quality. Continuing with low-quality settings."); + Logger::write( Logger::ZONE_ERROR, "SDL", "Improve scale quality. Continuing with low-quality settings." ); } bool minimize_on_focus_loss_; - if(config.getProperty("minimize_on_focus_loss", minimize_on_focus_loss_)) + if ( config.getProperty( "minimize_on_focus_loss", minimize_on_focus_loss_ ) ) { - if(minimize_on_focus_loss_) + if ( minimize_on_focus_loss_ ) { - SDL_SetHintWithPriority(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "1", SDL_HINT_OVERRIDE); + SDL_SetHintWithPriority( SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "1", SDL_HINT_OVERRIDE ); } else { - SDL_SetHintWithPriority(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0", SDL_HINT_OVERRIDE); + SDL_SetHintWithPriority( SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0", SDL_HINT_OVERRIDE ); } } - if(retVal) + if ( retVal ) { - mutex_ = SDL_CreateMutex(); + mutex_ = SDL_CreateMutex( ); - if (mutex_ == NULL) + if ( mutex_ == NULL ) { - std::string error = SDL_GetError(); - Logger::write(Logger::ZONE_ERROR, "SDL", "Mutex creation failed: " + error); + std::string error = SDL_GetError( ); + Logger::write( Logger::ZONE_ERROR, "SDL", "Mutex creation failed: " + error ); retVal = false; } } //todo: specify in configuration file - if (retVal && Mix_OpenAudio(audioRate, audioFormat, audioChannels, audioBuffers) == -1) + if ( retVal && Mix_OpenAudio( audioRate, audioFormat, audioChannels, audioBuffers ) == -1 ) { - std::string error = Mix_GetError(); - Logger::write(Logger::ZONE_ERROR, "SDL", "Audio initialize failed: " + error); + std::string error = Mix_GetError( ); + Logger::write( Logger::ZONE_ERROR, "SDL", "Audio initialize failed: " + error ); retVal = false; } return retVal; + } -bool SDL::deInitialize() -{ - std::string error = SDL_GetError(); - Logger::write(Logger::ZONE_INFO, "SDL", "DeInitializing"); - Mix_CloseAudio(); - Mix_Quit(); - if(mutex_) +// Deinitialize SDL +bool SDL::deInitialize( ) +{ + std::string error = SDL_GetError( ); + Logger::write( Logger::ZONE_INFO, "SDL", "DeInitializing" ); + + Mix_CloseAudio( ); + Mix_Quit( ); + + if ( mutex_ ) { SDL_DestroyMutex(mutex_); mutex_ = NULL; } - if(renderer_) + if ( renderer_ ) { SDL_DestroyRenderer(renderer_); renderer_ = NULL; } - if(window_) + if ( window_ ) { SDL_DestroyWindow(window_); window_ = NULL; } - SDL_ShowCursor(SDL_TRUE); + SDL_ShowCursor( SDL_TRUE ); - SDL_Quit(); + SDL_Quit( ); return true; } -SDL_Renderer* SDL::getRenderer() + +// Get the renderer +SDL_Renderer* SDL::getRenderer( ) { return renderer_; } -SDL_mutex* SDL::getMutex() + +// Get the mutex +SDL_mutex* SDL::getMutex( ) { return mutex_; } -SDL_Window* SDL::getWindow() + +// Get the window +SDL_Window* SDL::getWindow( ) { return window_; } -bool SDL::renderCopy(SDL_Texture *texture, float alpha, SDL_Rect *src, SDL_Rect *dest, ViewInfo &viewInfo) + +// Render a copy of a texture +bool SDL::renderCopy( SDL_Texture *texture, float alpha, SDL_Rect *src, SDL_Rect *dest, ViewInfo &viewInfo ) { SDL_Rect srcRect; @@ -281,7 +288,7 @@ bool SDL::renderCopy(SDL_Texture *texture, float alpha, SDL_Rect *src, SDL_Rect dstRect.w = dest->w; dstRect.h = dest->h; - if(fullscreen_) + if ( fullscreen_ ) { dstRect.x = dest->x + (displayWidth_ - windowWidth_)/2; dstRect.y = dest->y + (displayHeight_ - windowHeight_)/2; @@ -312,8 +319,8 @@ bool SDL::renderCopy(SDL_Texture *texture, float alpha, SDL_Rect *src, SDL_Rect } // Define the scale - scaleX = (dstRect.w > 0) ? static_cast(srcRect.w) / static_cast(dstRect.w) : 0.0; - scaleY = (dstRect.h > 0) ? static_cast(srcRect.h) / static_cast(dstRect.h) : 0.0; + scaleX = (dstRect.w > 0) ? static_cast( srcRect.w ) / static_cast( dstRect.w ) : 0.0; + scaleY = (dstRect.h > 0) ? static_cast( srcRect.h ) / static_cast( dstRect.h ) : 0.0; // Make a copy srcRectCopy.x = srcRect.x; @@ -326,77 +333,77 @@ bool SDL::renderCopy(SDL_Texture *texture, float alpha, SDL_Rect *src, SDL_Rect dstRectCopy.h = dstRect.h; // If a container has been defined, limit the display to the container boundaries. - if (viewInfo.ContainerWidth > 0 && viewInfo.ContainerHeight > 0 && - dstRectCopy.w > 0 && dstRectCopy.h > 0) + if ( viewInfo.ContainerWidth > 0 && viewInfo.ContainerHeight > 0 && + dstRectCopy.w > 0 && dstRectCopy.h > 0 ) { // Correct if the image falls to the left of the container - if (dstRect.x < viewInfo.ContainerX) + if ( dstRect.x < viewInfo.ContainerX ) { - dstRect.x = static_cast(viewInfo.ContainerX); + dstRect.x = static_cast( viewInfo.ContainerX ); dstRect.w = dstRectCopy.w + dstRectCopy.x - dstRect.x; srcRect.x = srcRectCopy.x + srcRectCopy.w * (dstRect.x - dstRectCopy.x) / dstRectCopy.w; } // Correct if the image falls to the right of the container - if ((dstRectCopy.x + dstRectCopy.w) > (viewInfo.ContainerX + viewInfo.ContainerWidth)) + if ( (dstRectCopy.x + dstRectCopy.w) > (viewInfo.ContainerX + viewInfo.ContainerWidth) ) { - dstRect.w = static_cast(viewInfo.ContainerX + viewInfo.ContainerWidth) - dstRect.x; + dstRect.w = static_cast( viewInfo.ContainerX + viewInfo.ContainerWidth ) - dstRect.x; } // Correct if the image falls to the top of the container - if (dstRect.y < viewInfo.ContainerY) + if ( dstRect.y < viewInfo.ContainerY ) { - dstRect.y = static_cast(viewInfo.ContainerY); + dstRect.y = static_cast( viewInfo.ContainerY ); dstRect.h = dstRectCopy.h + dstRectCopy.y - dstRect.y; srcRect.y = srcRectCopy.y + srcRectCopy.h * (dstRect.y - dstRectCopy.y) / dstRectCopy.h; } // Correct if the image falls to the bottom of the container - if ((dstRectCopy.y + dstRectCopy.h) > (viewInfo.ContainerY + viewInfo.ContainerHeight)) + if ( (dstRectCopy.y + dstRectCopy.h) > (viewInfo.ContainerY + viewInfo.ContainerHeight) ) { - dstRect.h = static_cast(viewInfo.ContainerY + viewInfo.ContainerHeight) - dstRect.y; + dstRect.h = static_cast( viewInfo.ContainerY + viewInfo.ContainerHeight ) - dstRect.y; } // Define source width and height - srcRect.w = static_cast(dstRect.w * scaleX); - srcRect.h = static_cast(dstRect.h * scaleY); + srcRect.w = static_cast( dstRect.w * scaleX ); + srcRect.h = static_cast( dstRect.h * scaleY ); } - SDL_SetTextureAlphaMod(texture, static_cast(alpha * 255)); - SDL_RenderCopyEx(getRenderer(), texture, &srcRect, &dstRect, viewInfo.Angle, NULL, SDL_FLIP_NONE); + SDL_SetTextureAlphaMod( texture, static_cast( alpha * 255 ) ); + SDL_RenderCopyEx( getRenderer( ), texture, &srcRect, &dstRect, viewInfo.Angle, NULL, SDL_FLIP_NONE ); - if (viewInfo.Reflection == "top") + if ( viewInfo.Reflection == "top" ) { - dstRect.h = static_cast(static_cast(dstRect.h) * viewInfo.ReflectionScale); + dstRect.h = static_cast( static_cast(dstRect.h ) * viewInfo.ReflectionScale); dstRect.y = dstRect.y - dstRect.h - viewInfo.ReflectionDistance; - SDL_SetTextureAlphaMod(texture, static_cast(viewInfo.ReflectionAlpha * alpha * 255)); - SDL_RenderCopyEx(getRenderer(), texture, src, &dstRect, viewInfo.Angle, NULL, SDL_FLIP_VERTICAL); + SDL_SetTextureAlphaMod( texture, static_cast( viewInfo.ReflectionAlpha * alpha * 255 ) ); + SDL_RenderCopyEx( getRenderer( ), texture, src, &dstRect, viewInfo.Angle, NULL, SDL_FLIP_VERTICAL ); } - if (viewInfo.Reflection == "bottom") + if ( viewInfo.Reflection == "bottom" ) { dstRect.y = dstRect.y + dstRect.h + viewInfo.ReflectionDistance; - dstRect.h = static_cast(static_cast(dstRect.h) * viewInfo.ReflectionScale); - SDL_SetTextureAlphaMod(texture, static_cast(viewInfo.ReflectionAlpha * alpha * 255)); - SDL_RenderCopyEx(getRenderer(), texture, src, &dstRect, viewInfo.Angle, NULL, SDL_FLIP_VERTICAL); + dstRect.h = static_cast( static_cast(dstRect.h ) * viewInfo.ReflectionScale); + SDL_SetTextureAlphaMod( texture, static_cast( viewInfo.ReflectionAlpha * alpha * 255 ) ); + SDL_RenderCopyEx( getRenderer( ), texture, src, &dstRect, viewInfo.Angle, NULL, SDL_FLIP_VERTICAL ); } - if (viewInfo.Reflection == "left") + if ( viewInfo.Reflection == "left" ) { - dstRect.w = static_cast(static_cast(dstRect.w) * viewInfo.ReflectionScale); + dstRect.w = static_cast( static_cast(dstRect.w ) * viewInfo.ReflectionScale); dstRect.x = dstRect.x - dstRect.w - viewInfo.ReflectionDistance; - SDL_SetTextureAlphaMod(texture, static_cast(viewInfo.ReflectionAlpha * alpha * 255)); - SDL_RenderCopyEx(getRenderer(), texture, src, &dstRect, viewInfo.Angle, NULL, SDL_FLIP_HORIZONTAL); + SDL_SetTextureAlphaMod( texture, static_cast( viewInfo.ReflectionAlpha * alpha * 255 ) ); + SDL_RenderCopyEx( getRenderer( ), texture, src, &dstRect, viewInfo.Angle, NULL, SDL_FLIP_HORIZONTAL ); } - if (viewInfo.Reflection == "right") + if ( viewInfo.Reflection == "right" ) { dstRect.x = dstRect.x + dstRect.w + viewInfo.ReflectionDistance; - dstRect.w = static_cast(static_cast(dstRect.w) * viewInfo.ReflectionScale); - SDL_SetTextureAlphaMod(texture, static_cast(viewInfo.ReflectionAlpha * alpha * 255)); - SDL_RenderCopyEx(getRenderer(), texture, src, &dstRect, viewInfo.Angle, NULL, SDL_FLIP_HORIZONTAL); + dstRect.w = static_cast( static_cast(dstRect.w ) * viewInfo.ReflectionScale); + SDL_SetTextureAlphaMod( texture, static_cast( viewInfo.ReflectionAlpha * alpha * 255 ) ); + SDL_RenderCopyEx( getRenderer( ), texture, src, &dstRect, viewInfo.Angle, NULL, SDL_FLIP_HORIZONTAL ); } return true; diff --git a/RetroFE/Source/SDL.h b/RetroFE/Source/SDL.h index 87b20c6..033692e 100644 --- a/RetroFE/Source/SDL.h +++ b/RetroFE/Source/SDL.h @@ -14,42 +14,45 @@ * along with RetroFE. If not, see . */ #pragma once + + #include #include #include "Graphics/ViewInfo.h" -// todo: this wrapper could be cleaned up + class Configuration; + class SDL { public: - static bool initialize(Configuration &config); - static bool deInitialize(); - static SDL_Renderer *getRenderer(); - static SDL_mutex *getMutex(); - static SDL_Window *getWindow(); - static bool renderCopy(SDL_Texture *texture, float alpha, SDL_Rect *src, SDL_Rect *dest, ViewInfo &viewInfo); - static int getWindowWidth() + static bool initialize( Configuration &config ); + static bool deInitialize( ); + static SDL_Renderer *getRenderer( ); + static SDL_mutex *getMutex( ); + static SDL_Window *getWindow( ); + static bool renderCopy( SDL_Texture *texture, float alpha, SDL_Rect *src, SDL_Rect *dest, ViewInfo &viewInfo ); + static int getWindowWidth( ) { return windowWidth_; } - static int getWindowHeight() + static int getWindowHeight( ) { return windowHeight_; } - static bool isFullscreen() + static bool isFullscreen( ) { return fullscreen_; } private: - static SDL_Window *window_; + static SDL_Window *window_; static SDL_Renderer *renderer_; - static SDL_mutex *mutex_; - static int displayWidth_; - static int displayHeight_; - static int windowWidth_; - static int windowHeight_; - static bool fullscreen_; + static SDL_mutex *mutex_; + static int displayWidth_; + static int displayHeight_; + static int windowWidth_; + static int windowHeight_; + static bool fullscreen_; }; diff --git a/RetroFE/Source/Version.cpp b/RetroFE/Source/Version.cpp index 90e9539..4b17a6e 100644 --- a/RetroFE/Source/Version.cpp +++ b/RetroFE/Source/Version.cpp @@ -14,16 +14,17 @@ * along with RetroFE. If not, see . */ + #include "Version.h" #include std::string retrofe_version_major = "0"; std::string retrofe_version_minor = "8"; -std::string retrofe_version_build = "7"; +std::string retrofe_version_build = "8"; -std::string Version::getString() +std::string Version::getString( ) { std::string return_string = retrofe_version_major + "." + retrofe_version_minor + "." + retrofe_version_build; return return_string; diff --git a/RetroFE/Source/Version.h b/RetroFE/Source/Version.h index 4595889..05b3339 100644 --- a/RetroFE/Source/Version.h +++ b/RetroFE/Source/Version.h @@ -15,10 +15,12 @@ */ #pragma once + #include + class Version { public: - static std::string getString(); + static std::string getString( ); };