diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index f9f01fb99..09e216dbe 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -611,12 +611,12 @@ QueueCmdCopy(SDL_Renderer *renderer, SDL_Texture * texture, const SDL_Rect * src static int QueueCmdCopyEx(SDL_Renderer *renderer, SDL_Texture * texture, const SDL_Rect * srcquad, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y) { SDL_RenderCommand *cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_COPY_EX, texture); int retval = -1; if (cmd != NULL) { - retval = renderer->QueueCopyEx(renderer, cmd, texture, srcquad, dstrect, angle, center, flip); + retval = renderer->QueueCopyEx(renderer, cmd, texture, srcquad, dstrect, angle, center, flip, scale_x, scale_y); if (retval < 0) { cmd->command = SDL_RENDERCMD_NO_OP; } @@ -3734,15 +3734,7 @@ SDL_RenderCopyExF(SDL_Renderer * renderer, SDL_Texture * texture, renderer->scale.x, renderer->scale.y); } else { - real_dstrect.x *= renderer->scale.x; - real_dstrect.y *= renderer->scale.y; - real_dstrect.w *= renderer->scale.x; - real_dstrect.h *= renderer->scale.y; - - real_center.x *= renderer->scale.x; - real_center.y *= renderer->scale.y; - - retval = QueueCmdCopyEx(renderer, texture, &real_srcrect, &real_dstrect, angle, &real_center, flip); + retval = QueueCmdCopyEx(renderer, texture, &real_srcrect, &real_dstrect, angle, &real_center, flip, renderer->scale.x, renderer->scale.y); } return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); } diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h index ff38ed0dd..5d92f6a26 100644 --- a/src/render/SDL_sysrender.h +++ b/src/render/SDL_sysrender.h @@ -143,7 +143,7 @@ struct SDL_Renderer const SDL_Rect * srcrect, const SDL_FRect * dstrect); int (*QueueCopyEx) (SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, const SDL_Rect * srcquad, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip); + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y); int (*QueueGeometry) (SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, int num_vertices, const void *indices, int num_indices, int size_indices, diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c index 961aea2f3..4fabcee48 100644 --- a/src/render/software/SDL_render_sw.c +++ b/src/render/software/SDL_render_sw.c @@ -273,12 +273,14 @@ typedef struct CopyExData double angle; SDL_FPoint center; SDL_RendererFlip flip; + float scale_x; + float scale_y; } CopyExData; static int SW_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y) { CopyExData *verts = (CopyExData *) SDL_AllocateRenderVertices(renderer, sizeof (CopyExData), 0, &cmd->data.draw.first); @@ -297,14 +299,35 @@ SW_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * te verts->angle = angle; SDL_memcpy(&verts->center, center, sizeof (SDL_FPoint)); verts->flip = flip; + verts->scale_x = scale_x; + verts->scale_y = scale_y; return 0; } +static int +Blit_to_Screen(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *surface, SDL_Rect *dstrect, + float scale_x, float scale_y, SDL_ScaleMode scaleMode) +{ + int retval; + /* Renderer scaling, if needed */ + if (scale_x != 1.0f || scale_y != 1.0f) { + SDL_Rect r; + r.x = (int)((float) dstrect->x * scale_x); + r.y = (int)((float) dstrect->y * scale_y); + r.w = (int)((float) dstrect->w * scale_x); + r.h = (int)((float) dstrect->h * scale_y); + retval = SDL_PrivateUpperBlitScaled(src, srcrect, surface, &r, scaleMode); + } else { + retval = SDL_BlitSurface(src, srcrect, surface, dstrect); + } + return retval; +} + static int SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * final_rect, - const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip) + const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip, float scale_x, float scale_y) { SDL_Surface *src = (SDL_Surface *) texture->driverdata; SDL_Rect tmp_rect; @@ -475,7 +498,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex SDL_SetSurfaceAlphaMod(src_rotated, alphaMod); SDL_SetSurfaceColorMod(src_rotated, rMod, gMod, bMod); } - retval = SDL_BlitSurface(src_rotated, NULL, surface, &tmp_rect); + /* Renderer scaling, if needed */ + retval = Blit_to_Screen(src_rotated, NULL, surface, &tmp_rect, scale_x, scale_y, texture->scaleMode); } else { /* The NONE blend mode requires three steps to get the pixels onto the destination surface. * First, the area where the rotated pixels will be blitted to get set to zero. @@ -484,7 +508,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex */ SDL_Rect mask_rect = tmp_rect; SDL_SetSurfaceBlendMode(mask_rotated, SDL_BLENDMODE_NONE); - retval = SDL_BlitSurface(mask_rotated, NULL, surface, &mask_rect); + /* Renderer scaling, if needed */ + retval = Blit_to_Screen(mask_rotated, NULL, surface, &mask_rect, scale_x, scale_y, texture->scaleMode); if (!retval) { /* The next step copies the alpha value. This is done with the BLEND blend mode and * by modulating the source colors with 0. Since the destination is all zeros, this @@ -492,7 +517,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex */ SDL_SetSurfaceColorMod(src_rotated, 0, 0, 0); mask_rect = tmp_rect; - retval = SDL_BlitSurface(src_rotated, NULL, surface, &mask_rect); + /* Renderer scaling, if needed */ + retval = Blit_to_Screen(src_rotated, NULL, surface, &mask_rect, scale_x, scale_y, texture->scaleMode); if (!retval) { /* The last step gets the color values in place. The ADD blend mode simply adds them to * the destination (where the color values are all zero). However, because the ADD blend @@ -508,7 +534,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex retval = -1; } else { SDL_SetSurfaceBlendMode(src_rotated_rgb, SDL_BLENDMODE_ADD); - retval = SDL_BlitSurface(src_rotated_rgb, NULL, surface, &tmp_rect); + /* Renderer scaling, if needed */ + retval = Blit_to_Screen(src_rotated_rgb, NULL, surface, &tmp_rect, scale_x, scale_y, texture->scaleMode); SDL_FreeSurface(src_rotated_rgb); } } @@ -879,7 +906,8 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic } SW_RenderCopyEx(renderer, surface, cmd->data.draw.texture, ©data->srcrect, - ©data->dstrect, copydata->angle, ©data->center, copydata->flip); + ©data->dstrect, copydata->angle, ©data->center, copydata->flip, + copydata->scale_x, copydata->scale_y); break; }