Commit c18a2c360e3100bbd71162cf922dcd8c429a8b71
Committed by
Anthony Liguori
1 parent
14899cdf
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>
Showing
6 changed files
with
413 additions
and
19 deletions
Makefile
... | ... | @@ -165,7 +165,7 @@ OBJS+=$(addprefix audio/, $(AUDIO_OBJS)) |
165 | 165 | |
166 | 166 | OBJS+=keymaps.o |
167 | 167 | ifdef CONFIG_SDL |
168 | -OBJS+=sdl.o x_keymap.o | |
168 | +OBJS+=sdl.o sdl_zoom.o x_keymap.o | |
169 | 169 | endif |
170 | 170 | ifdef CONFIG_CURSES |
171 | 171 | OBJS+=curses.o |
... | ... | @@ -209,7 +209,9 @@ cocoa.o: cocoa.m |
209 | 209 | |
210 | 210 | keymaps.o: keymaps.c keymaps.h |
211 | 211 | |
212 | -sdl.o: sdl.c keymaps.h sdl_keysym.h | |
212 | +sdl_zoom.o: sdl_zoom.c sdl_zoom.h sdl_zoom_template.h | |
213 | + | |
214 | +sdl.o: sdl.c keymaps.h sdl_keysym.h sdl_zoom.h | |
213 | 215 | |
214 | 216 | sdl.o audio/sdlaudio.o baum.o: CFLAGS += $(SDL_CFLAGS) |
215 | 217 | ... | ... |
console.h
... | ... | @@ -75,6 +75,7 @@ void kbd_put_keysym(int keysym); |
75 | 75 | |
76 | 76 | #define QEMU_BIG_ENDIAN_FLAG 0x01 |
77 | 77 | #define QEMU_ALLOCATED_FLAG 0x02 |
78 | +#define QEMU_REALPIXELS_FLAG 0x04 | |
78 | 79 | |
79 | 80 | struct PixelFormat { |
80 | 81 | uint8_t bits_per_pixel; |
... | ... | @@ -172,7 +173,8 @@ static inline int is_surface_bgr(DisplaySurface *surface) |
172 | 173 | |
173 | 174 | static inline int is_buffer_shared(DisplaySurface *surface) |
174 | 175 | { |
175 | - return (!(surface->flags & QEMU_ALLOCATED_FLAG)); | |
176 | + return (!(surface->flags & QEMU_ALLOCATED_FLAG) && | |
177 | + !(surface->flags & QEMU_REALPIXELS_FLAG)); | |
176 | 178 | } |
177 | 179 | |
178 | 180 | static inline void register_displaychangelistener(DisplayState *ds, DisplayChangeListener *dcl) | ... | ... |
sdl.c
... | ... | @@ -32,6 +32,7 @@ |
32 | 32 | #include "console.h" |
33 | 33 | #include "sysemu.h" |
34 | 34 | #include "x_keymap.h" |
35 | +#include "sdl_zoom.h" | |
35 | 36 | |
36 | 37 | static DisplayChangeListener *dcl; |
37 | 38 | static SDL_Surface *real_screen; |
... | ... | @@ -54,20 +55,29 @@ static int guest_cursor = 0; |
54 | 55 | static int guest_x, guest_y; |
55 | 56 | static SDL_Cursor *guest_sprite = 0; |
56 | 57 | static uint8_t allocator; |
57 | -static uint8_t hostbpp; | |
58 | +static SDL_PixelFormat host_format; | |
59 | +static int scaling_active = 0; | |
58 | 60 | |
59 | 61 | static void sdl_update(DisplayState *ds, int x, int y, int w, int h) |
60 | 62 | { |
61 | 63 | // printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h); |
64 | + SDL_Rect rec; | |
65 | + rec.x = x; | |
66 | + rec.y = y; | |
67 | + rec.w = w; | |
68 | + rec.h = h; | |
69 | + | |
62 | 70 | if (guest_screen) { |
63 | - SDL_Rect rec; | |
64 | - rec.x = x; | |
65 | - rec.y = y; | |
66 | - rec.w = w; | |
67 | - rec.h = h; | |
68 | - SDL_BlitSurface(guest_screen, &rec, real_screen, &rec); | |
69 | - } | |
70 | - SDL_UpdateRect(real_screen, x, y, w, h); | |
71 | + if (!scaling_active) { | |
72 | + SDL_BlitSurface(guest_screen, &rec, real_screen, &rec); | |
73 | + } else { | |
74 | + if (sdl_zoom_blit(guest_screen, real_screen, SMOOTHING_ON, &rec) < 0) { | |
75 | + fprintf(stderr, "Zoom blit failed\n"); | |
76 | + exit(1); | |
77 | + } | |
78 | + } | |
79 | + } | |
80 | + SDL_UpdateRect(real_screen, rec.x, rec.y, rec.w, rec.h); | |
71 | 81 | } |
72 | 82 | |
73 | 83 | static void sdl_setdata(DisplayState *ds) |
... | ... | @@ -92,7 +102,7 @@ static void do_sdl_resize(int new_width, int new_height, int bpp) |
92 | 102 | |
93 | 103 | // printf("resizing to %d %d\n", w, h); |
94 | 104 | |
95 | - flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL; | |
105 | + flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_RESIZABLE; | |
96 | 106 | if (gui_fullscreen) |
97 | 107 | flags |= SDL_FULLSCREEN; |
98 | 108 | if (gui_noframe) |
... | ... | @@ -110,7 +120,10 @@ static void do_sdl_resize(int new_width, int new_height, int bpp) |
110 | 120 | static void sdl_resize(DisplayState *ds) |
111 | 121 | { |
112 | 122 | if (!allocator) { |
113 | - do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0); | |
123 | + if (!scaling_active) | |
124 | + do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0); | |
125 | + else if (real_screen->format->BitsPerPixel != ds_get_bits_per_pixel(ds)) | |
126 | + do_sdl_resize(real_screen->w, real_screen->h, ds_get_bits_per_pixel(ds)); | |
114 | 127 | sdl_setdata(ds); |
115 | 128 | } else { |
116 | 129 | if (guest_screen != NULL) { |
... | ... | @@ -163,8 +176,26 @@ static DisplaySurface* sdl_create_displaysurface(int width, int height) |
163 | 176 | |
164 | 177 | surface->width = width; |
165 | 178 | surface->height = height; |
179 | + | |
180 | + if (scaling_active) { | |
181 | + if (host_format.BytesPerPixel != 2 && host_format.BytesPerPixel != 4) { | |
182 | + surface->linesize = width * 4; | |
183 | + surface->pf = qemu_default_pixelformat(32); | |
184 | + } else { | |
185 | + surface->linesize = width * host_format.BytesPerPixel; | |
186 | + surface->pf = sdl_to_qemu_pixelformat(&host_format); | |
187 | + } | |
188 | +#ifdef WORDS_BIGENDIAN | |
189 | + surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG; | |
190 | +#else | |
191 | + surface->flags = QEMU_ALLOCATED_FLAG; | |
192 | +#endif | |
193 | + surface->data = (uint8_t*) qemu_mallocz(surface->linesize * surface->height); | |
194 | + | |
195 | + return surface; | |
196 | + } | |
166 | 197 | |
167 | - if (hostbpp == 16) | |
198 | + if (host_format.BitsPerPixel == 16) | |
168 | 199 | do_sdl_resize(width, height, 16); |
169 | 200 | else |
170 | 201 | do_sdl_resize(width, height, 32); |
... | ... | @@ -174,9 +205,9 @@ static DisplaySurface* sdl_create_displaysurface(int width, int height) |
174 | 205 | surface->data = real_screen->pixels; |
175 | 206 | |
176 | 207 | #ifdef WORDS_BIGENDIAN |
177 | - surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG; | |
208 | + surface->flags = QEMU_REALPIXELS_FLAG | QEMU_BIG_ENDIAN_FLAG; | |
178 | 209 | #else |
179 | - surface->flags = QEMU_ALLOCATED_FLAG; | |
210 | + surface->flags = QEMU_REALPIXELS_FLAG; | |
180 | 211 | #endif |
181 | 212 | allocator = 1; |
182 | 213 | |
... | ... | @@ -188,6 +219,9 @@ static void sdl_free_displaysurface(DisplaySurface *surface) |
188 | 219 | allocator = 0; |
189 | 220 | if (surface == NULL) |
190 | 221 | return; |
222 | + | |
223 | + if (surface->flags & QEMU_ALLOCATED_FLAG) | |
224 | + qemu_free(surface->data); | |
191 | 225 | qemu_free(surface); |
192 | 226 | } |
193 | 227 | |
... | ... | @@ -482,8 +516,8 @@ static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state |
482 | 516 | static void toggle_full_screen(DisplayState *ds) |
483 | 517 | { |
484 | 518 | gui_fullscreen = !gui_fullscreen; |
485 | - do_sdl_resize(real_screen->w, real_screen->h, real_screen->format->BitsPerPixel); | |
486 | 519 | if (gui_fullscreen) { |
520 | + scaling_active = 0; | |
487 | 521 | gui_saved_grab = gui_grab; |
488 | 522 | sdl_grab_start(); |
489 | 523 | } else { |
... | ... | @@ -675,6 +709,18 @@ static void sdl_refresh(DisplayState *ds) |
675 | 709 | } |
676 | 710 | } |
677 | 711 | break; |
712 | + case SDL_VIDEORESIZE: | |
713 | + { | |
714 | + SDL_ResizeEvent *rev = &ev->resize; | |
715 | + int bpp = real_screen->format->BitsPerPixel; | |
716 | + if (bpp != 16 && bpp != 32) | |
717 | + bpp = 32; | |
718 | + do_sdl_resize(rev->w, rev->h, bpp); | |
719 | + scaling_active = 1; | |
720 | + vga_hw_invalidate(); | |
721 | + vga_hw_update(); | |
722 | + break; | |
723 | + } | |
678 | 724 | default: |
679 | 725 | break; |
680 | 726 | } |
... | ... | @@ -783,7 +829,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) |
783 | 829 | exit(1); |
784 | 830 | } |
785 | 831 | vi = SDL_GetVideoInfo(); |
786 | - hostbpp = vi->vfmt->BitsPerPixel; | |
832 | + host_format = *(vi->vfmt); | |
787 | 833 | |
788 | 834 | dcl = qemu_mallocz(sizeof(DisplayChangeListener)); |
789 | 835 | dcl->dpy_update = sdl_update; | ... | ... |
sdl_zoom.c
0 โ 100644
1 | +/* | |
2 | + * SDL_zoom - surface scaling | |
3 | + * | |
4 | + * Copyright (c) 2009 Citrix Systems, Inc. | |
5 | + * | |
6 | + * Derived from: SDL_rotozoom, LGPL (c) A. Schiffler from the SDL_gfx library. | |
7 | + * Modifications by Stefano Stabellini. | |
8 | + * | |
9 | + * This work is licensed under the terms of the GNU GPL version 2. | |
10 | + * See the COPYING file in the top-level directory. | |
11 | + * | |
12 | + */ | |
13 | + | |
14 | +#include "sdl_zoom.h" | |
15 | +#include "osdep.h" | |
16 | +#include <stdint.h> | |
17 | + | |
18 | +static int sdl_zoom_rgb16(SDL_Surface *src, SDL_Surface *dst, int smooth, | |
19 | + SDL_Rect *dst_rect); | |
20 | +static int sdl_zoom_rgb32(SDL_Surface *src, SDL_Surface *dst, int smooth, | |
21 | + SDL_Rect *dst_rect); | |
22 | + | |
23 | +#define BPP 32 | |
24 | +#include "sdl_zoom_template.h" | |
25 | +#undef BPP | |
26 | +#define BPP 16 | |
27 | +#include "sdl_zoom_template.h" | |
28 | +#undef BPP | |
29 | + | |
30 | +int sdl_zoom_blit(SDL_Surface *src_sfc, SDL_Surface *dst_sfc, int smooth, | |
31 | + SDL_Rect *in_rect) | |
32 | +{ | |
33 | + SDL_Rect zoom, src_rect; | |
34 | + int extra; | |
35 | + | |
36 | + /* Grow the size of the modified rectangle to avoid edge artefacts */ | |
37 | + src_rect.x = (in_rect->x > 0) ? (in_rect->x - 1) : 0; | |
38 | + src_rect.y = (in_rect->y > 0) ? (in_rect->y - 1) : 0; | |
39 | + | |
40 | + src_rect.w = in_rect->w + 1; | |
41 | + if (src_rect.x + src_rect.w > src_sfc->w) | |
42 | + src_rect.w = src_sfc->w - src_rect.x; | |
43 | + | |
44 | + src_rect.h = in_rect->h + 1; | |
45 | + if (src_rect.y + src_rect.h > src_sfc->h) | |
46 | + src_rect.h = src_sfc->h - src_rect.y; | |
47 | + | |
48 | + /* (x,y) : round down */ | |
49 | + zoom.x = (int)(((float)(src_rect.x * dst_sfc->w)) / (float)(src_sfc->w)); | |
50 | + zoom.y = (int)(((float)(src_rect.y * dst_sfc->h)) / (float)(src_sfc->h)); | |
51 | + | |
52 | + /* (w,h) : round up */ | |
53 | + zoom.w = (int)( ((double)((src_rect.w * dst_sfc->w) + (src_sfc->w - 1))) / | |
54 | + (double)(src_sfc->w)); | |
55 | + | |
56 | + zoom.h = (int)( ((double)((src_rect.h * dst_sfc->h) + (src_sfc->h - 1))) / | |
57 | + (double)(src_sfc->h)); | |
58 | + | |
59 | + /* Account for any (x,y) rounding by adding one-source-pixel's worth | |
60 | + * of destination pixels and then edge checking. | |
61 | + */ | |
62 | + | |
63 | + extra = ((dst_sfc->w-1) / src_sfc->w) + 1; | |
64 | + | |
65 | + if ((zoom.x + zoom.w) < (dst_sfc->w - extra)) | |
66 | + zoom.w += extra; | |
67 | + else | |
68 | + zoom.w = dst_sfc->w - zoom.x; | |
69 | + | |
70 | + extra = ((dst_sfc->h-1) / src_sfc->h) + 1; | |
71 | + | |
72 | + if ((zoom.y + zoom.h) < (dst_sfc->h - extra)) | |
73 | + zoom.h += extra; | |
74 | + else | |
75 | + zoom.h = dst_sfc->h - zoom.y; | |
76 | + | |
77 | + /* The rectangle (zoom.x, zoom.y, zoom.w, zoom.h) is the area on the | |
78 | + * destination surface that needs to be updated. | |
79 | + */ | |
80 | + if (src_sfc->format->BitsPerPixel == 32) | |
81 | + sdl_zoom_rgb32(src_sfc, dst_sfc, smooth, &zoom); | |
82 | + else if (src_sfc->format->BitsPerPixel == 16) | |
83 | + sdl_zoom_rgb16(src_sfc, dst_sfc, smooth, &zoom); | |
84 | + else { | |
85 | + fprintf(stderr, "pixel format not supported\n"); | |
86 | + return -1; | |
87 | + } | |
88 | + | |
89 | + /* Return the rectangle of the update to the caller */ | |
90 | + *in_rect = zoom; | |
91 | + | |
92 | + return 0; | |
93 | +} | |
94 | + | ... | ... |
sdl_zoom.h
0 โ 100644
1 | +/* | |
2 | + * SDL_zoom - surface scaling | |
3 | + * | |
4 | + * Copyright (c) 2009 Citrix Systems, Inc. | |
5 | + * | |
6 | + * Derived from: SDL_rotozoom, LGPL (c) A. Schiffler from the SDL_gfx library. | |
7 | + * Modifications by Stefano Stabellini. | |
8 | + * | |
9 | + * This work is licensed under the terms of the GNU GPL version 2. | |
10 | + * See the COPYING file in the top-level directory. | |
11 | + * | |
12 | + */ | |
13 | + | |
14 | +#ifndef _SDL_zoom_h | |
15 | +#define _SDL_zoom_h | |
16 | + | |
17 | +#include <SDL/SDL.h> | |
18 | + | |
19 | +#define SMOOTHING_OFF 0 | |
20 | +#define SMOOTHING_ON 1 | |
21 | + | |
22 | +int sdl_zoom_blit(SDL_Surface *src_sfc, SDL_Surface *dst_sfc, | |
23 | + int smooth, SDL_Rect *src_rect); | |
24 | + | |
25 | +#endif /* _SDL_zoom_h */ | ... | ... |
sdl_zoom_template.h
0 โ 100644
1 | +/* | |
2 | + * SDL_zoom_template - surface scaling | |
3 | + * | |
4 | + * Copyright (c) 2009 Citrix Systems, Inc. | |
5 | + * | |
6 | + * Derived from: SDL_rotozoom, LGPL (c) A. Schiffler from the SDL_gfx library. | |
7 | + * Modifications by Stefano Stabellini. | |
8 | + * | |
9 | + * This work is licensed under the terms of the GNU GPL version 2. | |
10 | + * See the COPYING file in the top-level directory. | |
11 | + * | |
12 | + */ | |
13 | + | |
14 | +#if BPP == 16 | |
15 | +#define SDL_TYPE Uint16 | |
16 | +#elif BPP == 32 | |
17 | +#define SDL_TYPE Uint32 | |
18 | +#else | |
19 | +#error unsupport depth | |
20 | +#endif | |
21 | + | |
22 | +/* | |
23 | + * Simple helper functions to make the code looks nicer | |
24 | + * | |
25 | + * Assume spf = source SDL_PixelFormat | |
26 | + * dpf = dest SDL_PixelFormat | |
27 | + * | |
28 | + */ | |
29 | +#define getRed(color) (((color) & spf->Rmask) >> spf->Rshift) | |
30 | +#define getGreen(color) (((color) & spf->Gmask) >> spf->Gshift) | |
31 | +#define getBlue(color) (((color) & spf->Bmask) >> spf->Bshift) | |
32 | +#define getAlpha(color) (((color) & spf->Amask) >> spf->Ashift) | |
33 | + | |
34 | +#define setRed(r, pcolor) do { \ | |
35 | + *pcolor = ((*pcolor) & (~(dpf->Rmask))) + \ | |
36 | + (((r) & (dpf->Rmask >> dpf->Rshift)) << dpf->Rshift); \ | |
37 | +} while (0); | |
38 | + | |
39 | +#define setGreen(g, pcolor) do { \ | |
40 | + *pcolor = ((*pcolor) & (~(dpf->Gmask))) + \ | |
41 | + (((g) & (dpf->Gmask >> dpf->Gshift)) << dpf->Gshift); \ | |
42 | +} while (0); | |
43 | + | |
44 | +#define setBlue(b, pcolor) do { \ | |
45 | + *pcolor = ((*pcolor) & (~(dpf->Bmask))) + \ | |
46 | + (((b) & (dpf->Bmask >> dpf->Bshift)) << dpf->Bshift); \ | |
47 | +} while (0); | |
48 | + | |
49 | +#define setAlpha(a, pcolor) do { \ | |
50 | + *pcolor = ((*pcolor) & (~(dpf->Amask))) + \ | |
51 | + (((a) & (dpf->Amask >> dpf->Ashift)) << dpf->Ashift); \ | |
52 | +} while (0); | |
53 | + | |
54 | +static int glue(sdl_zoom_rgb, BPP)(SDL_Surface *src, SDL_Surface *dst, int smooth, | |
55 | + SDL_Rect *dst_rect) | |
56 | +{ | |
57 | + int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep, sstep_jump; | |
58 | + SDL_TYPE *c00, *c01, *c10, *c11, *sp, *csp, *dp; | |
59 | + int d_gap; | |
60 | + SDL_PixelFormat *spf = src->format; | |
61 | + SDL_PixelFormat *dpf = dst->format; | |
62 | + | |
63 | + if (smooth) { | |
64 | + /* For interpolation: assume source dimension is one pixel. | |
65 | + * Smaller here to avoid overflow on right and bottom edge. | |
66 | + */ | |
67 | + sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w); | |
68 | + sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h); | |
69 | + } else { | |
70 | + sx = (int) (65536.0 * (float) src->w / (float) dst->w); | |
71 | + sy = (int) (65536.0 * (float) src->h / (float) dst->h); | |
72 | + } | |
73 | + | |
74 | + if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) { | |
75 | + return (-1); | |
76 | + } | |
77 | + if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) { | |
78 | + free(sax); | |
79 | + return (-1); | |
80 | + } | |
81 | + | |
82 | + sp = csp = (SDL_TYPE *) src->pixels; | |
83 | + dp = (SDL_TYPE *) (dst->pixels + dst_rect->y * dst->pitch + | |
84 | + dst_rect->x * dst->format->BytesPerPixel); | |
85 | + | |
86 | + csx = 0; | |
87 | + csax = sax; | |
88 | + for (x = 0; x <= dst->w; x++) { | |
89 | + *csax = csx; | |
90 | + csax++; | |
91 | + csx &= 0xffff; | |
92 | + csx += sx; | |
93 | + } | |
94 | + csy = 0; | |
95 | + csay = say; | |
96 | + for (y = 0; y <= dst->h; y++) { | |
97 | + *csay = csy; | |
98 | + csay++; | |
99 | + csy &= 0xffff; | |
100 | + csy += sy; | |
101 | + } | |
102 | + | |
103 | + d_gap = dst->pitch - dst_rect->w * dst->format->BytesPerPixel; | |
104 | + | |
105 | + if (smooth) { | |
106 | + csay = say; | |
107 | + for (y = 0; y < dst_rect->y; y++) { | |
108 | + csay++; | |
109 | + sstep = (*csay >> 16) * src->pitch; | |
110 | + csp = (SDL_TYPE *) ((Uint8 *) csp + sstep); | |
111 | + } | |
112 | + | |
113 | + /* Calculate sstep_jump */ | |
114 | + csax = sax; | |
115 | + sstep_jump = 0; | |
116 | + for (x = 0; x < dst_rect->x; x++) { | |
117 | + csax++; | |
118 | + sstep = (*csax >> 16); | |
119 | + sstep_jump += sstep; | |
120 | + } | |
121 | + | |
122 | + for (y = 0; y < dst_rect->h ; y++) { | |
123 | + /* Setup colour source pointers */ | |
124 | + c00 = csp + sstep_jump; | |
125 | + c01 = c00 + 1; | |
126 | + c10 = (SDL_TYPE *) ((Uint8 *) csp + src->pitch) + sstep_jump; | |
127 | + c11 = c10 + 1; | |
128 | + csax = sax + dst_rect->x; | |
129 | + | |
130 | + for (x = 0; x < dst_rect->w; x++) { | |
131 | + | |
132 | + /* Interpolate colours */ | |
133 | + ex = (*csax & 0xffff); | |
134 | + ey = (*csay & 0xffff); | |
135 | + t1 = ((((getRed(*c01) - getRed(*c00)) * ex) >> 16) + | |
136 | + getRed(*c00)) & (dpf->Rmask >> dpf->Rshift); | |
137 | + t2 = ((((getRed(*c11) - getRed(*c10)) * ex) >> 16) + | |
138 | + getRed(*c10)) & (dpf->Rmask >> dpf->Rshift); | |
139 | + setRed((((t2 - t1) * ey) >> 16) + t1, dp); | |
140 | + t1 = ((((getGreen(*c01) - getGreen(*c00)) * ex) >> 16) + | |
141 | + getGreen(*c00)) & (dpf->Gmask >> dpf->Gshift); | |
142 | + t2 = ((((getGreen(*c11) - getGreen(*c10)) * ex) >> 16) + | |
143 | + getGreen(*c10)) & (dpf->Gmask >> dpf->Gshift); | |
144 | + setGreen((((t2 - t1) * ey) >> 16) + t1, dp); | |
145 | + t1 = ((((getBlue(*c01) - getBlue(*c00)) * ex) >> 16) + | |
146 | + getBlue(*c00)) & (dpf->Bmask >> dpf->Bshift); | |
147 | + t2 = ((((getBlue(*c11) - getBlue(*c10)) * ex) >> 16) + | |
148 | + getBlue(*c10)) & (dpf->Bmask >> dpf->Bshift); | |
149 | + setBlue((((t2 - t1) * ey) >> 16) + t1, dp); | |
150 | + t1 = ((((getAlpha(*c01) - getAlpha(*c00)) * ex) >> 16) + | |
151 | + getAlpha(*c00)) & (dpf->Amask >> dpf->Ashift); | |
152 | + t2 = ((((getAlpha(*c11) - getAlpha(*c10)) * ex) >> 16) + | |
153 | + getAlpha(*c10)) & (dpf->Amask >> dpf->Ashift); | |
154 | + setAlpha((((t2 - t1) * ey) >> 16) + t1, dp); | |
155 | + | |
156 | + /* Advance source pointers */ | |
157 | + csax++; | |
158 | + sstep = (*csax >> 16); | |
159 | + c00 += sstep; | |
160 | + c01 += sstep; | |
161 | + c10 += sstep; | |
162 | + c11 += sstep; | |
163 | + /* Advance destination pointer */ | |
164 | + dp++; | |
165 | + } | |
166 | + /* Advance source pointer */ | |
167 | + csay++; | |
168 | + csp = (SDL_TYPE *) ((Uint8 *) csp + (*csay >> 16) * src->pitch); | |
169 | + /* Advance destination pointers */ | |
170 | + dp = (SDL_TYPE *) ((Uint8 *) dp + d_gap); | |
171 | + } | |
172 | + | |
173 | + | |
174 | + } else { | |
175 | + csay = say; | |
176 | + | |
177 | + for (y = 0; y < dst_rect->y; y++) { | |
178 | + csay++; | |
179 | + sstep = (*csay >> 16) * src->pitch; | |
180 | + csp = (SDL_TYPE *) ((Uint8 *) csp + sstep); | |
181 | + } | |
182 | + | |
183 | + /* Calculate sstep_jump */ | |
184 | + csax = sax; | |
185 | + sstep_jump = 0; | |
186 | + for (x = 0; x < dst_rect->x; x++) { | |
187 | + csax++; | |
188 | + sstep = (*csax >> 16); | |
189 | + sstep_jump += sstep; | |
190 | + } | |
191 | + | |
192 | + for (y = 0 ; y < dst_rect->h ; y++) { | |
193 | + sp = csp + sstep_jump; | |
194 | + csax = sax + dst_rect->x; | |
195 | + | |
196 | + for (x = 0; x < dst_rect->w; x++) { | |
197 | + | |
198 | + /* Draw */ | |
199 | + *dp = *sp; | |
200 | + | |
201 | + /* Advance source pointers */ | |
202 | + csax++; | |
203 | + sstep = (*csax >> 16); | |
204 | + sp += sstep; | |
205 | + | |
206 | + /* Advance destination pointer */ | |
207 | + dp++; | |
208 | + } | |
209 | + /* Advance source pointers */ | |
210 | + csay++; | |
211 | + sstep = (*csay >> 16) * src->pitch; | |
212 | + csp = (SDL_TYPE *) ((Uint8 *) csp + sstep); | |
213 | + | |
214 | + /* Advance destination pointer */ | |
215 | + dp = (SDL_TYPE *) ((Uint8 *) dp + d_gap); | |
216 | + } | |
217 | + } | |
218 | + | |
219 | + free(sax); | |
220 | + free(say); | |
221 | + return (0); | |
222 | +} | |
223 | + | |
224 | +#undef SDL_TYPE | |
225 | + | ... | ... |