diff --git a/SourceX/DiabloUI/credits.cpp b/SourceX/DiabloUI/credits.cpp index 2dab2358e..76090d51c 100644 --- a/SourceX/DiabloUI/credits.cpp +++ b/SourceX/DiabloUI/credits.cpp @@ -5,6 +5,7 @@ #include "controls/menu_controls.h" #include "all.h" #include "display.h" +#include "sdl_ptrs.h" #include "DiabloUI/diabloui.h" #include "DiabloUI/credits_lines.h" @@ -35,19 +36,18 @@ struct CachedLine { CachedLine() { m_index = 0; - m_surface = NULL; palette_version = pal_surface_palette_version; } - CachedLine(std::size_t index, SDL_Surface *surface) + CachedLine(std::size_t index, SDLSurfaceUniquePtr surface) { m_index = index; - m_surface = surface; + m_surface = std::move(surface); palette_version = pal_surface_palette_version; } std::size_t m_index; - SDL_Surface *m_surface; + SDLSurfaceUniquePtr m_surface; unsigned int palette_version; }; @@ -68,40 +68,37 @@ CachedLine PrepareLine(std::size_t index) ++contents; const SDL_Color shadow_color = { 0, 0, 0, 0 }; - SDL_Surface *text = RenderText(contents, shadow_color); + SDLSurfaceUniquePtr text { RenderText(contents, shadow_color) }; // Precompose shadow and text: - SDL_Surface *surface = NULL; - if (text != NULL) { + SDLSurfaceUniquePtr surface; + if (text != nullptr) { // Set up the target surface to have 3 colors: mask, text, and shadow. - surface = SDL_CreateRGBSurfaceWithFormat(0, text->w + SHADOW_OFFSET_X, text->h + SHADOW_OFFSET_Y, 8, SDL_PIXELFORMAT_INDEX8); + surface = SDLSurfaceUniquePtr { SDL_CreateRGBSurfaceWithFormat(0, text->w + SHADOW_OFFSET_X, text->h + SHADOW_OFFSET_Y, 8, SDL_PIXELFORMAT_INDEX8) }; const SDL_Color mask_color = { 0, 255, 0, 0 }; // Any color different from both shadow and text const SDL_Color &text_color = palette->colors[224]; SDL_Color colors[3] = { mask_color, text_color, shadow_color }; - if (SDLC_SetSurfaceColors(surface, colors, 0, 3) <= -1) + if (SDLC_SetSurfaceColors(surface.get(), colors, 0, 3) <= -1) SDL_Log(SDL_GetError()); - SDLC_SetColorKey(surface, 0); + SDLC_SetColorKey(surface.get(), 0); // Blit the shadow first: SDL_Rect shadow_rect = { SHADOW_OFFSET_X, SHADOW_OFFSET_Y, 0, 0 }; - if (SDL_BlitSurface(text, NULL, surface, &shadow_rect) <= -1) + if (SDL_BlitSurface(text.get(), NULL, surface.get(), &shadow_rect) <= -1) ErrSdl(); // Change the text surface color and blit again: SDL_Color text_colors[2] = { mask_color, text_color }; - if (SDLC_SetSurfaceColors(text, text_colors, 0, 2) <= -1) + if (SDLC_SetSurfaceColors(text.get(), text_colors, 0, 2) <= -1) ErrSdl(); - SDLC_SetColorKey(text, 0); + SDLC_SetColorKey(text.get(), 0); - if (SDL_BlitSurface(text, NULL, surface, NULL) <= -1) + if (SDL_BlitSurface(text.get(), NULL, surface.get(), NULL) <= -1) ErrSdl(); - SDL_Surface *surface_ptr = surface; - ScaleSurfaceToOutput(&surface_ptr); - surface = surface_ptr; + surface = ScaleSurfaceToOutput(std::move(surface)); } - SDL_FreeSurface(text); - return CachedLine(index, surface); + return CachedLine(index, std::move(surface)); } class CreditsRenderer { @@ -120,11 +117,7 @@ public: ArtBackgroundWidescreen.Unload(); ArtBackground.Unload(); UnloadTtfFont(); - - for (size_t x = 0; x < lines_.size(); x++) { - if (lines_[x].m_surface) - SDL_FreeSurface(lines_[x].m_surface); - } + lines_.clear(); } void Render(); @@ -176,12 +169,11 @@ void CreditsRenderer::Render() Sint16 dest_y = UI_OFFSET_Y + VIEWPORT.y - (offset_y - lines_begin * 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) + if (line.m_surface == nullptr) continue; // Still fading in: the cached line was drawn with a different fade level. if (line.palette_version != pal_surface_palette_version) { - SDL_FreeSurface(line.m_surface); line = PrepareLine(line.m_index); } @@ -194,7 +186,7 @@ void CreditsRenderer::Render() ScaleOutputRect(&dst_rect); dst_rect.w = line.m_surface->w; dst_rect.h = line.m_surface->h; - if (SDL_BlitSurface(line.m_surface, NULL, DiabloUiSurface(), &dst_rect) < 0) + if (SDL_BlitSurface(line.m_surface.get(), NULL, DiabloUiSurface(), &dst_rect) < 0) ErrSdl(); } SDL_SetClipRect(DiabloUiSurface(), NULL); diff --git a/SourceX/display.cpp b/SourceX/display.cpp index 57e4d618c..6f46cd304 100644 --- a/SourceX/display.cpp +++ b/SourceX/display.cpp @@ -301,6 +301,17 @@ SDL_Surface *CreateScaledSurface(SDL_Surface *src) } // namespace #endif // USE_SDL1 +SDLSurfaceUniquePtr ScaleSurfaceToOutput(SDLSurfaceUniquePtr surface) +{ +#ifdef USE_SDL1 + SDL_Surface *ptr = surface.release(); + ScaleSurfaceToOutput(&ptr); + return SDLSurfaceUniquePtr{ptr}; +#else + return surface; +#endif +} + void ScaleSurfaceToOutput(SDL_Surface **surface) { #ifdef USE_SDL1 diff --git a/SourceX/display.h b/SourceX/display.h index 5e6af3fea..b5094eb80 100644 --- a/SourceX/display.h +++ b/SourceX/display.h @@ -3,6 +3,8 @@ #include #include "all.h" +#include "sdl_ptrs.h" + #include #include @@ -38,6 +40,10 @@ bool OutputRequiresScaling(); void ScaleOutputRect(SDL_Rect *rect); // If the output requires software scaling, replaces the given surface with a scaled one. +SDLSurfaceUniquePtr ScaleSurfaceToOutput(SDLSurfaceUniquePtr surface); + +// Prefer the SDLSurfaceUniquePtr version. +// FIXME: Delete this version. void ScaleSurfaceToOutput(SDL_Surface **surface); // Convert from output coordinates to logical (resolution-independent) coordinates.