diff -r f061a86fbb08 src/render/software/SDL_render_sw.c --- a/src/render/software/SDL_render_sw.c Sun Jul 13 09:04:55 2014 -0700 +++ b/src/render/software/SDL_render_sw.c Fri Jul 18 19:10:16 2014 +0300 @@ -348,11 +348,21 @@ { SW_RenderData *data = (SW_RenderData *) renderer->driverdata; SDL_Surface *surface = data->surface; + SDL_Rect final_clip = renderer->viewport; if (surface) { if (renderer->clipping_enabled) { - SDL_SetClipRect(surface, &renderer->clip_rect); + SDL_Rect new_rclip; + new_rclip = renderer->clip_rect; + new_rclip.x += final_clip.x; + new_rclip.y += final_clip.y; + SDL_IntersectRect(&(renderer->viewport), &new_rclip, &final_clip); + SDL_SetClipRect(surface, &final_clip); } else { - SDL_SetClipRect(surface, NULL); + if (final_clip.w == surface->w && final_clip.h == surface->h) { + SDL_SetClipRect(surface, NULL); + } else { + SDL_SetClipRect(surface, &final_clip); + } } } return 0; @@ -534,26 +544,70 @@ { SDL_Surface *surface = SW_ActivateRenderer(renderer); SDL_Surface *src = (SDL_Surface *) texture->driverdata; - SDL_Rect final_rect; + SDL_Rect tmp_rect, final_dstrect; + int offx, offy; + const SDL_Rect *final_srcrect = srcrect; if (!surface) { return -1; } if (renderer->viewport.x || renderer->viewport.y) { - final_rect.x = (int)(renderer->viewport.x + dstrect->x); - final_rect.y = (int)(renderer->viewport.y + dstrect->y); + tmp_rect.x = (int)(renderer->viewport.x + dstrect->x); + tmp_rect.y = (int)(renderer->viewport.y + dstrect->y); } else { - final_rect.x = (int)dstrect->x; - final_rect.y = (int)dstrect->y; + tmp_rect.x = (int)dstrect->x; + tmp_rect.y = (int)dstrect->y; } - final_rect.w = (int)dstrect->w; - final_rect.h = (int)dstrect->h; + tmp_rect.w = (int)dstrect->w; + tmp_rect.h = (int)dstrect->h; - if ( srcrect->w == final_rect.w && srcrect->h == final_rect.h ) { - return SDL_BlitSurface(src, srcrect, surface, &final_rect); + /* Perform clipping */ + offx = tmp_rect.x; + offy = tmp_rect.y; + if (!SDL_IntersectRect(&(surface->clip_rect), &tmp_rect, &final_dstrect)) { + puts("clipt"); + return 0; + } + if (final_dstrect.w != dstrect->w || final_dstrect.h != dstrect->h) { + /* The size changed! Change the source rect as well. */ + if (srcrect) { + tmp_rect = *srcrect; + } else { + tmp_rect.x = 0; + tmp_rect.y = 0; + tmp_rect.w = (int)src->w; + tmp_rect.h = (int)src->h; + } + if (offx < 0) { + tmp_rect.x = (int)-offx; + } else if (offx < final_dstrect.x) { + tmp_rect.x = (int)((int)final_dstrect.x - (int)offx); + } else { + tmp_rect.x = 0; + } + if (offy < 0) { + tmp_rect.y = (int)-offy; + } else if (offy < final_dstrect.y) { + tmp_rect.y = (int)((int)final_dstrect.y - (int)offy); + } else { + tmp_rect.y = (int)0; + } + tmp_rect.w *= (int)final_dstrect.w; + tmp_rect.w /= (int)dstrect->w; + tmp_rect.h *= (int)final_dstrect.h; + tmp_rect.h /= (int)dstrect->h; + tmp_rect.x *= (int)tmp_rect.w; + tmp_rect.x /= (int)final_dstrect.w; + tmp_rect.y *= (int)tmp_rect.h; + tmp_rect.y /= (int)final_dstrect.h; + final_srcrect = &tmp_rect; + } + + if ( final_srcrect->w == final_dstrect.w && final_srcrect->h == final_dstrect.h ) { + return SDL_BlitSurface(src, final_srcrect, surface, &final_dstrect); } else { - return SDL_BlitScaled(src, srcrect, surface, &final_rect); + return SDL_BlitScaled(src, final_srcrect, surface, &final_dstrect); } } @@ -576,11 +630,13 @@ { SDL_Surface *surface = SW_ActivateRenderer(renderer); SDL_Surface *src = (SDL_Surface *) texture->driverdata; - SDL_Rect final_rect, tmp_rect; + SDL_Rect final_rect, final_dstrect, tmp_rect; + const SDL_Rect *final_srcrect; SDL_Surface *surface_rotated, *surface_scaled; + SDL_BlendMode texblendmode; Uint32 colorkey; int retval, dstwidth, dstheight, abscenterx, abscentery; - double cangle, sangle, px, py, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y; + double cangle, sangle, px, py, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y, offx, offy; if (!surface) { return -1; @@ -606,7 +662,13 @@ tmp_rect.x = 0; tmp_rect.y = 0; + /* reset the texture blend mode for the duration of the scaled blit */ + SDL_GetSurfaceBlendMode(src, &texblendmode); + SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_NONE); retval = SDL_BlitScaled(src, srcrect, surface_scaled, &tmp_rect); + /* restore it */ + SDL_SetSurfaceBlendMode(src, texblendmode); + if (!retval) { SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, -angle, &dstwidth, &dstheight, &cangle, &sangle); surface_rotated = SDLgfx_rotateSurface(surface_scaled, -angle, dstwidth/2, dstheight/2, GetScaleQuality(), flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle); @@ -646,7 +708,41 @@ tmp_rect.w = dstwidth; tmp_rect.h = dstheight; - retval = SDL_BlitSurface(surface_rotated, NULL, surface, &tmp_rect); + /* set the appropriate blend mode for the rotated blit */ + SDL_SetSurfaceBlendMode(surface_rotated, texblendmode); + + /* Perform clipping */ + offx = tmp_rect.x; + offy = tmp_rect.y; + if (!SDL_IntersectRect(&(surface->clip_rect), &tmp_rect, &final_dstrect)) { + SDL_free(surface_scaled); + SDL_free(surface_rotated); + return 0; + } + if (final_dstrect.w != dstrect->w || final_dstrect.h != dstrect->h) { + /* The size changed! Change the source rect as well. */ + if (offx < 0) { + tmp_rect.x = (int)-offx; + } else if (offx < final_dstrect.x) { + tmp_rect.x = (int)((int)final_dstrect.x - (int)offx); + } else { + tmp_rect.x = 0; + } + if (offy < 0) { + tmp_rect.y = (int)-offy; + } else if (offy < final_dstrect.y) { + tmp_rect.y = (int)((int)final_dstrect.y - (int)offy); + } else { + tmp_rect.y = (int)0; + } + tmp_rect.w = (int)final_dstrect.w; + tmp_rect.h = (int)final_dstrect.h; + final_srcrect = &tmp_rect; + } else { + final_srcrect = NULL; + } + + retval = SDL_BlitSurface(surface_rotated, final_srcrect, surface, &final_dstrect); SDL_FreeSurface(surface_scaled); SDL_FreeSurface(surface_rotated); return retval; diff -r f061a86fbb08 src/render/software/SDL_rotate.c --- a/src/render/software/SDL_rotate.c Sun Jul 13 09:04:55 2014 -0700 +++ b/src/render/software/SDL_rotate.c Fri Jul 18 19:10:16 2014 +0300 @@ -463,7 +463,7 @@ * Turn on source-alpha support */ /* SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); */ - SDL_SetColorKey(rz_dst, /* SDL_SRCCOLORKEY */ SDL_TRUE | SDL_RLEACCEL, _colorkey(rz_src)); + SDL_SetColorKey(rz_dst, /* SDL_SRCCOLORKEY */ SDL_TRUE /* | SDL_RLEACCEL */, _colorkey(rz_src)); } else { /* * Copy palette and colorkey info @@ -478,7 +478,7 @@ transformSurfaceY(rz_src, rz_dst, centerx, centery, (int) (sangleinv), (int) (cangleinv), flipx, flipy); - SDL_SetColorKey(rz_dst, /* SDL_SRCCOLORKEY */ SDL_TRUE | SDL_RLEACCEL, _colorkey(rz_src)); + SDL_SetColorKey(rz_dst, /* SDL_SRCCOLORKEY */ SDL_TRUE /* | SDL_RLEACCEL */, _colorkey(rz_src)); } /* * Unlock source surface