early-access version 1667

This commit is contained in:
pineappleEA
2021-05-09 11:30:38 +02:00
parent 5e268d25d7
commit 5dbb928ff2
1069 changed files with 38272 additions and 14437 deletions

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -26,6 +26,7 @@
#include "SDL_RLEaccel_c.h"
#include "SDL_pixels_c.h"
#include "SDL_yuv_c.h"
#include "../render/SDL_sysrender.h"
/* Check to make sure we can safely check multiplication of surface w and pitch and it won't overflow size_t */
@@ -325,11 +326,12 @@ SDL_GetColorKey(SDL_Surface * surface, Uint32 * key)
return 0;
}
/* This is a fairly slow function to switch from colorkey to alpha */
/* This is a fairly slow function to switch from colorkey to alpha
NB: it doesn't handle bpp 1 or 3, because they have no alpha channel */
static void
SDL_ConvertColorkeyToAlpha(SDL_Surface * surface, SDL_bool ignore_alpha)
{
int x, y;
int x, y, bpp;
if (!surface) {
return;
@@ -340,82 +342,74 @@ SDL_ConvertColorkeyToAlpha(SDL_Surface * surface, SDL_bool ignore_alpha)
return;
}
bpp = surface->format->BytesPerPixel;
SDL_LockSurface(surface);
switch (surface->format->BytesPerPixel) {
case 2:
{
Uint16 *row, *spot;
Uint16 ckey = (Uint16) surface->map->info.colorkey;
Uint16 mask = (Uint16) (~surface->format->Amask);
if (bpp == 2) {
Uint16 *row, *spot;
Uint16 ckey = (Uint16) surface->map->info.colorkey;
Uint16 mask = (Uint16) (~surface->format->Amask);
/* Ignore, or not, alpha in colorkey comparison */
if (ignore_alpha) {
ckey &= mask;
row = (Uint16 *) surface->pixels;
for (y = surface->h; y--;) {
spot = row;
for (x = surface->w; x--;) {
if ((*spot & mask) == ckey) {
*spot &= mask;
}
++spot;
/* Ignore, or not, alpha in colorkey comparison */
if (ignore_alpha) {
ckey &= mask;
row = (Uint16 *) surface->pixels;
for (y = surface->h; y--;) {
spot = row;
for (x = surface->w; x--;) {
if ((*spot & mask) == ckey) {
*spot &= mask;
}
row += surface->pitch / 2;
++spot;
}
} else {
row = (Uint16 *) surface->pixels;
for (y = surface->h; y--;) {
spot = row;
for (x = surface->w; x--;) {
if (*spot == ckey) {
*spot &= mask;
}
++spot;
row += surface->pitch / 2;
}
} else {
row = (Uint16 *) surface->pixels;
for (y = surface->h; y--;) {
spot = row;
for (x = surface->w; x--;) {
if (*spot == ckey) {
*spot &= mask;
}
row += surface->pitch / 2;
++spot;
}
row += surface->pitch / 2;
}
}
break;
case 3:
/* FIXME */
break;
case 4:
{
Uint32 *row, *spot;
Uint32 ckey = surface->map->info.colorkey;
Uint32 mask = ~surface->format->Amask;
} else if (bpp == 4) {
Uint32 *row, *spot;
Uint32 ckey = surface->map->info.colorkey;
Uint32 mask = ~surface->format->Amask;
/* Ignore, or not, alpha in colorkey comparison */
if (ignore_alpha) {
ckey &= mask;
row = (Uint32 *) surface->pixels;
for (y = surface->h; y--;) {
spot = row;
for (x = surface->w; x--;) {
if ((*spot & mask) == ckey) {
*spot &= mask;
}
++spot;
/* Ignore, or not, alpha in colorkey comparison */
if (ignore_alpha) {
ckey &= mask;
row = (Uint32 *) surface->pixels;
for (y = surface->h; y--;) {
spot = row;
for (x = surface->w; x--;) {
if ((*spot & mask) == ckey) {
*spot &= mask;
}
row += surface->pitch / 4;
++spot;
}
} else {
row = (Uint32 *) surface->pixels;
for (y = surface->h; y--;) {
spot = row;
for (x = surface->w; x--;) {
if (*spot == ckey) {
*spot &= mask;
}
++spot;
row += surface->pitch / 4;
}
} else {
row = (Uint32 *) surface->pixels;
for (y = surface->h; y--;) {
spot = row;
for (x = surface->w; x--;) {
if (*spot == ckey) {
*spot &= mask;
}
row += surface->pitch / 4;
++spot;
}
row += surface->pitch / 4;
}
}
break;
}
SDL_UnlockSurface(surface);
@@ -745,6 +739,14 @@ SDL_UpperBlit(SDL_Surface * src, const SDL_Rect * srcrect,
int
SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
SDL_Surface * dst, SDL_Rect * dstrect)
{
return SDL_PrivateUpperBlitScaled(src, srcrect, dst, dstrect, SDL_ScaleModeNearest);
}
int
SDL_PrivateUpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
SDL_Surface * dst, SDL_Rect * dstrect, SDL_ScaleMode scaleMode)
{
double src_x0, src_y0, src_x1, src_y1;
double dst_x0, dst_y0, dst_x1, dst_y1;
@@ -788,25 +790,25 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
if (NULL == dstrect) {
dst_x0 = 0;
dst_y0 = 0;
dst_x1 = dst_w - 1;
dst_y1 = dst_h - 1;
dst_x1 = dst_w;
dst_y1 = dst_h;
} else {
dst_x0 = dstrect->x;
dst_y0 = dstrect->y;
dst_x1 = dst_x0 + dst_w - 1;
dst_y1 = dst_y0 + dst_h - 1;
dst_x1 = dst_x0 + dst_w;
dst_y1 = dst_y0 + dst_h;
}
if (NULL == srcrect) {
src_x0 = 0;
src_y0 = 0;
src_x1 = src_w - 1;
src_y1 = src_h - 1;
src_x1 = src_w;
src_y1 = src_h;
} else {
src_x0 = srcrect->x;
src_y0 = srcrect->y;
src_x1 = src_x0 + src_w - 1;
src_y1 = src_y0 + src_h - 1;
src_x1 = src_x0 + src_w;
src_y1 = src_y0 + src_h;
/* Clip source rectangle to the source surface */
@@ -815,9 +817,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
src_x0 = 0;
}
if (src_x1 >= src->w) {
dst_x1 -= (src_x1 - src->w + 1) * scaling_w;
src_x1 = src->w - 1;
if (src_x1 > src->w) {
dst_x1 -= (src_x1 - src->w) * scaling_w;
src_x1 = src->w;
}
if (src_y0 < 0) {
@@ -825,9 +827,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
src_y0 = 0;
}
if (src_y1 >= src->h) {
dst_y1 -= (src_y1 - src->h + 1) * scaling_h;
src_y1 = src->h - 1;
if (src_y1 > src->h) {
dst_y1 -= (src_y1 - src->h) * scaling_h;
src_y1 = src->h;
}
}
@@ -844,9 +846,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
dst_x0 = 0;
}
if (dst_x1 >= dst->clip_rect.w) {
src_x1 -= (dst_x1 - dst->clip_rect.w + 1) / scaling_w;
dst_x1 = dst->clip_rect.w - 1;
if (dst_x1 > dst->clip_rect.w) {
src_x1 -= (dst_x1 - dst->clip_rect.w) / scaling_w;
dst_x1 = dst->clip_rect.w;
}
if (dst_y0 < 0) {
@@ -854,9 +856,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
dst_y0 = 0;
}
if (dst_y1 >= dst->clip_rect.h) {
src_y1 -= (dst_y1 - dst->clip_rect.h + 1) / scaling_h;
dst_y1 = dst->clip_rect.h - 1;
if (dst_y1 > dst->clip_rect.h) {
src_y1 -= (dst_y1 - dst->clip_rect.h) / scaling_h;
dst_y1 = dst->clip_rect.h;
}
/* Translate back to surface coordinates */
@@ -865,23 +867,32 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
dst_y0 += dst->clip_rect.y;
dst_y1 += dst->clip_rect.y;
final_src.x = (int)SDL_floor(src_x0 + 0.5);
final_src.y = (int)SDL_floor(src_y0 + 0.5);
final_src.w = (int)SDL_floor(src_x1 + 1 + 0.5) - (int)SDL_floor(src_x0 + 0.5);
final_src.h = (int)SDL_floor(src_y1 + 1 + 0.5) - (int)SDL_floor(src_y0 + 0.5);
final_src.x = (int)SDL_round(src_x0);
final_src.y = (int)SDL_round(src_y0);
final_src.w = (int)SDL_round(src_x1 - src_x0);
final_src.h = (int)SDL_round(src_y1 - src_y0);
final_dst.x = (int)SDL_floor(dst_x0 + 0.5);
final_dst.y = (int)SDL_floor(dst_y0 + 0.5);
final_dst.w = (int)SDL_floor(dst_x1 - dst_x0 + 1.5);
final_dst.h = (int)SDL_floor(dst_y1 - dst_y0 + 1.5);
final_dst.x = (int)SDL_round(dst_x0);
final_dst.y = (int)SDL_round(dst_y0);
final_dst.w = (int)SDL_round(dst_x1 - dst_x0);
final_dst.h = (int)SDL_round(dst_y1 - dst_y0);
if (final_dst.w < 0)
final_dst.w = 0;
if (final_dst.h < 0)
final_dst.h = 0;
/* Clip again */
{
SDL_Rect tmp;
tmp.x = 0;
tmp.y = 0;
tmp.w = src->w;
tmp.h = src->h;
SDL_IntersectRect(&tmp, &final_src, &final_src);
}
if (dstrect)
/* Clip again */
SDL_IntersectRect(&dst->clip_rect, &final_dst, &final_dst);
if (dstrect) {
*dstrect = final_dst;
}
if (final_dst.w == 0 || final_dst.h == 0 ||
final_src.w <= 0 || final_src.h <= 0) {
@@ -889,7 +900,7 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
return 0;
}
return SDL_LowerBlitScaled(src, &final_src, dst, &final_dst);
return SDL_PrivateLowerBlitScaled(src, &final_src, dst, &final_dst, scaleMode);
}
/**
@@ -899,6 +910,13 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
int
SDL_LowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect,
SDL_Surface * dst, SDL_Rect * dstrect)
{
return SDL_PrivateLowerBlitScaled(src, srcrect, dst, dstrect, SDL_ScaleModeNearest);
}
int
SDL_PrivateLowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect,
SDL_Surface * dst, SDL_Rect * dstrect, SDL_ScaleMode scaleMode)
{
static const Uint32 complex_copy_flags = (
SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA |
@@ -906,17 +924,103 @@ SDL_LowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect,
SDL_COPY_COLORKEY
);
if (srcrect->w > SDL_MAX_UINT16 || srcrect->h > SDL_MAX_UINT16 ||
dstrect->w > SDL_MAX_UINT16 || dstrect->h > SDL_MAX_UINT16) {
return SDL_SetError("Size too large for scaling");
}
if (!(src->map->info.flags & SDL_COPY_NEAREST)) {
src->map->info.flags |= SDL_COPY_NEAREST;
SDL_InvalidateMap(src->map);
}
if ( !(src->map->info.flags & complex_copy_flags) &&
src->format->format == dst->format->format &&
!SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) {
return SDL_SoftStretch( src, srcrect, dst, dstrect );
if (scaleMode == SDL_ScaleModeNearest) {
if ( !(src->map->info.flags & complex_copy_flags) &&
src->format->format == dst->format->format &&
!SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) {
return SDL_SoftStretch( src, srcrect, dst, dstrect );
} else {
return SDL_LowerBlit( src, srcrect, dst, dstrect );
}
} else {
return SDL_LowerBlit( src, srcrect, dst, dstrect );
if ( !(src->map->info.flags & complex_copy_flags) &&
src->format->format == dst->format->format &&
!SDL_ISPIXELFORMAT_INDEXED(src->format->format) &&
src->format->BytesPerPixel == 4 &&
src->format->format != SDL_PIXELFORMAT_ARGB2101010) {
/* fast path */
return SDL_SoftStretchLinear(src, srcrect, dst, dstrect);
} else {
/* Use intermediate surface(s) */
SDL_Surface *tmp1 = NULL;
int ret;
SDL_Rect srcrect2;
int is_complex_copy_flags = (src->map->info.flags & complex_copy_flags);
Uint32 flags;
Uint8 r, g, b;
Uint8 alpha;
SDL_BlendMode blendMode;
/* Save source infos */
flags = src->flags;
SDL_GetSurfaceColorMod(src, &r, &g, &b);
SDL_GetSurfaceAlphaMod(src, &alpha);
SDL_GetSurfaceBlendMode(src, &blendMode);
srcrect2.x = srcrect->x;
srcrect2.y = srcrect->y;
srcrect2.w = srcrect->w;
srcrect2.h = srcrect->h;
/* Change source format if not appropriate for scaling */
if (src->format->BytesPerPixel != 4 || src->format->format == SDL_PIXELFORMAT_ARGB2101010) {
SDL_Rect tmprect;
int fmt;
tmprect.x = 0;
tmprect.y = 0;
tmprect.w = src->w;
tmprect.h = src->h;
if (dst->format->BytesPerPixel == 4 && dst->format->format != SDL_PIXELFORMAT_ARGB2101010) {
fmt = dst->format->format;
} else {
fmt = SDL_PIXELFORMAT_ARGB8888;
}
tmp1 = SDL_CreateRGBSurfaceWithFormat(flags, src->w, src->h, 0, fmt);
SDL_LowerBlit(src, srcrect, tmp1, &tmprect);
srcrect2.x = 0;
srcrect2.y = 0;
SDL_SetSurfaceColorMod(tmp1, r, g, b);
SDL_SetSurfaceAlphaMod(tmp1, alpha);
SDL_SetSurfaceBlendMode(tmp1, blendMode);
src = tmp1;
}
/* Intermediate scaling */
if (is_complex_copy_flags || src->format->format != dst->format->format) {
SDL_Rect tmprect;
SDL_Surface *tmp2 = SDL_CreateRGBSurfaceWithFormat(flags, dstrect->w, dstrect->h, 0, src->format->format);
SDL_SoftStretchLinear(src, &srcrect2, tmp2, NULL);
SDL_SetSurfaceColorMod(tmp2, r, g, b);
SDL_SetSurfaceAlphaMod(tmp2, alpha);
SDL_SetSurfaceBlendMode(tmp2, blendMode);
tmprect.x = 0;
tmprect.y = 0;
tmprect.w = dstrect->w;
tmprect.h = dstrect->h;
ret = SDL_LowerBlit(tmp2, &tmprect, dst, dstrect);
SDL_FreeSurface(tmp2);
} else {
ret = SDL_SoftStretchLinear(src, &srcrect2, dst, dstrect);
}
SDL_FreeSurface(tmp1);
return ret;
}
}
}