diff --git a/SourceS/sdl2_to_1_2_backports.h b/SourceS/sdl2_to_1_2_backports.h index 97bb566e7..c35e13e8d 100644 --- a/SourceS/sdl2_to_1_2_backports.h +++ b/SourceS/sdl2_to_1_2_backports.h @@ -215,6 +215,21 @@ SDL_FreePalette(SDL_Palette *palette) SDL_free(palette); } +inline bool SDL_HasColorKey(SDL_Surface *surface) +{ + return (surface->flags & (SDL_SRCCOLORKEY | SDL_RLEACCELOK)) != 0; +} + +inline int SDL_GetColorKey(SDL_Surface *surface, Uint32 *colorkey) +{ + if (!SDL_HasColorKey(surface)) { + SDL_SetError("Surface doesn't have a colorkey"); + return -1; + } + *colorkey = surface->format->colorkey; + return 0; +} + //= Pixel formats #define SDL_PIXELFORMAT_INDEX8 1 @@ -259,7 +274,8 @@ inline void SDLBackport_PixelformatToMask(int pixelformat, Uint32 *flags, Uint32 */ inline bool SDLBackport_PixelFormatFormatEq(const SDL_PixelFormat *a, const SDL_PixelFormat *b) { - return a->BitsPerPixel == b->BitsPerPixel && (a->palette != nullptr) == (b->palette != nullptr); + return a->BitsPerPixel == b->BitsPerPixel && (a->palette != nullptr) == (b->palette != nullptr) + && a->Rmask == b->Rmask && a->Gmask == b->Gmask && a->Bmask == b->Bmask; } /** diff --git a/SourceS/sdl_compat.h b/SourceS/sdl_compat.h index 9c14ad16c..aac01ef42 100644 --- a/SourceS/sdl_compat.h +++ b/SourceS/sdl_compat.h @@ -14,6 +14,7 @@ #define SDLC_KEYSTATE_LEFT SDL_SCANCODE_LEFT #define SDLC_KEYSTATE_RIGHT SDL_SCANCODE_RIGHT #else +#include "sdl2_to_1_2_backports.h" #define SDLC_KEYSTATE_LEFTCTRL SDLK_LCTRL #define SDLC_KEYSTATE_RIGHTCTRL SDLK_RCTRL #define SDLC_KEYSTATE_LEFTSHIFT SDLK_LSHIFT @@ -26,6 +27,14 @@ #define SDLC_KEYSTATE_RIGHT SDLK_RIGHT #endif +inline bool SDLC_PixelFormatEq(const SDL_PixelFormat *a, const SDL_PixelFormat *b) { +#ifndef USE_SDL1 + return a->format == b->format; +#else + return SDLBackport_PixelFormatFormatEq(a, b); +#endif +} + inline const Uint8 *SDLC_GetKeyState() { #ifndef USE_SDL1 diff --git a/SourceX/dx.cpp b/SourceX/dx.cpp index 3fc9b044c..06da4adc3 100644 --- a/SourceX/dx.cpp +++ b/SourceX/dx.cpp @@ -173,40 +173,59 @@ void CreatePalette() void BltFast(SDL_Rect *src_rect, SDL_Rect *dst_rect) { - if (OutputRequiresScaling()) { - ScaleOutputRect(dst_rect); - // Convert from 8-bit to 32-bit - SDL_Surface *tmp = SDL_ConvertSurface(pal_surface, GetOutputSurface()->format, 0); - if (SDL_BlitScaled(tmp, src_rect, GetOutputSurface(), dst_rect) <= -1) { - SDL_FreeSurface(tmp); - ErrSdl(); - } - SDL_FreeSurface(tmp); - } else { - // Convert from 8-bit to 32-bit - if (SDL_BlitSurface(pal_surface, src_rect, GetOutputSurface(), dst_rect) <= -1) { - ErrSdl(); - } - } + Blit(pal_surface, src_rect, dst_rect); } void Blit(SDL_Surface *src, SDL_Rect *src_rect, SDL_Rect *dst_rect) { - if (OutputRequiresScaling()) { - ScaleOutputRect(dst_rect); - // Convert from 8-bit to 32-bit - SDL_Surface *tmp = SDL_ConvertSurface(src, GetOutputSurface()->format, 0); - if (SDL_BlitScaled(tmp, src_rect, GetOutputSurface(), dst_rect) <= -1) { - SDL_FreeSurface(tmp); + SDL_Surface *dst = GetOutputSurface(); + if (!OutputRequiresScaling()) { + if (SDL_BlitSurface(src, src_rect, dst, dst_rect) < 0) ErrSdl(); - } - SDL_FreeSurface(tmp); - } else { - // Convert from 8-bit to 32-bit - if (SDL_BlitSurface(src, src_rect, GetOutputSurface(), dst_rect) <= -1) { + return; + } + + ScaleOutputRect(dst_rect); + + // Same pixel format: We can call BlitScaled directly. + if (SDLC_PixelFormatEq(src->format, dst->format)) { + if (SDL_BlitScaled(src, src_rect, dst, dst_rect) < 0) + ErrSdl(); + return; + } + + // If the surface has a color key, we must stretch first and can then call BlitSurface. + if (SDL_HasColorKey(src)) { + SDL_Surface *stretched = SDL_CreateRGBSurface(SDL_SWSURFACE, dst_rect->w, dst_rect->h, src->format->BitsPerPixel, + src->format->Rmask, src->format->Gmask, src->format->BitsPerPixel, src->format->Amask); + Uint32 colorkey; + SDL_GetColorKey(src, &colorkey); + SDLC_SetColorKey(stretched, colorkey); +#ifndef USE_SDL1 + if (SDL_ISPIXELFORMAT_INDEXED(src->format->format)) + SDL_SetSurfacePalette(stretched, src->format->palette); +#else + if (src->format->palette != nullptr) + SDL_SetPalette(stretched, SDL_LOGPAL, src->format->palette->colors, 0, src->format->palette->ncolors); +#endif + SDL_Rect stretched_rect = { 0, 0, dst_rect->w, dst_rect->h }; + if (SDL_SoftStretch(src, src_rect, stretched, &stretched_rect) < 0 + || SDL_BlitSurface(stretched, &stretched_rect, dst, dst_rect) < 0) { + SDL_FreeSurface(stretched); ErrSdl(); } + SDL_FreeSurface(stretched); + return; + } + + // A surface with a non-output pixel format but without a color key needs scaling. + // We can convert the format and then call BlitScaled. + SDL_Surface *converted = SDL_ConvertSurface(src, dst->format, 0); + if (SDL_BlitScaled(converted, src_rect, dst, dst_rect) < 0) { + SDL_FreeSurface(converted); + ErrSdl(); } + SDL_FreeSurface(converted); } /**