mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
sdl zooming
Hi all, this patch implements zooming capabilities for the sdl interface. A new sdl_zoom_blit function is added that is able to scale and blit a portion of a surface into another. This way we can enable SDL_RESIZABLE and have a real_screen surface with a different size than the guest surface and let sdl_zoom_blit take care of the problem. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
14899cdf3a
commit
c18a2c360e
6 changed files with 413 additions and 19 deletions
225
sdl_zoom_template.h
Normal file
225
sdl_zoom_template.h
Normal file
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* SDL_zoom_template - surface scaling
|
||||
*
|
||||
* Copyright (c) 2009 Citrix Systems, Inc.
|
||||
*
|
||||
* Derived from: SDL_rotozoom, LGPL (c) A. Schiffler from the SDL_gfx library.
|
||||
* Modifications by Stefano Stabellini.
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL version 2.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#if BPP == 16
|
||||
#define SDL_TYPE Uint16
|
||||
#elif BPP == 32
|
||||
#define SDL_TYPE Uint32
|
||||
#else
|
||||
#error unsupport depth
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simple helper functions to make the code looks nicer
|
||||
*
|
||||
* Assume spf = source SDL_PixelFormat
|
||||
* dpf = dest SDL_PixelFormat
|
||||
*
|
||||
*/
|
||||
#define getRed(color) (((color) & spf->Rmask) >> spf->Rshift)
|
||||
#define getGreen(color) (((color) & spf->Gmask) >> spf->Gshift)
|
||||
#define getBlue(color) (((color) & spf->Bmask) >> spf->Bshift)
|
||||
#define getAlpha(color) (((color) & spf->Amask) >> spf->Ashift)
|
||||
|
||||
#define setRed(r, pcolor) do { \
|
||||
*pcolor = ((*pcolor) & (~(dpf->Rmask))) + \
|
||||
(((r) & (dpf->Rmask >> dpf->Rshift)) << dpf->Rshift); \
|
||||
} while (0);
|
||||
|
||||
#define setGreen(g, pcolor) do { \
|
||||
*pcolor = ((*pcolor) & (~(dpf->Gmask))) + \
|
||||
(((g) & (dpf->Gmask >> dpf->Gshift)) << dpf->Gshift); \
|
||||
} while (0);
|
||||
|
||||
#define setBlue(b, pcolor) do { \
|
||||
*pcolor = ((*pcolor) & (~(dpf->Bmask))) + \
|
||||
(((b) & (dpf->Bmask >> dpf->Bshift)) << dpf->Bshift); \
|
||||
} while (0);
|
||||
|
||||
#define setAlpha(a, pcolor) do { \
|
||||
*pcolor = ((*pcolor) & (~(dpf->Amask))) + \
|
||||
(((a) & (dpf->Amask >> dpf->Ashift)) << dpf->Ashift); \
|
||||
} while (0);
|
||||
|
||||
static int glue(sdl_zoom_rgb, BPP)(SDL_Surface *src, SDL_Surface *dst, int smooth,
|
||||
SDL_Rect *dst_rect)
|
||||
{
|
||||
int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep, sstep_jump;
|
||||
SDL_TYPE *c00, *c01, *c10, *c11, *sp, *csp, *dp;
|
||||
int d_gap;
|
||||
SDL_PixelFormat *spf = src->format;
|
||||
SDL_PixelFormat *dpf = dst->format;
|
||||
|
||||
if (smooth) {
|
||||
/* For interpolation: assume source dimension is one pixel.
|
||||
* Smaller here to avoid overflow on right and bottom edge.
|
||||
*/
|
||||
sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w);
|
||||
sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h);
|
||||
} else {
|
||||
sx = (int) (65536.0 * (float) src->w / (float) dst->w);
|
||||
sy = (int) (65536.0 * (float) src->h / (float) dst->h);
|
||||
}
|
||||
|
||||
if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
|
||||
free(sax);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
sp = csp = (SDL_TYPE *) src->pixels;
|
||||
dp = (SDL_TYPE *) (dst->pixels + dst_rect->y * dst->pitch +
|
||||
dst_rect->x * dst->format->BytesPerPixel);
|
||||
|
||||
csx = 0;
|
||||
csax = sax;
|
||||
for (x = 0; x <= dst->w; x++) {
|
||||
*csax = csx;
|
||||
csax++;
|
||||
csx &= 0xffff;
|
||||
csx += sx;
|
||||
}
|
||||
csy = 0;
|
||||
csay = say;
|
||||
for (y = 0; y <= dst->h; y++) {
|
||||
*csay = csy;
|
||||
csay++;
|
||||
csy &= 0xffff;
|
||||
csy += sy;
|
||||
}
|
||||
|
||||
d_gap = dst->pitch - dst_rect->w * dst->format->BytesPerPixel;
|
||||
|
||||
if (smooth) {
|
||||
csay = say;
|
||||
for (y = 0; y < dst_rect->y; y++) {
|
||||
csay++;
|
||||
sstep = (*csay >> 16) * src->pitch;
|
||||
csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
|
||||
}
|
||||
|
||||
/* Calculate sstep_jump */
|
||||
csax = sax;
|
||||
sstep_jump = 0;
|
||||
for (x = 0; x < dst_rect->x; x++) {
|
||||
csax++;
|
||||
sstep = (*csax >> 16);
|
||||
sstep_jump += sstep;
|
||||
}
|
||||
|
||||
for (y = 0; y < dst_rect->h ; y++) {
|
||||
/* Setup colour source pointers */
|
||||
c00 = csp + sstep_jump;
|
||||
c01 = c00 + 1;
|
||||
c10 = (SDL_TYPE *) ((Uint8 *) csp + src->pitch) + sstep_jump;
|
||||
c11 = c10 + 1;
|
||||
csax = sax + dst_rect->x;
|
||||
|
||||
for (x = 0; x < dst_rect->w; x++) {
|
||||
|
||||
/* Interpolate colours */
|
||||
ex = (*csax & 0xffff);
|
||||
ey = (*csay & 0xffff);
|
||||
t1 = ((((getRed(*c01) - getRed(*c00)) * ex) >> 16) +
|
||||
getRed(*c00)) & (dpf->Rmask >> dpf->Rshift);
|
||||
t2 = ((((getRed(*c11) - getRed(*c10)) * ex) >> 16) +
|
||||
getRed(*c10)) & (dpf->Rmask >> dpf->Rshift);
|
||||
setRed((((t2 - t1) * ey) >> 16) + t1, dp);
|
||||
t1 = ((((getGreen(*c01) - getGreen(*c00)) * ex) >> 16) +
|
||||
getGreen(*c00)) & (dpf->Gmask >> dpf->Gshift);
|
||||
t2 = ((((getGreen(*c11) - getGreen(*c10)) * ex) >> 16) +
|
||||
getGreen(*c10)) & (dpf->Gmask >> dpf->Gshift);
|
||||
setGreen((((t2 - t1) * ey) >> 16) + t1, dp);
|
||||
t1 = ((((getBlue(*c01) - getBlue(*c00)) * ex) >> 16) +
|
||||
getBlue(*c00)) & (dpf->Bmask >> dpf->Bshift);
|
||||
t2 = ((((getBlue(*c11) - getBlue(*c10)) * ex) >> 16) +
|
||||
getBlue(*c10)) & (dpf->Bmask >> dpf->Bshift);
|
||||
setBlue((((t2 - t1) * ey) >> 16) + t1, dp);
|
||||
t1 = ((((getAlpha(*c01) - getAlpha(*c00)) * ex) >> 16) +
|
||||
getAlpha(*c00)) & (dpf->Amask >> dpf->Ashift);
|
||||
t2 = ((((getAlpha(*c11) - getAlpha(*c10)) * ex) >> 16) +
|
||||
getAlpha(*c10)) & (dpf->Amask >> dpf->Ashift);
|
||||
setAlpha((((t2 - t1) * ey) >> 16) + t1, dp);
|
||||
|
||||
/* Advance source pointers */
|
||||
csax++;
|
||||
sstep = (*csax >> 16);
|
||||
c00 += sstep;
|
||||
c01 += sstep;
|
||||
c10 += sstep;
|
||||
c11 += sstep;
|
||||
/* Advance destination pointer */
|
||||
dp++;
|
||||
}
|
||||
/* Advance source pointer */
|
||||
csay++;
|
||||
csp = (SDL_TYPE *) ((Uint8 *) csp + (*csay >> 16) * src->pitch);
|
||||
/* Advance destination pointers */
|
||||
dp = (SDL_TYPE *) ((Uint8 *) dp + d_gap);
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
csay = say;
|
||||
|
||||
for (y = 0; y < dst_rect->y; y++) {
|
||||
csay++;
|
||||
sstep = (*csay >> 16) * src->pitch;
|
||||
csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
|
||||
}
|
||||
|
||||
/* Calculate sstep_jump */
|
||||
csax = sax;
|
||||
sstep_jump = 0;
|
||||
for (x = 0; x < dst_rect->x; x++) {
|
||||
csax++;
|
||||
sstep = (*csax >> 16);
|
||||
sstep_jump += sstep;
|
||||
}
|
||||
|
||||
for (y = 0 ; y < dst_rect->h ; y++) {
|
||||
sp = csp + sstep_jump;
|
||||
csax = sax + dst_rect->x;
|
||||
|
||||
for (x = 0; x < dst_rect->w; x++) {
|
||||
|
||||
/* Draw */
|
||||
*dp = *sp;
|
||||
|
||||
/* Advance source pointers */
|
||||
csax++;
|
||||
sstep = (*csax >> 16);
|
||||
sp += sstep;
|
||||
|
||||
/* Advance destination pointer */
|
||||
dp++;
|
||||
}
|
||||
/* Advance source pointers */
|
||||
csay++;
|
||||
sstep = (*csay >> 16) * src->pitch;
|
||||
csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
|
||||
|
||||
/* Advance destination pointer */
|
||||
dp = (SDL_TYPE *) ((Uint8 *) dp + d_gap);
|
||||
}
|
||||
}
|
||||
|
||||
free(sax);
|
||||
free(say);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#undef SDL_TYPE
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue