Fix scroller draining off-screen on low frame rates
The scroller recycled at most one line per frame while movement was continuous (velocity * dt), so whenever a frame's displacement exceeded one line height the text block drifted toward the boundary and the screen drained with nothing replacing it. This surfaced on slower hardware / 60Hz panels (|move| > lineHeight) but not on fast machines. Recycle in a loop until every line that scrolled fully off-screen has a replacement, for both scroll directions. addLineAt() now returns whether a line was produced so the loop stops cleanly instead of losing lines.
This commit is contained in:
+21
-14
@@ -140,26 +140,32 @@ void ScrollerPage::update(float dt)
|
|||||||
|
|
||||||
if (velocity_ > 0.0f)
|
if (velocity_ > 0.0f)
|
||||||
{
|
{
|
||||||
// Lines move downward; recycle the bottom line off-screen and add a new
|
// Lines move downward. Recycle every line that scrolled fully off the
|
||||||
// line just above the top.
|
// bottom this frame (movement is continuous, so one frame can cover
|
||||||
ScrollerLine &back = lines_.back();
|
// several line heights) and add a replacement just above the top.
|
||||||
if (back.words[0].y > screenH_)
|
while (!lines_.empty() && lines_.back().words[0].y > screenH_)
|
||||||
{
|
{
|
||||||
float baseY = lines_.front().words[0].y - lineHeight_;
|
float baseY = lines_.front().words[0].y - lineHeight_;
|
||||||
lines_.pop_back();
|
lines_.pop_back();
|
||||||
addLineAt(baseY);
|
if (!addLineAt(baseY))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (velocity_ < 0.0f)
|
else if (velocity_ < 0.0f)
|
||||||
{
|
{
|
||||||
// Lines move upward; recycle the top line off-screen and add a new line
|
// Lines move upward. Recycle every line that scrolled fully off the top
|
||||||
// just below the bottom.
|
// this frame and add a replacement just below the bottom.
|
||||||
ScrollerLine &front = lines_.front();
|
while (!lines_.empty() &&
|
||||||
if (front.words[0].y + front.words[0].height < 0.0f)
|
lines_.front().words[0].y + lines_.front().words[0].height < 0.0f)
|
||||||
{
|
{
|
||||||
float baseY = lines_.back().words[0].y + lineHeight_;
|
float baseY = lines_.back().words[0].y + lineHeight_;
|
||||||
lines_.pop_front();
|
lines_.pop_front();
|
||||||
addLineAt(baseY);
|
if (!addLineAt(baseY))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -380,18 +386,18 @@ void ScrollerPage::prefillLines()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScrollerPage::addLineAt(float baseY)
|
bool ScrollerPage::addLineAt(float baseY)
|
||||||
{
|
{
|
||||||
if (streams_.empty() || !font_)
|
if (streams_.empty() || !font_)
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProclamationStream &stream = streams_[streamIndex_];
|
ProclamationStream &stream = streams_[streamIndex_];
|
||||||
if (stream.words.empty())
|
if (stream.words.empty())
|
||||||
{
|
{
|
||||||
advanceStream();
|
advanceStream();
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FibonacciLinePattern &pattern = patterns_[streamIndex_];
|
FibonacciLinePattern &pattern = patterns_[streamIndex_];
|
||||||
@@ -451,7 +457,7 @@ void ScrollerPage::addLineAt(float baseY)
|
|||||||
|
|
||||||
if (line.words.empty())
|
if (line.words.empty())
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
line.width = width;
|
line.width = width;
|
||||||
|
|
||||||
@@ -471,6 +477,7 @@ void ScrollerPage::addLineAt(float baseY)
|
|||||||
{
|
{
|
||||||
lines_.push_back(std::move(line));
|
lines_.push_back(std::move(line));
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScrollerPage::advanceStream()
|
void ScrollerPage::advanceStream()
|
||||||
|
|||||||
+1
-1
@@ -79,7 +79,7 @@ private:
|
|||||||
void destroyResources();
|
void destroyResources();
|
||||||
void rebuildWordTextures();
|
void rebuildWordTextures();
|
||||||
void prefillLines();
|
void prefillLines();
|
||||||
void addLineAt(float baseY);
|
bool addLineAt(float baseY);
|
||||||
void advanceStream();
|
void advanceStream();
|
||||||
void switchAudioForCurrentStream();
|
void switchAudioForCurrentStream();
|
||||||
void updateAutoVelocity(float dt);
|
void updateAutoVelocity(float dt);
|
||||||
|
|||||||
Reference in New Issue
Block a user