diff --git a/SourceX/DiabloUI/credits.cpp b/SourceX/DiabloUI/credits.cpp index bbffc5bd5..00a1dde2b 100644 --- a/SourceX/DiabloUI/credits.cpp +++ b/SourceX/DiabloUI/credits.cpp @@ -26,18 +26,20 @@ const int LINE_H = 22; // a line is leaving the screen while another one is entering. #define MAX_VISIBLE_LINES ((VIEWPORT.h - 1) / LINE_H + 2) -struct SurfaceDeleter { - void operator()(SDL_Surface *surface) +struct CachedLine { + + CachedLine() { - SDL_FreeSurface(surface); + m_index = 0; + m_surface = NULL; + palette_version = pal_surface_palette_version; } -}; -struct CachedLine { CachedLine(std::size_t index, SDL_Surface *surface) { m_index = index; m_surface = surface; + palette_version = pal_surface_palette_version; } std::size_t m_index; @@ -94,79 +96,14 @@ CachedLine PrepareLine(std::size_t index) ScaleSurfaceToOutput(&surface_ptr); surface = surface_ptr; } - + SDL_FreeSurface(text); return CachedLine(index, surface); } -/** - * Similar to std::deque but simpler and backed by a single vector. - */ -class LinesBuffer { -public: - LinesBuffer(std::size_t capacity) - { - data_.reserve(capacity); - for (std::size_t i = 0; i < capacity; ++i) - data_.push_back(CachedLine(0, NULL)); - - start_ = 0; - end_ = 0; - empty_ = true; - } - - bool empty() const - { - return empty_; - } - - CachedLine &front() - { - return data_[start_]; - } - - CachedLine &back() - { - return data_[end_]; - } - - CachedLine &operator[](std::size_t i) - { - return data_[(start_ + i) % data_.size()]; - } - - std::size_t size() const - { - if (empty_) - return 0; - return start_ < end_ ? end_ - start_ : data_.size(); - } - - void pop_front() - { - start_ = (start_ + 1) % data_.size(); - if (start_ == end_) - empty_ = true; - } - - void push_back(CachedLine line) - { - end_ = (end_ + 1) % data_.size(); - data_[end_] = line; - empty_ = false; - } - -private: - std::size_t start_; - std::size_t end_; - bool empty_; - std::vector data_; -}; - class CreditsRenderer { public: CreditsRenderer() - : lines_(MAX_VISIBLE_LINES) { LoadBackgroundArt("ui_art\\credits.pcx"); LoadTtfFont(); @@ -179,6 +116,11 @@ public: { ArtBackground.Unload(); UnloadTtfFont(); + + for (int x = 0; x < lines_.size(); x++) { + if (lines_[x].m_surface) + SDL_FreeSurface(lines_[x].m_surface); + } } void Render(); @@ -189,7 +131,7 @@ public: } private: - LinesBuffer lines_; + std::vector lines_; bool finished_; Uint32 ticks_begin_; int prev_offset_y_; @@ -216,12 +158,8 @@ void CreditsRenderer::Render() return; } - while (!lines_.empty() && lines_.front().m_index != lines_begin) - lines_.pop_front(); - if (lines_.empty()) - lines_.push_back(PrepareLine(lines_begin)); - while (lines_.back().m_index + 1 != lines_end) - lines_.push_back(PrepareLine(lines_.back().m_index + 1)); + while (lines_end > lines_.size()) + lines_.push_back(PrepareLine(lines_.size())); SDL_Rect viewport = VIEWPORT; ScaleOutputRect(&viewport); @@ -229,14 +167,16 @@ void CreditsRenderer::Render() // We use unscaled coordinates for calculation throughout. Sint16 dest_y = VIEWPORT.y - (offset_y - lines_begin * LINE_H); - for (std::size_t i = 0; i < lines_.size(); ++i, dest_y += LINE_H) { + for (std::size_t i = lines_begin; i < lines_end; ++i, dest_y += LINE_H) { CachedLine &line = lines_[i]; if (line.m_surface == NULL) continue; // Still fading in: the cached line was drawn with a different fade level. - if (line.palette_version != pal_surface_palette_version) + if (line.palette_version != pal_surface_palette_version) { + SDL_FreeSurface(line.m_surface); line = PrepareLine(line.m_index); + } Sint16 dest_x = PANEL_LEFT + VIEWPORT.x + 31; if (CREDITS_LINES[line.m_index][0] == '\t')