mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-26 12:27:44 +00:00
Added SDL_BlitSurfaceTiledWithScale()
This commit is contained in:
@@ -26,6 +26,7 @@ SDL3_0.0.0 {
|
||||
SDL_BlitSurface;
|
||||
SDL_BlitSurfaceScaled;
|
||||
SDL_BlitSurfaceTiled;
|
||||
SDL_BlitSurfaceTiledWithScale;
|
||||
SDL_BlitSurfaceUnchecked;
|
||||
SDL_BlitSurfaceUncheckedScaled;
|
||||
SDL_BroadcastCondition;
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#define SDL_BlitSurface SDL_BlitSurface_REAL
|
||||
#define SDL_BlitSurfaceScaled SDL_BlitSurfaceScaled_REAL
|
||||
#define SDL_BlitSurfaceTiled SDL_BlitSurfaceTiled_REAL
|
||||
#define SDL_BlitSurfaceTiledWithScale SDL_BlitSurfaceTiledWithScale_REAL
|
||||
#define SDL_BlitSurfaceUnchecked SDL_BlitSurfaceUnchecked_REAL
|
||||
#define SDL_BlitSurfaceUncheckedScaled SDL_BlitSurfaceUncheckedScaled_REAL
|
||||
#define SDL_BroadcastCondition SDL_BroadcastCondition_REAL
|
||||
|
||||
@@ -71,6 +71,7 @@ SDL_DYNAPI_PROC(int,SDL_BindAudioStreams,(SDL_AudioDeviceID a, SDL_AudioStream *
|
||||
SDL_DYNAPI_PROC(int,SDL_BlitSurface,(SDL_Surface *a, const SDL_Rect *b, SDL_Surface *c, SDL_Rect *d),(a,b,c,d),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_BlitSurfaceScaled,(SDL_Surface *a, const SDL_Rect *b, SDL_Surface *c, SDL_Rect *d, SDL_ScaleMode e),(a,b,c,d,e),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_BlitSurfaceTiled,(SDL_Surface *a, const SDL_Rect *b, SDL_Surface *c, const SDL_Rect *d),(a,b,c,d),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_BlitSurfaceTiledWithScale,(SDL_Surface *a, const SDL_Rect *b, float c, SDL_ScaleMode d, SDL_Surface *e, const SDL_Rect *f),(a,b,c,d,e,f),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_BlitSurfaceUnchecked,(SDL_Surface *a, const SDL_Rect *b, SDL_Surface *c, const SDL_Rect *d),(a,b,c,d),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_BlitSurfaceUncheckedScaled,(SDL_Surface *a, const SDL_Rect *b, SDL_Surface *c, const SDL_Rect *d, SDL_ScaleMode e),(a,b,c,d,e),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_BroadcastCondition,(SDL_Condition *a),(a),return)
|
||||
|
||||
@@ -1341,6 +1341,119 @@ int SDL_BlitSurfaceTiled(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_BlitSurfaceTiledWithScale(SDL_Surface *src, const SDL_Rect *srcrect, float scale, SDL_ScaleMode scaleMode, SDL_Surface *dst, const SDL_Rect *dstrect)
|
||||
{
|
||||
SDL_Rect r_src, r_dst;
|
||||
|
||||
/* Make sure the surfaces aren't locked */
|
||||
if (!SDL_SurfaceValid(src)) {
|
||||
return SDL_InvalidParamError("src");
|
||||
} else if (!SDL_SurfaceValid(dst)) {
|
||||
return SDL_InvalidParamError("dst");
|
||||
} else if ((src->flags & SDL_SURFACE_LOCKED) || (dst->flags & SDL_SURFACE_LOCKED)) {
|
||||
return SDL_SetError("Surfaces must not be locked during blit");
|
||||
}
|
||||
|
||||
if (scale <= 0.0f) {
|
||||
return SDL_InvalidParamError("scale");
|
||||
}
|
||||
|
||||
/* Full src surface */
|
||||
r_src.x = 0;
|
||||
r_src.y = 0;
|
||||
r_src.w = src->w;
|
||||
r_src.h = src->h;
|
||||
|
||||
if (dstrect) {
|
||||
r_dst.x = dstrect->x;
|
||||
r_dst.y = dstrect->y;
|
||||
r_dst.w = dstrect->w;
|
||||
r_dst.h = dstrect->h;
|
||||
} else {
|
||||
r_dst.x = 0;
|
||||
r_dst.y = 0;
|
||||
r_dst.w = dst->w;
|
||||
r_dst.h = dst->h;
|
||||
}
|
||||
|
||||
/* clip the source rectangle to the source surface */
|
||||
if (srcrect) {
|
||||
if (SDL_GetRectIntersection(srcrect, &r_src, &r_src) == SDL_FALSE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* For tiling we don't adjust the destination rectangle */
|
||||
}
|
||||
|
||||
/* clip the destination rectangle against the clip rectangle */
|
||||
{
|
||||
if (SDL_GetRectIntersection(&r_dst, &dst->internal->clip_rect, &r_dst) == SDL_FALSE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* For tiling we don't adjust the source rectangle */
|
||||
}
|
||||
|
||||
/* Switch back to a fast blit if we were previously stretching */
|
||||
if (src->internal->map.info.flags & SDL_COPY_NEAREST) {
|
||||
src->internal->map.info.flags &= ~SDL_COPY_NEAREST;
|
||||
SDL_InvalidateMap(&src->internal->map);
|
||||
}
|
||||
|
||||
int tile_width = (int)(r_src.w * scale);
|
||||
int tile_height = (int)(r_src.h * scale);
|
||||
int rows = r_dst.h / tile_height;
|
||||
int cols = r_dst.w / tile_width;
|
||||
int remaining_dst_w = (r_dst.w - cols * tile_width);
|
||||
int remaining_dst_h = (r_dst.h - rows * tile_height);
|
||||
int remaining_src_w = (int)(remaining_dst_w / scale);
|
||||
int remaining_src_h = (int)(remaining_dst_h / scale);
|
||||
SDL_Rect curr_src, curr_dst;
|
||||
|
||||
SDL_copyp(&curr_src, &r_src);
|
||||
curr_dst.y = r_dst.y;
|
||||
curr_dst.w = tile_width;
|
||||
curr_dst.h = tile_height;
|
||||
for (int y = 0; y < rows; ++y) {
|
||||
curr_dst.x = r_dst.x;
|
||||
for (int x = 0; x < cols; ++x) {
|
||||
if (SDL_BlitSurfaceUncheckedScaled(src, &curr_src, dst, &curr_dst, scaleMode) < 0) {
|
||||
return -1;
|
||||
}
|
||||
curr_dst.x += curr_dst.w;
|
||||
}
|
||||
if (remaining_dst_w > 0) {
|
||||
curr_src.w = remaining_src_w;
|
||||
curr_dst.w = remaining_dst_w;
|
||||
if (SDL_BlitSurfaceUncheckedScaled(src, &curr_src, dst, &curr_dst, scaleMode) < 0) {
|
||||
return -1;
|
||||
}
|
||||
curr_src.w = r_src.w;
|
||||
curr_dst.w = tile_width;
|
||||
}
|
||||
curr_dst.y += curr_dst.h;
|
||||
}
|
||||
if (remaining_dst_h > 0) {
|
||||
curr_src.h = remaining_src_h;
|
||||
curr_dst.h = remaining_dst_h;
|
||||
curr_dst.x = r_dst.x;
|
||||
for (int x = 0; x < cols; ++x) {
|
||||
if (SDL_BlitSurfaceUncheckedScaled(src, &curr_src, dst, &curr_dst, scaleMode) < 0) {
|
||||
return -1;
|
||||
}
|
||||
curr_dst.x += curr_dst.w;
|
||||
}
|
||||
if (remaining_dst_w > 0) {
|
||||
curr_src.w = remaining_src_w;
|
||||
curr_dst.w = remaining_dst_w;
|
||||
if (SDL_BlitSurfaceUncheckedScaled(src, &curr_src, dst, &curr_dst, scaleMode) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock a surface to directly access the pixels
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user