Browse Source

Blit: Fix scaled output handling

Fixes #594
pull/595/head
Gleb Mazovetskiy 6 years ago
parent
commit
114a166a01
  1. 18
      SourceS/sdl2_to_1_2_backports.h
  2. 9
      SourceS/sdl_compat.h
  3. 71
      SourceX/dx.cpp

18
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;
}
/**

9
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

71
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);
}
/**

Loading…
Cancel
Save