From 817ee4122a2efbd47595db20f617c2f5ca57eb9e Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Mon, 28 Jun 2021 20:45:52 +0200 Subject: [PATCH] Fixed an issue where horizontally scrolling game names would sometimes flicker. Also cleaned up some code. --- es-core/src/components/TextListComponent.h | 59 ++++++++++++---------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/es-core/src/components/TextListComponent.h b/es-core/src/components/TextListComponent.h index 0185a47cd..0eec010a6 100644 --- a/es-core/src/components/TextListComponent.h +++ b/es-core/src/components/TextListComponent.h @@ -105,6 +105,7 @@ private: int mMarqueeOffset; int mMarqueeOffset2; int mMarqueeTime; + bool mMarqueeScroll; Alignment mAlignment; float mHorizontalMargin; @@ -133,8 +134,9 @@ TextListComponent::TextListComponent(Window* window) : mMarqueeOffset = 0; mMarqueeOffset2 = 0; mMarqueeTime = 0; + mMarqueeScroll = false; - mHorizontalMargin = 0; + mHorizontalMargin = 0.0f; mAlignment = ALIGN_CENTER; mFont = Font::get(FONT_SIZE_MEDIUM); @@ -153,17 +155,17 @@ TextListComponent::TextListComponent(Window* window) : template void TextListComponent::render(const Transform4x4f& parentTrans) { - Transform4x4f trans = parentTrans * getTransform(); - - std::shared_ptr& font = mFont; - if (size() == 0) return; - const float entrySize = std::max(font->getHeight(1.0), - static_cast(font->getSize())) * mLineSpacing; + Transform4x4f trans = parentTrans * getTransform(); + std::shared_ptr& font = mFont; int startEntry = 0; + float y = 0; + + const float entrySize = std::max(font->getHeight(1.0), + static_cast(font->getSize())) * mLineSpacing; // Number of entries that can fit on the screen simultaneously. int screenCount = static_cast(mSize.y() / entrySize + 0.5f); @@ -176,8 +178,6 @@ void TextListComponent::render(const Transform4x4f& parentTrans) startEntry = size() - screenCount; } - float y = 0; - int listCutoff = startEntry + screenCount; if (listCutoff > size()) listCutoff = size(); @@ -185,16 +185,15 @@ void TextListComponent::render(const Transform4x4f& parentTrans) // Draw selector bar. if (startEntry < listCutoff) { if (mSelectorImage.hasImage()) { - mSelectorImage.setPosition(0.f, - (mCursor - startEntry)*entrySize + mSelectorOffsetY, 0.f); + mSelectorImage.setPosition(0.0f, (mCursor - startEntry) * + entrySize + mSelectorOffsetY, 0.0f); mSelectorImage.render(trans); } else { Renderer::setMatrix(trans); Renderer::drawRect( 0.0f, - (mCursor - startEntry)*entrySize + - mSelectorOffsetY, + (mCursor - startEntry) * entrySize + mSelectorOffsetY, mSize.x(), mSelectorHeight, mSelectorColor, @@ -210,7 +209,7 @@ void TextListComponent::render(const Transform4x4f& parentTrans) } // Clip to inside margins. - Vector3f dim(mSize.x(), mSize.y(), 0); + Vector3f dim(mSize.x(), mSize.y(), 0.0f); dim = trans * dim - trans.translation(); Renderer::pushClipRect(Vector2i(static_cast(trans.translation().x() + mHorizontalMargin), static_cast(trans.translation().y())), @@ -240,7 +239,7 @@ void TextListComponent::render(const Transform4x4f& parentTrans) else entry.data.textCache->setColor(color); - Vector3f offset(0, y, 0); + Vector3f offset(0.0f, y, 0.0f); switch (mAlignment) { case ALIGN_LEFT: @@ -248,7 +247,7 @@ void TextListComponent::render(const Transform4x4f& parentTrans) break; case ALIGN_CENTER: offset[0] = static_cast((mSize.x() - - entry.data.textCache->metrics.size.x()) / 2); + entry.data.textCache->metrics.size.x()) / 2.0f); if (offset[0] < mHorizontalMargin) offset[0] = mHorizontalMargin; break; @@ -264,19 +263,23 @@ void TextListComponent::render(const Transform4x4f& parentTrans) Transform4x4f drawTrans = trans; // Currently selected item text might be scrolling. - if ((mCursor == i) && (mMarqueeOffset > 0)) - drawTrans.translate(offset - Vector3f(static_cast(mMarqueeOffset), 0, 0)); + if (mCursor == i && mMarqueeOffset > 0) + drawTrans.translate(offset - Vector3f(static_cast(mMarqueeOffset), 0.0f, 0.0f)); else drawTrans.translate(offset); + // Needed to avoid flickering when returning to the start position. + if (mMarqueeOffset == 0 && mMarqueeOffset2 == 0) + mMarqueeScroll = false; + Renderer::setMatrix(drawTrans); font->renderTextCache(entry.data.textCache.get()); - // Render currently selected item text again if marquee is - // scrolled far enough for it to repeat. - if ((mCursor == i) && (mMarqueeOffset2 < 0)) { + // Render currently selected row again if marquee is scrolled far enough for it to repeat. + if ((mCursor == i && mMarqueeOffset2 < 0) || (mCursor == i && mMarqueeScroll)) { + mMarqueeScroll = true; drawTrans = trans; - drawTrans.translate(offset - Vector3f(static_cast(mMarqueeOffset2), 0, 0)); + drawTrans.translate(offset - Vector3f(static_cast(mMarqueeOffset2), 0.0f, 0.0f)); Renderer::setMatrix(drawTrans); font->renderTextCache(entry.data.textCache.get()); } @@ -344,23 +347,23 @@ void TextListComponent::update(int deltaTime) if (!isScrolling() && size() > 0) { // Always reset the marquee offsets. - mMarqueeOffset = 0; + mMarqueeOffset = 0; mMarqueeOffset2 = 0; - // If we're not scrolling and this object's text goes outside our size, marquee it! + // If we're not scrolling and this object's text exceeds our size, then marquee it. const float textLength = mFont->sizeText(Utils::String::toUpper( mEntries.at(static_cast(mCursor)).name)).x(); - const float limit = mSize.x() - mHorizontalMargin * 2; + const float limit = mSize.x() - mHorizontalMargin * 2.0f; if (textLength > limit) { // Loop. // Pixels per second (based on nes-mini font at 1920x1080 to produce a speed of 200). const float speed = mFont->sizeText("ABCDEFGHIJKLMNOPQRSTUVWXYZ").x() * 0.247f; - const float delay = 3000; + const float delay = 3000.0f; const float scrollLength = textLength; const float returnLength = speed * 1.5f; - const float scrollTime = (scrollLength * 1000) / speed; - const float returnTime = (returnLength * 1000) / speed; + const float scrollTime = (scrollLength * 1000.0f) / speed; + const float returnTime = (returnLength * 1000.0f) / speed; const int maxTime = static_cast(delay + scrollTime + returnTime); mMarqueeTime += deltaTime;