diff --git a/RetroFE/Build/CHANGELOG b/RetroFE/Build/CHANGELOG index cda049630..6e74b3eda 100644 --- a/RetroFE/Build/CHANGELOG +++ b/RetroFE/Build/CHANGELOG @@ -41,3 +41,5 @@ v0.10.34.1 - added ability to specify SDL render driver to use, SDLRenderDriver in settings.conf. Acceptable values are direct3d11, opengl (inigomontoya) - added logging to report the SDL render driver being used (inigomontoya) - changed SDL screen config logic to iterate over number of screens preventing iterations beyond number of found displays (inigomontoya) + - defined as std:min(numScreens_, numDisplays_) and replaced all instances of that with screenCount_ (inigomontoya) + - added onMenuFastScroll layout event that triggers when menu starts scrolling fast. use onMenuIdle as exit event (monkofthefunk) diff --git a/RetroFE/Source/Graphics/Component/Component.cpp b/RetroFE/Source/Graphics/Component/Component.cpp index cfeb2da6f..e86deac6a 100644 --- a/RetroFE/Source/Graphics/Component/Component.cpp +++ b/RetroFE/Source/Graphics/Component/Component.cpp @@ -154,56 +154,56 @@ void Component::update(float dt) { elapsedTweenTime_ += dt; - if ( animationRequested_ && animationRequestedType_ != "" ) - { - Animation *newTweens; - // Check if this component is part of an active scrolling list - if ( menuIndex_ >= MENU_INDEX_HIGH ) - { - // Check for animation at index i - newTweens = tweens_->getAnimation( animationRequestedType_, MENU_INDEX_HIGH ); - if ( !(newTweens && newTweens->size() > 0) ) - { - // Check for animation at the current menuIndex - newTweens = tweens_->getAnimation( animationRequestedType_, menuIndex_ - MENU_INDEX_HIGH); - } - } - else - { - // Check for animation at the current menuIndex - newTweens = tweens_->getAnimation( animationRequestedType_, menuIndex_ ); - } - if (newTweens && newTweens->size() > 0) - { - animationType_ = animationRequestedType_; - currentTweens_ = newTweens; - currentTweenIndex_ = 0; - elapsedTweenTime_ = 0; - storeViewInfo_ = baseViewInfo; - currentTweenComplete_ = false; - } - animationRequested_ = false; - } + if (animationRequested_) { + if (animationRequestedType_ != "") + { + Animation* newTweens; + // Check if this component is part of an active scrolling list + if (menuIndex_ >= MENU_INDEX_HIGH) + { + // Check for animation at index i + newTweens = tweens_->getAnimation(animationRequestedType_, MENU_INDEX_HIGH); + if (!(newTweens && newTweens->size() > 0)) + { + // Check for animation at the current menuIndex + newTweens = tweens_->getAnimation(animationRequestedType_, menuIndex_ - MENU_INDEX_HIGH); + } + } + else + { + // Check for animation at the current menuIndex + newTweens = tweens_->getAnimation(animationRequestedType_, menuIndex_); + } + if (newTweens && newTweens->size() > 0) + { + animationType_ = animationRequestedType_; + currentTweens_ = newTweens; + currentTweenIndex_ = 0; + elapsedTweenTime_ = 0; + storeViewInfo_ = baseViewInfo; + currentTweenComplete_ = false; + } + animationRequested_ = false; + } - if (tweens_ && currentTweenComplete_) - { - animationType_ = "idle"; - currentTweens_ = tweens_->getAnimation( "idle", menuIndex_ ); - if ( currentTweens_ && currentTweens_->size( ) == 0 && !page.isMenuScrolling( ) ) + // perform idle animation + if (tweens_ && currentTweenComplete_) { - currentTweens_ = tweens_->getAnimation( "menuIdle", menuIndex_ ); - if ( currentTweens_ && currentTweens_->size( ) > 0 ) + animationType_ = "idle"; + currentTweens_ = tweens_->getAnimation("idle", menuIndex_); + if (currentTweens_ && currentTweens_->size() == 0 && !page.isMenuScrolling()) { - currentTweens_ = currentTweens_; + currentTweens_ = tweens_->getAnimation("menuIdle", menuIndex_); } + currentTweenIndex_ = 0; + elapsedTweenTime_ = 0; + storeViewInfo_ = baseViewInfo; + currentTweenComplete_ = false; + animationRequested_ = false; } - currentTweenIndex_ = 0; - elapsedTweenTime_ = 0; - storeViewInfo_ = baseViewInfo; - currentTweenComplete_ = false; - animationRequested_ = false; } + // reset currentTweenComplete_ = animate(); if ( currentTweenComplete_ ) { diff --git a/RetroFE/Source/Graphics/Component/Image.cpp b/RetroFE/Source/Graphics/Component/Image.cpp index 0350692fb..b9319f202 100644 --- a/RetroFE/Source/Graphics/Component/Image.cpp +++ b/RetroFE/Source/Graphics/Component/Image.cpp @@ -58,7 +58,8 @@ void Image::allocateGraphicsMemory() texture_ = IMG_LoadTexture(SDL::getRenderer(baseViewInfo.Monitor), file_.c_str()); if (!texture_ && altFile_ != "") { - texture_ = IMG_LoadTexture(SDL::getRenderer(baseViewInfo.Monitor), altFile_.c_str()); + file_ = altFile_; + texture_ = IMG_LoadTexture(SDL::getRenderer(baseViewInfo.Monitor), file_.c_str()); } if (texture_ != NULL) @@ -90,6 +91,6 @@ void Image::draw() rect.h = static_cast(baseViewInfo.ScaledHeight()); rect.w = static_cast(baseViewInfo.ScaledWidth()); - SDL::renderCopy(texture_, baseViewInfo.Alpha, NULL, &rect, baseViewInfo, page.getLayoutWidth(baseViewInfo.Monitor), page.getLayoutHeight(baseViewInfo.Monitor)); + SDL::renderCopy(texture_, baseViewInfo.Alpha, NULL, &rect, baseViewInfo, page.getLayoutWidth(baseViewInfo.Monitor), page.getLayoutHeight(baseViewInfo.Monitor), file_.c_str()); } } diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index a3caa8d0f..263213fea 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -1074,7 +1074,16 @@ void ScrollingList::updateScrollPeriod( ) if ( scrollPeriod_ < minScrollTime_ ) { scrollPeriod_ = minScrollTime_; + menuFastScroll_ = true; } + else { + menuFastScroll_ = false; + } +} + +bool ScrollingList::isMenuScrollingFast() +{ + return menuFastScroll_; } diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.h b/RetroFE/Source/Graphics/Component/ScrollingList.h index 5cfc83ddf..ad2869d2c 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.h +++ b/RetroFE/Source/Graphics/Component/ScrollingList.h @@ -107,6 +107,7 @@ class ScrollingList : public Component void allocateSpritePoints( ); void resetScrollPeriod( ); void updateScrollPeriod( ); + bool isMenuScrollingFast(); void scroll( bool forward ); bool isPlaylist(); private: @@ -119,6 +120,7 @@ class ScrollingList : public Component bool commonMode_; bool playlistType_; bool selectedImage_; + bool menuFastScroll_ = false; std::vector *spriteList_; std::vector *scrollPoints_; diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index d1a573e89..ef23ecea4 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -45,6 +45,7 @@ Page::Page(Configuration &config, int layoutWidth, int layoutHeight) , anActiveMenu_(NULL) , fromPreviousPlaylist (false) , fromPlaylistNav(false) + , scrollFastActive_(false) { for (int i = 0; i < SDL::getNumScreens(); i++) { @@ -326,6 +327,8 @@ bool Page::isMenuIdle() } } } + scrollFastActive_ = !idle; + return idle; } @@ -603,7 +606,6 @@ void Page::menuJumpExit() triggerEventOnAllMenus("menuJumpExit"); } - void Page::attractEnter() { triggerEventOnAllMenus("attractEnter"); @@ -619,7 +621,6 @@ void Page::attractExit() triggerEventOnAllMenus("attractExit"); } - void Page::jukeboxJump() { triggerEventOnAllMenus("jukeboxJump"); @@ -1441,12 +1442,26 @@ void Page::reallocateMenuSpritePoints(bool updatePlaylistMenu) } } - bool Page::isMenuScrolling() { return scrollActive_; } +bool Page::isMenuScrollingFast() +{ + bool retVal = false; + + for (std::vector::iterator it = activeMenu_.begin(); it != activeMenu_.end(); it++) + { + ScrollingList* menu = *it; + if (menu) + { + retVal |= menu->isMenuScrollingFast(); + } + } + + return retVal; +} bool Page::isPlaying() { @@ -1479,8 +1494,15 @@ void Page::updateScrollPeriod() for(std::vector::iterator it = activeMenu_.begin(); it != activeMenu_.end(); it++) { ScrollingList *menu = *it; - if(menu) menu->updateScrollPeriod(); + if (menu) { + menu->updateScrollPeriod(); + if (!scrollFastActive_ && menu->isMenuScrollingFast()) { + scrollFastActive_ = true; + triggerEventOnAllMenus("menuFastScroll"); + } + } } + return; } diff --git a/RetroFE/Source/Graphics/Page.h b/RetroFE/Source/Graphics/Page.h index 70e3b5a10..522e16de8 100644 --- a/RetroFE/Source/Graphics/Page.h +++ b/RetroFE/Source/Graphics/Page.h @@ -130,6 +130,7 @@ class Page void togglePlaylist(); void reallocateMenuSpritePoints(bool updatePlaylistMenu = true); bool isMenuScrolling(); + bool isMenuScrollingFast(); bool isPlaying(); void resetScrollPeriod(); void updateScrollPeriod(); @@ -189,6 +190,7 @@ class Page std::map lastPlaylistOffsets_; bool scrollActive_; + bool scrollFastActive_; Item *selectedItem_; Text *textStatusComponent_; diff --git a/RetroFE/Source/Graphics/PageBuilder.cpp b/RetroFE/Source/Graphics/PageBuilder.cpp index 0272cb035..776879088 100644 --- a/RetroFE/Source/Graphics/PageBuilder.cpp +++ b/RetroFE/Source/Graphics/PageBuilder.cpp @@ -896,6 +896,7 @@ AnimationEvents *PageBuilder::createTweenInstance(xml_node<> *componentXml) buildTweenSet(tweens, componentXml, "onAttractExit", "attractExit"); buildTweenSet(tweens, componentXml, "onJukeboxJump", "jukeboxJump"); + buildTweenSet(tweens, componentXml, "onMenuFastScroll", "menuFastScroll"); buildTweenSet(tweens, componentXml, "onMenuActionInputEnter", "menuActionInputEnter"); buildTweenSet(tweens, componentXml, "onMenuActionInputExit", "menuActionInputExit"); buildTweenSet(tweens, componentXml, "onMenuActionSelectEnter", "menuActionSelectEnter"); @@ -1316,6 +1317,8 @@ void PageBuilder::buildViewInfo(xml_node<> *componentXml, ViewInfo &info, xml_no xml_attribute<> *containerHeight = findAttribute(componentXml, "containerHeight", defaultXml); xml_attribute<> *monitor = findAttribute(componentXml, "monitor", defaultXml); xml_attribute<> *volume = findAttribute(componentXml, "volume", defaultXml); + xml_attribute<>* blur = findAttribute(componentXml, "blur", defaultXml); + info.X = getHorizontalAlignment(x, 0); info.Y = getVerticalAlignment(y, 0); @@ -1358,6 +1361,7 @@ void PageBuilder::buildViewInfo(xml_node<> *componentXml, ViewInfo &info, xml_no info.ContainerHeight = containerHeight ? Utils::convertFloat(containerHeight->value()) : -1.f; info.Monitor = monitor ? Utils::convertInt(monitor->value()) : 0; info.Volume = volume ? Utils::convertFloat(volume->value()) : 1.f; + info.Blur = blur ? Utils::convertInt(blur->value()) : 0; if(fontColor) { diff --git a/RetroFE/Source/Graphics/ViewInfo.h b/RetroFE/Source/Graphics/ViewInfo.h index e1ebbdfcd..c4bdde20e 100644 --- a/RetroFE/Source/Graphics/ViewInfo.h +++ b/RetroFE/Source/Graphics/ViewInfo.h @@ -73,6 +73,7 @@ class ViewInfo float ContainerHeight; int Monitor; float Volume; + int Blur; private: float AbsoluteHeight() const; diff --git a/RetroFE/Source/SDL.cpp b/RetroFE/Source/SDL.cpp index 0990b6d43..39551b54c 100644 --- a/RetroFE/Source/SDL.cpp +++ b/RetroFE/Source/SDL.cpp @@ -20,6 +20,7 @@ #include "Utility/Log.h" #include #include "Utility/Utils.h" +#include std::vector SDL::window_; std::vector SDL::renderer_; @@ -394,7 +395,7 @@ SDL_Window* SDL::getWindow( int index ) // Render a copy of a texture -bool SDL::renderCopy( SDL_Texture *texture, float alpha, SDL_Rect *src, SDL_Rect *dest, ViewInfo &viewInfo, int layoutWidth, int layoutHeight ) +bool SDL::renderCopy( SDL_Texture *texture, float alpha, SDL_Rect *src, SDL_Rect *dest, ViewInfo &viewInfo, int layoutWidth, int layoutHeight, const char* fileName) { // Skip rendering if the object is invisible anyway or if renderer does not exist @@ -528,6 +529,74 @@ bool SDL::renderCopy( SDL_Texture *texture, float alpha, SDL_Rect *src, SDL_Rect } + // Blur + if (viewInfo.Blur) { + SDL_Surface* imageSurface = IMG_Load(fileName); + int blur_extent = viewInfo.Blur; + for (int y = 0; y < imageSurface->h; y++) + { + for (int x = 0; x < (imageSurface->pitch / 4); x++) + { + Uint32 color = ((Uint32*)imageSurface->pixels)[(y * (imageSurface->pitch / 4)) + x]; + + //SDL_GetRGBA() is a method for getting color + //components from a 32 bit color + Uint8 r = 0, g = 0, b = 0, a = 0; + SDL_GetRGBA(color, imageSurface->format, &r, &g, &b, &a); + + Uint32 rb = 0, gb = 0, bb = 0, ab = 0; + + //Within the two for-loops below, colors of adjacent pixels are added up + + for (int yo = -blur_extent; yo <= blur_extent; yo++) + { + for (int xo = -blur_extent; xo <= blur_extent; xo++) { + if (y + yo >= 0 && x + xo >= 0 + && y + yo < imageSurface->h && x + xo < (imageSurface->pitch / 4) + ) + { + Uint32 colOth = ((Uint32*)imageSurface->pixels)[((y + yo) + * (imageSurface->pitch / 4)) + (x + xo)]; + + Uint8 ro = 0, go = 0, bo = 0, ao = 0; + SDL_GetRGBA(colOth, imageSurface->format, &ro, &go, &bo, &ao); + + rb += ro; + gb += go; + bb += bo; + ab += ao; + } + } + } + + //The sum is then, divided by the total number of + //pixels present in a block of blur radius + + //For blur_extent 1, it will be 9 + //For blur_extent 2, it will be 25 + //and so on... + + //In this way, we are getting the average of + //all the pixels in a block of blur radius + + //(((blur_extent * 2) + 1) * ((blur_extent * 2) + 1)) calculates + //the total number of pixels present in a block of blur radius + + r = (Uint8)(rb / (((blur_extent * 2) + 1) * ((blur_extent * 2) + 1))); + g = (Uint8)(gb / (((blur_extent * 2) + 1) * ((blur_extent * 2) + 1))); + b = (Uint8)(bb / (((blur_extent * 2) + 1) * ((blur_extent * 2) + 1))); + a = (Uint8)(ab / (((blur_extent * 2) + 1) * ((blur_extent * 2) + 1))); + + //Bit shifting color bits to form a 32 bit proper colour + color = (r) | (g << 8) | (b << 16) | (a << 24); + ((Uint32*)imageSurface->pixels)[(y * (imageSurface->pitch / 4)) + x] = color; + } + } + SDL_UpperBlit(imageSurface, &srcRect, NULL, &dstRect); + SDL_UpdateWindowSurface(getWindow(viewInfo.Monitor)); + } + + // Angle double angle = viewInfo.Angle; if ( !mirror_[viewInfo.Monitor] ) angle += rotation_[viewInfo.Monitor] * 90; diff --git a/RetroFE/Source/SDL.h b/RetroFE/Source/SDL.h index 2db0678d4..e0e56366d 100644 --- a/RetroFE/Source/SDL.h +++ b/RetroFE/Source/SDL.h @@ -33,7 +33,7 @@ class SDL static SDL_Renderer *getRenderer( int index ); static SDL_mutex *getMutex( ); static SDL_Window *getWindow( int index ); - static bool renderCopy( SDL_Texture *texture, float alpha, SDL_Rect *src, SDL_Rect *dest, ViewInfo &viewInfo, int layoutWidth, int layoutHeight ); + static bool renderCopy( SDL_Texture *texture, float alpha, SDL_Rect *src, SDL_Rect *dest, ViewInfo &viewInfo, int layoutWidth, int layoutHeight, const char* fileName = ""); static int getWindowWidth( int index ) { return (index < screenCount_ ? windowWidth_[index] : windowWidth_[0]);