Mercurial > sdl-ios-xcode
annotate src/video/SDL_RLEaccel.c @ 821:30168104389f
Date: Sat, 14 Feb 2004 14:52:40 +0200
From: "Mike Gorchak"
Subject: Batch of the QNX6 fixes for the SDL
1. Updated readme.QNX
2. Fixed crashes during intensive window updating under fast machines (got over 200 rectangles for update).
3. Fixed double-buffered fullscreen modes, now it works as needed.
4. Fixed Photon detection algorithm.
5. Fixed HWSURFACE update function.
6. Added SDL_PHOTON_FULLSCREEN_REFRESH environment variable support for control refresh rates under Photon.
7. Added 640x400 fullscreen mode emulation via 640x480 (if videodriver not supports original 640x400 mode of course) shifted by 40 vertical pixels from begin, to center it. It's needed for some old DOS games which ran in doubled 320x200 mode.
8. Added available video ram amount support.
8. Added hardware surface allocation/deallocation support if current videomode and videodriver supports it.
9. Added hardware filling support.
10. Added hardware blits support (simple and colorkeyed).
And I've added to testvidinfo test color-keyed blits benchmark (maybe need to add alpha blits benchmark too ?). Currently Photon not supporting any alpha hardware blittings (all drivers lack of alpha blitting code support, only software alpha blitting exist in photon, which is hundreds times slowest than the SDL's one). So I've not added the alpha support. I suppose new QNX 6.3 will have the hardware alpha support, so when it will be done, I'll add alpha support.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 14 Feb 2004 20:22:21 +0000 |
parents | b8d311d90021 |
children | 2bacec7930b1 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
739
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
1
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* | |
29 * RLE encoding for software colorkey and alpha-channel acceleration | |
30 * | |
31 * Original version by Sam Lantinga | |
32 * | |
33 * Mattias Engdegård (Yorick): Rewrite. New encoding format, encoder and | |
34 * decoder. Added per-surface alpha blitter. Added per-pixel alpha | |
35 * format, encoder and blitter. | |
36 * | |
37 * Many thanks to Xark and johns for hints, benchmarks and useful comments | |
38 * leading to this code. | |
39 * | |
40 * Welcome to Macro Mayhem. | |
41 */ | |
42 | |
43 /* | |
44 * The encoding translates the image data to a stream of segments of the form | |
45 * | |
46 * <skip> <run> <data> | |
47 * | |
48 * where <skip> is the number of transparent pixels to skip, | |
49 * <run> is the number of opaque pixels to blit, | |
50 * and <data> are the pixels themselves. | |
51 * | |
52 * This basic structure is used both for colorkeyed surfaces, used for simple | |
53 * binary transparency and for per-surface alpha blending, and for surfaces | |
54 * with per-pixel alpha. The details differ, however: | |
55 * | |
56 * Encoding of colorkeyed surfaces: | |
57 * | |
58 * Encoded pixels always have the same format as the target surface. | |
59 * <skip> and <run> are unsigned 8 bit integers, except for 32 bit depth | |
60 * where they are 16 bit. This makes the pixel data aligned at all times. | |
61 * Segments never wrap around from one scan line to the next. | |
62 * | |
63 * The end of the sequence is marked by a zero <skip>,<run> pair at the * | |
64 * beginning of a line. | |
65 * | |
66 * Encoding of surfaces with per-pixel alpha: | |
67 * | |
68 * The sequence begins with a struct RLEDestFormat describing the target | |
69 * pixel format, to provide reliable un-encoding. | |
70 * | |
71 * Each scan line is encoded twice: First all completely opaque pixels, | |
72 * encoded in the target format as described above, and then all | |
73 * partially transparent (translucent) pixels (where 1 <= alpha <= 254), | |
74 * in the following 32-bit format: | |
75 * | |
76 * For 32-bit targets, each pixel has the target RGB format but with | |
77 * the alpha value occupying the highest 8 bits. The <skip> and <run> | |
78 * counts are 16 bit. | |
79 * | |
80 * For 16-bit targets, each pixel has the target RGB format, but with | |
81 * the middle component (usually green) shifted 16 steps to the left, | |
82 * and the hole filled with the 5 most significant bits of the alpha value. | |
83 * i.e. if the target has the format rrrrrggggggbbbbb, | |
84 * the encoded pixel will be 00000gggggg00000rrrrr0aaaaabbbbb. | |
85 * The <skip> and <run> counts are 8 bit for the opaque lines, 16 bit | |
86 * for the translucent lines. Two padding bytes may be inserted | |
87 * before each translucent line to keep them 32-bit aligned. | |
88 * | |
89 * The end of the sequence is marked by a zero <skip>,<run> pair at the | |
90 * beginning of an opaque line. | |
91 */ | |
92 | |
93 #include <stdio.h> | |
94 #include <stdlib.h> | |
95 #include <string.h> | |
96 | |
97 #include "SDL_types.h" | |
98 #include "SDL_video.h" | |
99 #include "SDL_error.h" | |
100 #include "SDL_sysvideo.h" | |
101 #include "SDL_blit.h" | |
102 #include "SDL_memops.h" | |
103 #include "SDL_RLEaccel_c.h" | |
104 | |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
105 #if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
106 #include "mmx.h" |
739
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
689
diff
changeset
|
107 #include "SDL_cpuinfo.h" |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
108 #endif |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
109 |
0 | 110 #ifndef MAX |
111 #define MAX(a, b) ((a) > (b) ? (a) : (b)) | |
112 #endif | |
113 #ifndef MIN | |
114 #define MIN(a, b) ((a) < (b) ? (a) : (b)) | |
115 #endif | |
116 | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
117 #define PIXEL_COPY(to, from, len, bpp) \ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
118 do { \ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
119 if(bpp == 4) { \ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
120 SDL_memcpy4(to, from, (unsigned)(len)); \ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
121 } else { \ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
122 SDL_memcpy(to, from, (unsigned)(len) * (bpp)); \ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
123 } \ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
124 } while(0) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
125 |
0 | 126 /* |
127 * Various colorkey blit methods, for opaque and per-surface alpha | |
128 */ | |
129 | |
130 #define OPAQUE_BLIT(to, from, length, bpp, alpha) \ | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
131 PIXEL_COPY(to, from, length, bpp) |
0 | 132 |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
133 #if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
134 |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
135 #define ALPHA_BLIT32_888MMX(to, from, length, bpp, alpha) \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
136 do { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
137 Uint32 *srcp = (Uint32 *)(from); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
138 Uint32 *dstp = (Uint32 *)(to); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
139 int i = 0x00FF00FF; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
140 movd_m2r(*(&i), mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
141 punpckldq_r2r(mm3, mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
142 i = 0xFF000000; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
143 movd_m2r(*(&i), mm7); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
144 punpckldq_r2r(mm7, mm7); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
145 i = alpha | alpha << 16; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
146 movd_m2r(*(&i), mm4); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
147 punpckldq_r2r(mm4, mm4); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
148 pcmpeqd_r2r(mm5,mm5); /* set mm5 to "1" */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
149 pxor_r2r(mm7, mm5); /* make clear alpha mask */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
150 i = length; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
151 if(i & 1) { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
152 movd_m2r((*srcp), mm1); /* src -> mm1 */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
153 punpcklbw_r2r(mm1, mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
154 pand_r2r(mm3, mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
155 movd_m2r((*dstp), mm2); /* dst -> mm2 */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
156 punpcklbw_r2r(mm2, mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
157 pand_r2r(mm3, mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
158 psubw_r2r(mm2, mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
159 pmullw_r2r(mm4, mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
160 psrlw_i2r(8, mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
161 paddw_r2r(mm1, mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
162 pand_r2r(mm3, mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
163 packuswb_r2r(mm2, mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
164 pand_r2r(mm5, mm2); /* 00000RGB -> mm2 */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
165 movd_r2m(mm2, *dstp); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
166 ++srcp; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
167 ++dstp; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
168 i--; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
169 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
170 for(; i > 0; --i) { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
171 movq_m2r((*srcp), mm0); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
172 movq_r2r(mm0, mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
173 punpcklbw_r2r(mm0, mm0); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
174 movq_m2r((*dstp), mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
175 punpckhbw_r2r(mm1, mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
176 movq_r2r(mm2, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
177 pand_r2r(mm3, mm0); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
178 punpcklbw_r2r(mm2, mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
179 pand_r2r(mm3, mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
180 punpckhbw_r2r(mm6, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
181 pand_r2r(mm3, mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
182 psubw_r2r(mm2, mm0); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
183 pmullw_r2r(mm4, mm0); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
184 pand_r2r(mm3, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
185 psubw_r2r(mm6, mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
186 pmullw_r2r(mm4, mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
187 psrlw_i2r(8, mm0); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
188 paddw_r2r(mm0, mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
189 psrlw_i2r(8, mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
190 paddw_r2r(mm1, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
191 pand_r2r(mm3, mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
192 pand_r2r(mm3, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
193 packuswb_r2r(mm2, mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
194 packuswb_r2r(mm6, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
195 psrlq_i2r(32, mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
196 psllq_i2r(32, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
197 por_r2r(mm6, mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
198 pand_r2r(mm5, mm2); /* 00000RGB -> mm2 */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
199 movq_r2m(mm2, *dstp); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
200 srcp += 2; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
201 dstp += 2; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
202 i--; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
203 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
204 emms(); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
205 } while(0) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
206 |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
207 #define ALPHA_BLIT16_565MMX(to, from, length, bpp, alpha) \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
208 do { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
209 int i, n = 0; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
210 Uint16 *srcp = (Uint16 *)(from); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
211 Uint16 *dstp = (Uint16 *)(to); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
212 Uint32 ALPHA = 0xF800; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
213 movd_m2r(*(&ALPHA), mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
214 punpcklwd_r2r(mm1, mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
215 punpcklwd_r2r(mm1, mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
216 ALPHA = 0x07E0; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
217 movd_m2r(*(&ALPHA), mm4); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
218 punpcklwd_r2r(mm4, mm4); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
219 punpcklwd_r2r(mm4, mm4); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
220 ALPHA = 0x001F; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
221 movd_m2r(*(&ALPHA), mm7); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
222 punpcklwd_r2r(mm7, mm7); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
223 punpcklwd_r2r(mm7, mm7); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
224 alpha &= ~(1+2+4); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
225 i = (Uint32)alpha | (Uint32)alpha << 16; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
226 movd_m2r(*(&i), mm0); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
227 punpckldq_r2r(mm0, mm0); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
228 ALPHA = alpha >> 3; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
229 i = ((int)(length) & 3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
230 for(; i > 0; --i) { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
231 Uint32 s = *srcp++; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
232 Uint32 d = *dstp; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
233 s = (s | s << 16) & 0x07e0f81f; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
234 d = (d | d << 16) & 0x07e0f81f; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
235 d += (s - d) * ALPHA >> 5; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
236 d &= 0x07e0f81f; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
237 *dstp++ = d | d >> 16; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
238 n++; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
239 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
240 i = (int)(length) - n; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
241 for(; i > 0; --i) { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
242 movq_m2r((*dstp), mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
243 movq_m2r((*srcp), mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
244 movq_r2r(mm2, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
245 pand_r2r(mm1 , mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
246 psrlq_i2r(11, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
247 movq_r2r(mm3, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
248 pand_r2r(mm1 , mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
249 psrlq_i2r(11, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
250 psubw_r2r(mm6, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
251 pmullw_r2r(mm0, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
252 psrlw_i2r(8, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
253 paddw_r2r(mm5, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
254 psllq_i2r(11, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
255 pand_r2r(mm1, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
256 movq_r2r(mm4, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
257 por_r2r(mm7, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
258 pand_r2r(mm5, mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
259 por_r2r(mm6, mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
260 movq_r2r(mm2, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
261 pand_r2r(mm4 , mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
262 psrlq_i2r(5, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
263 movq_r2r(mm3, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
264 pand_r2r(mm4 , mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
265 psrlq_i2r(5, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
266 psubw_r2r(mm6, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
267 pmullw_r2r(mm0, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
268 psrlw_i2r(8, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
269 paddw_r2r(mm5, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
270 psllq_i2r(5, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
271 pand_r2r(mm4, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
272 movq_r2r(mm1, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
273 por_r2r(mm7, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
274 pand_r2r(mm5, mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
275 por_r2r(mm6, mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
276 movq_r2r(mm2, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
277 pand_r2r(mm7 , mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
278 movq_r2r(mm3, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
279 pand_r2r(mm7 , mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
280 psubw_r2r(mm6, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
281 pmullw_r2r(mm0, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
282 psrlw_i2r(8, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
283 paddw_r2r(mm5, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
284 pand_r2r(mm7, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
285 movq_r2r(mm1, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
286 por_r2r(mm4, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
287 pand_r2r(mm5, mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
288 por_r2r(mm6, mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
289 movq_r2m(mm3, *dstp); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
290 srcp += 4; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
291 dstp += 4; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
292 i -= 3; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
293 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
294 emms(); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
295 } while(0) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
296 |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
297 #define ALPHA_BLIT16_555MMX(to, from, length, bpp, alpha) \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
298 do { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
299 int i, n = 0; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
300 Uint16 *srcp = (Uint16 *)(from); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
301 Uint16 *dstp = (Uint16 *)(to); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
302 Uint32 ALPHA = 0x7C00; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
303 movd_m2r(*(&ALPHA), mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
304 punpcklwd_r2r(mm1, mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
305 punpcklwd_r2r(mm1, mm1); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
306 ALPHA = 0x03E0; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
307 movd_m2r(*(&ALPHA), mm4); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
308 punpcklwd_r2r(mm4, mm4); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
309 punpcklwd_r2r(mm4, mm4); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
310 ALPHA = 0x001F; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
311 movd_m2r(*(&ALPHA), mm7); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
312 punpcklwd_r2r(mm7, mm7); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
313 punpcklwd_r2r(mm7, mm7); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
314 alpha &= ~(1+2+4); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
315 i = (Uint32)alpha | (Uint32)alpha << 16; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
316 movd_m2r(*(&i), mm0); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
317 punpckldq_r2r(mm0, mm0); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
318 i = ((int)(length) & 3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
319 ALPHA = alpha >> 3; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
320 for(; i > 0; --i) { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
321 Uint32 s = *srcp++; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
322 Uint32 d = *dstp; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
323 s = (s | s << 16) & 0x03e07c1f; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
324 d = (d | d << 16) & 0x03e07c1f; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
325 d += (s - d) * ALPHA >> 5; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
326 d &= 0x03e07c1f; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
327 *dstp++ = d | d >> 16; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
328 n++; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
329 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
330 i = (int)(length) - n; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
331 for(; i > 0; --i) { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
332 movq_m2r((*dstp), mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
333 movq_m2r((*srcp), mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
334 movq_r2r(mm2, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
335 pand_r2r(mm1 , mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
336 psrlq_i2r(10, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
337 movq_r2r(mm3, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
338 pand_r2r(mm1 , mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
339 psrlq_i2r(10, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
340 psubw_r2r(mm6, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
341 pmullw_r2r(mm0, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
342 psrlw_i2r(8, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
343 paddw_r2r(mm5, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
344 psllq_i2r(10, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
345 pand_r2r(mm1, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
346 movq_r2r(mm4, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
347 por_r2r(mm7, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
348 pand_r2r(mm5, mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
349 por_r2r(mm6, mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
350 movq_r2r(mm2, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
351 pand_r2r(mm4 , mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
352 psrlq_i2r(5, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
353 movq_r2r(mm3, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
354 pand_r2r(mm4 , mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
355 psrlq_i2r(5, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
356 psubw_r2r(mm6, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
357 pmullw_r2r(mm0, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
358 psrlw_i2r(8, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
359 paddw_r2r(mm5, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
360 psllq_i2r(5, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
361 pand_r2r(mm4, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
362 movq_r2r(mm1, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
363 por_r2r(mm7, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
364 pand_r2r(mm5, mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
365 por_r2r(mm6, mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
366 movq_r2r(mm2, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
367 pand_r2r(mm7 , mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
368 movq_r2r(mm3, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
369 pand_r2r(mm7 , mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
370 psubw_r2r(mm6, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
371 pmullw_r2r(mm0, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
372 psrlw_i2r(8, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
373 paddw_r2r(mm5, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
374 pand_r2r(mm7, mm6); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
375 movq_r2r(mm1, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
376 por_r2r(mm4, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
377 pand_r2r(mm5, mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
378 por_r2r(mm6, mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
379 movq_r2m(mm3, *dstp); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
380 srcp += 4; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
381 dstp += 4; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
382 i -= 3; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
383 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
384 emms(); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
385 } while(0) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
386 |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
387 #endif |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
388 |
0 | 389 /* |
390 * For 32bpp pixels on the form 0x00rrggbb: | |
391 * If we treat the middle component separately, we can process the two | |
392 * remaining in parallel. This is safe to do because of the gap to the left | |
393 * of each component, so the bits from the multiplication don't collide. | |
394 * This can be used for any RGB permutation of course. | |
395 */ | |
396 #define ALPHA_BLIT32_888(to, from, length, bpp, alpha) \ | |
397 do { \ | |
398 int i; \ | |
399 Uint32 *src = (Uint32 *)(from); \ | |
400 Uint32 *dst = (Uint32 *)(to); \ | |
401 for(i = 0; i < (int)(length); i++) { \ | |
402 Uint32 s = *src++; \ | |
403 Uint32 d = *dst; \ | |
404 Uint32 s1 = s & 0xff00ff; \ | |
405 Uint32 d1 = d & 0xff00ff; \ | |
406 d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \ | |
407 s &= 0xff00; \ | |
408 d &= 0xff00; \ | |
409 d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ | |
410 *dst++ = d1 | d; \ | |
411 } \ | |
412 } while(0) | |
413 | |
414 /* | |
415 * For 16bpp pixels we can go a step further: put the middle component | |
416 * in the high 16 bits of a 32 bit word, and process all three RGB | |
417 * components at the same time. Since the smallest gap is here just | |
418 * 5 bits, we have to scale alpha down to 5 bits as well. | |
419 */ | |
420 #define ALPHA_BLIT16_565(to, from, length, bpp, alpha) \ | |
421 do { \ | |
422 int i; \ | |
423 Uint16 *src = (Uint16 *)(from); \ | |
424 Uint16 *dst = (Uint16 *)(to); \ | |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
425 Uint32 ALPHA = alpha >> 3; \ |
0 | 426 for(i = 0; i < (int)(length); i++) { \ |
427 Uint32 s = *src++; \ | |
428 Uint32 d = *dst; \ | |
429 s = (s | s << 16) & 0x07e0f81f; \ | |
430 d = (d | d << 16) & 0x07e0f81f; \ | |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
431 d += (s - d) * ALPHA >> 5; \ |
0 | 432 d &= 0x07e0f81f; \ |
433 *dst++ = d | d >> 16; \ | |
434 } \ | |
435 } while(0) | |
436 | |
437 #define ALPHA_BLIT16_555(to, from, length, bpp, alpha) \ | |
438 do { \ | |
439 int i; \ | |
440 Uint16 *src = (Uint16 *)(from); \ | |
441 Uint16 *dst = (Uint16 *)(to); \ | |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
442 Uint32 ALPHA = alpha >> 3; \ |
0 | 443 for(i = 0; i < (int)(length); i++) { \ |
444 Uint32 s = *src++; \ | |
445 Uint32 d = *dst; \ | |
446 s = (s | s << 16) & 0x03e07c1f; \ | |
447 d = (d | d << 16) & 0x03e07c1f; \ | |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
448 d += (s - d) * ALPHA >> 5; \ |
0 | 449 d &= 0x03e07c1f; \ |
450 *dst++ = d | d >> 16; \ | |
451 } \ | |
452 } while(0) | |
453 | |
454 /* | |
455 * The general slow catch-all function, for remaining depths and formats | |
456 */ | |
457 #define ALPHA_BLIT_ANY(to, from, length, bpp, alpha) \ | |
458 do { \ | |
459 int i; \ | |
460 Uint8 *src = from; \ | |
461 Uint8 *dst = to; \ | |
462 for(i = 0; i < (int)(length); i++) { \ | |
463 Uint32 s, d; \ | |
464 unsigned rs, gs, bs, rd, gd, bd; \ | |
465 switch(bpp) { \ | |
466 case 2: \ | |
467 s = *(Uint16 *)src; \ | |
468 d = *(Uint16 *)dst; \ | |
469 break; \ | |
470 case 3: \ | |
471 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ | |
472 s = (src[0] << 16) | (src[1] << 8) | src[2]; \ | |
473 d = (dst[0] << 16) | (dst[1] << 8) | dst[2]; \ | |
474 } else { \ | |
475 s = (src[2] << 16) | (src[1] << 8) | src[0]; \ | |
476 d = (dst[2] << 16) | (dst[1] << 8) | dst[0]; \ | |
477 } \ | |
478 break; \ | |
479 case 4: \ | |
480 s = *(Uint32 *)src; \ | |
481 d = *(Uint32 *)dst; \ | |
482 break; \ | |
483 } \ | |
484 RGB_FROM_PIXEL(s, fmt, rs, gs, bs); \ | |
485 RGB_FROM_PIXEL(d, fmt, rd, gd, bd); \ | |
486 rd += (rs - rd) * alpha >> 8; \ | |
487 gd += (gs - gd) * alpha >> 8; \ | |
488 bd += (bs - bd) * alpha >> 8; \ | |
489 PIXEL_FROM_RGB(d, fmt, rd, gd, bd); \ | |
490 switch(bpp) { \ | |
491 case 2: \ | |
492 *(Uint16 *)dst = d; \ | |
493 break; \ | |
494 case 3: \ | |
495 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ | |
496 dst[0] = d >> 16; \ | |
497 dst[1] = d >> 8; \ | |
498 dst[2] = d; \ | |
499 } else { \ | |
500 dst[0] = d; \ | |
501 dst[1] = d >> 8; \ | |
502 dst[2] = d >> 16; \ | |
503 } \ | |
504 break; \ | |
505 case 4: \ | |
506 *(Uint32 *)dst = d; \ | |
507 break; \ | |
508 } \ | |
509 src += bpp; \ | |
510 dst += bpp; \ | |
511 } \ | |
512 } while(0) | |
513 | |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
514 #if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) |
0 | 515 |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
516 #define ALPHA_BLIT32_888_50MMX(to, from, length, bpp, alpha) \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
517 do { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
518 Uint32 *srcp = (Uint32 *)(from); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
519 Uint32 *dstp = (Uint32 *)(to); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
520 int i = 0x00fefefe; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
521 movd_m2r(*(&i), mm4); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
522 punpckldq_r2r(mm4, mm4); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
523 i = 0x00010101; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
524 movd_m2r(*(&i), mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
525 punpckldq_r2r(mm3, mm3); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
526 i = (int)(length); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
527 if( i & 1 ) { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
528 Uint32 s = *srcp++; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
529 Uint32 d = *dstp; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
530 *dstp++ = (((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
531 + (s & d & 0x00010101); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
532 i--; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
533 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
534 for(; i > 0; --i) { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
535 movq_m2r((*dstp), mm2); /* dst -> mm2 */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
536 movq_r2r(mm2, mm6); /* dst -> mm6 */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
537 movq_m2r((*srcp), mm1); /* src -> mm1 */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
538 movq_r2r(mm1, mm5); /* src -> mm5 */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
539 pand_r2r(mm4, mm6); /* dst & 0x00fefefe -> mm6 */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
540 pand_r2r(mm4, mm5); /* src & 0x00fefefe -> mm5 */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
541 paddd_r2r(mm6, mm5); /* (dst & 0x00fefefe) + (dst & 0x00fefefe) -> mm5 */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
542 psrld_i2r(1, mm5); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
543 pand_r2r(mm1, mm2); /* s & d -> mm2 */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
544 pand_r2r(mm3, mm2); /* s & d & 0x00010101 -> mm2 */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
545 paddd_r2r(mm5, mm2); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
546 movq_r2m(mm2, (*dstp)); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
547 dstp += 2; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
548 srcp += 2; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
549 i--; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
550 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
551 emms(); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
552 } while(0) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
553 |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
554 #endif |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
555 |
0 | 556 /* |
557 * Special case: 50% alpha (alpha=128) | |
558 * This is treated specially because it can be optimized very well, and | |
559 * since it is good for many cases of semi-translucency. | |
560 * The theory is to do all three components at the same time: | |
561 * First zero the lowest bit of each component, which gives us room to | |
562 * add them. Then shift right and add the sum of the lowest bits. | |
563 */ | |
564 #define ALPHA_BLIT32_888_50(to, from, length, bpp, alpha) \ | |
565 do { \ | |
566 int i; \ | |
567 Uint32 *src = (Uint32 *)(from); \ | |
568 Uint32 *dst = (Uint32 *)(to); \ | |
569 for(i = 0; i < (int)(length); i++) { \ | |
570 Uint32 s = *src++; \ | |
571 Uint32 d = *dst; \ | |
572 *dst++ = (((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) \ | |
573 + (s & d & 0x00010101); \ | |
574 } \ | |
575 } while(0) | |
576 | |
577 /* | |
578 * For 16bpp, we can actually blend two pixels in parallel, if we take | |
579 * care to shift before we add, not after. | |
580 */ | |
581 | |
582 /* helper: blend a single 16 bit pixel at 50% */ | |
583 #define BLEND16_50(dst, src, mask) \ | |
584 do { \ | |
585 Uint32 s = *src++; \ | |
586 Uint32 d = *dst; \ | |
587 *dst++ = (((s & mask) + (d & mask)) >> 1) \ | |
588 + (s & d & (~mask & 0xffff)); \ | |
589 } while(0) | |
590 | |
591 /* basic 16bpp blender. mask is the pixels to keep when adding. */ | |
592 #define ALPHA_BLIT16_50(to, from, length, bpp, alpha, mask) \ | |
593 do { \ | |
594 unsigned n = (length); \ | |
595 Uint16 *src = (Uint16 *)(from); \ | |
596 Uint16 *dst = (Uint16 *)(to); \ | |
597 if(((unsigned long)src ^ (unsigned long)dst) & 3) { \ | |
598 /* source and destination not in phase, blit one by one */ \ | |
599 while(n--) \ | |
600 BLEND16_50(dst, src, mask); \ | |
601 } else { \ | |
602 if((unsigned long)src & 3) { \ | |
603 /* first odd pixel */ \ | |
604 BLEND16_50(dst, src, mask); \ | |
605 n--; \ | |
606 } \ | |
607 for(; n > 1; n -= 2) { \ | |
608 Uint32 s = *(Uint32 *)src; \ | |
609 Uint32 d = *(Uint32 *)dst; \ | |
610 *(Uint32 *)dst = ((s & (mask | mask << 16)) >> 1) \ | |
611 + ((d & (mask | mask << 16)) >> 1) \ | |
612 + (s & d & (~(mask | mask << 16))); \ | |
613 src += 2; \ | |
614 dst += 2; \ | |
615 } \ | |
616 if(n) \ | |
617 BLEND16_50(dst, src, mask); /* last odd pixel */ \ | |
618 } \ | |
619 } while(0) | |
620 | |
621 #define ALPHA_BLIT16_565_50(to, from, length, bpp, alpha) \ | |
622 ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xf7de) | |
623 | |
624 #define ALPHA_BLIT16_555_50(to, from, length, bpp, alpha) \ | |
625 ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xfbde) | |
626 | |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
627 #if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) |
0 | 628 |
629 #define CHOOSE_BLIT(blitter, alpha, fmt) \ | |
630 do { \ | |
631 if(alpha == 255) { \ | |
632 switch(fmt->BytesPerPixel) { \ | |
633 case 1: blitter(1, Uint8, OPAQUE_BLIT); break; \ | |
634 case 2: blitter(2, Uint8, OPAQUE_BLIT); break; \ | |
635 case 3: blitter(3, Uint8, OPAQUE_BLIT); break; \ | |
636 case 4: blitter(4, Uint16, OPAQUE_BLIT); break; \ | |
637 } \ | |
638 } else { \ | |
639 switch(fmt->BytesPerPixel) { \ | |
640 case 1: \ | |
641 /* No 8bpp alpha blitting */ \ | |
642 break; \ | |
643 \ | |
644 case 2: \ | |
645 switch(fmt->Rmask | fmt->Gmask | fmt->Bmask) { \ | |
646 case 0xffff: \ | |
647 if(fmt->Gmask == 0x07e0 \ | |
648 || fmt->Rmask == 0x07e0 \ | |
649 || fmt->Bmask == 0x07e0) { \ | |
650 if(alpha == 128) \ | |
651 blitter(2, Uint8, ALPHA_BLIT16_565_50); \ | |
652 else { \ | |
739
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
689
diff
changeset
|
653 if(SDL_HasMMX()) \ |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
654 blitter(2, Uint8, ALPHA_BLIT16_565MMX); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
655 else \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
656 blitter(2, Uint8, ALPHA_BLIT16_565); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
657 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
658 } else \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
659 goto general16; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
660 break; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
661 \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
662 case 0x7fff: \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
663 if(fmt->Gmask == 0x03e0 \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
664 || fmt->Rmask == 0x03e0 \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
665 || fmt->Bmask == 0x03e0) { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
666 if(alpha == 128) \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
667 blitter(2, Uint8, ALPHA_BLIT16_555_50); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
668 else { \ |
739
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
689
diff
changeset
|
669 if(SDL_HasMMX()) \ |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
670 blitter(2, Uint8, ALPHA_BLIT16_555MMX); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
671 else \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
672 blitter(2, Uint8, ALPHA_BLIT16_555); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
673 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
674 break; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
675 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
676 /* fallthrough */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
677 \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
678 default: \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
679 general16: \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
680 blitter(2, Uint8, ALPHA_BLIT_ANY); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
681 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
682 break; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
683 \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
684 case 3: \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
685 blitter(3, Uint8, ALPHA_BLIT_ANY); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
686 break; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
687 \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
688 case 4: \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
689 if((fmt->Rmask | fmt->Gmask | fmt->Bmask) == 0x00ffffff \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
690 && (fmt->Gmask == 0xff00 || fmt->Rmask == 0xff00 \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
691 || fmt->Bmask == 0xff00)) { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
692 if(alpha == 128) \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
693 { \ |
739
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
689
diff
changeset
|
694 if(SDL_HasMMX()) \ |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
695 blitter(4, Uint16, ALPHA_BLIT32_888_50MMX);\ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
696 else \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
697 blitter(4, Uint16, ALPHA_BLIT32_888_50);\ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
698 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
699 else \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
700 { \ |
739
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
689
diff
changeset
|
701 if(SDL_HasMMX()) \ |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
702 blitter(4, Uint16, ALPHA_BLIT32_888MMX);\ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
703 else \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
704 blitter(4, Uint16, ALPHA_BLIT32_888); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
705 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
706 } else \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
707 blitter(4, Uint16, ALPHA_BLIT_ANY); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
708 break; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
709 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
710 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
711 } while(0) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
712 |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
713 #else |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
714 |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
715 #define CHOOSE_BLIT(blitter, alpha, fmt) \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
716 do { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
717 if(alpha == 255) { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
718 switch(fmt->BytesPerPixel) { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
719 case 1: blitter(1, Uint8, OPAQUE_BLIT); break; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
720 case 2: blitter(2, Uint8, OPAQUE_BLIT); break; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
721 case 3: blitter(3, Uint8, OPAQUE_BLIT); break; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
722 case 4: blitter(4, Uint16, OPAQUE_BLIT); break; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
723 } \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
724 } else { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
725 switch(fmt->BytesPerPixel) { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
726 case 1: \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
727 /* No 8bpp alpha blitting */ \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
728 break; \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
729 \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
730 case 2: \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
731 switch(fmt->Rmask | fmt->Gmask | fmt->Bmask) { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
732 case 0xffff: \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
733 if(fmt->Gmask == 0x07e0 \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
734 || fmt->Rmask == 0x07e0 \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
735 || fmt->Bmask == 0x07e0) { \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
736 if(alpha == 128) \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
737 blitter(2, Uint8, ALPHA_BLIT16_565_50); \ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
738 else { \ |
0 | 739 blitter(2, Uint8, ALPHA_BLIT16_565); \ |
740 } \ | |
741 } else \ | |
742 goto general16; \ | |
743 break; \ | |
744 \ | |
745 case 0x7fff: \ | |
746 if(fmt->Gmask == 0x03e0 \ | |
747 || fmt->Rmask == 0x03e0 \ | |
748 || fmt->Bmask == 0x03e0) { \ | |
749 if(alpha == 128) \ | |
750 blitter(2, Uint8, ALPHA_BLIT16_555_50); \ | |
751 else { \ | |
752 blitter(2, Uint8, ALPHA_BLIT16_555); \ | |
753 } \ | |
754 break; \ | |
755 } \ | |
756 /* fallthrough */ \ | |
757 \ | |
758 default: \ | |
759 general16: \ | |
760 blitter(2, Uint8, ALPHA_BLIT_ANY); \ | |
761 } \ | |
762 break; \ | |
763 \ | |
764 case 3: \ | |
765 blitter(3, Uint8, ALPHA_BLIT_ANY); \ | |
766 break; \ | |
767 \ | |
768 case 4: \ | |
769 if((fmt->Rmask | fmt->Gmask | fmt->Bmask) == 0x00ffffff \ | |
770 && (fmt->Gmask == 0xff00 || fmt->Rmask == 0xff00 \ | |
771 || fmt->Bmask == 0xff00)) { \ | |
772 if(alpha == 128) \ | |
773 blitter(4, Uint16, ALPHA_BLIT32_888_50); \ | |
774 else \ | |
775 blitter(4, Uint16, ALPHA_BLIT32_888); \ | |
776 } else \ | |
777 blitter(4, Uint16, ALPHA_BLIT_ANY); \ | |
778 break; \ | |
779 } \ | |
780 } \ | |
781 } while(0) | |
782 | |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
783 #endif |
0 | 784 |
785 /* | |
786 * This takes care of the case when the surface is clipped on the left and/or | |
787 * right. Top clipping has already been taken care of. | |
788 */ | |
789 static void RLEClipBlit(int w, Uint8 *srcbuf, SDL_Surface *dst, | |
790 Uint8 *dstbuf, SDL_Rect *srcrect, unsigned alpha) | |
791 { | |
792 SDL_PixelFormat *fmt = dst->format; | |
793 | |
794 #define RLECLIPBLIT(bpp, Type, do_blit) \ | |
795 do { \ | |
796 int linecount = srcrect->h; \ | |
797 int ofs = 0; \ | |
798 int left = srcrect->x; \ | |
799 int right = left + srcrect->w; \ | |
800 dstbuf -= left * bpp; \ | |
801 for(;;) { \ | |
802 int run; \ | |
803 ofs += *(Type *)srcbuf; \ | |
804 run = ((Type *)srcbuf)[1]; \ | |
805 srcbuf += 2 * sizeof(Type); \ | |
806 if(run) { \ | |
807 /* clip to left and right borders */ \ | |
808 if(ofs < right) { \ | |
809 int start = 0; \ | |
810 int len = run; \ | |
811 int startcol; \ | |
812 if(left - ofs > 0) { \ | |
813 start = left - ofs; \ | |
814 len -= start; \ | |
815 if(len <= 0) \ | |
816 goto nocopy ## bpp ## do_blit; \ | |
817 } \ | |
818 startcol = ofs + start; \ | |
819 if(len > right - startcol) \ | |
820 len = right - startcol; \ | |
821 do_blit(dstbuf + startcol * bpp, srcbuf + start * bpp, \ | |
822 len, bpp, alpha); \ | |
823 } \ | |
824 nocopy ## bpp ## do_blit: \ | |
825 srcbuf += run * bpp; \ | |
826 ofs += run; \ | |
827 } else if(!ofs) \ | |
828 break; \ | |
829 if(ofs == w) { \ | |
830 ofs = 0; \ | |
831 dstbuf += dst->pitch; \ | |
832 if(!--linecount) \ | |
833 break; \ | |
834 } \ | |
835 } \ | |
836 } while(0) | |
837 | |
838 CHOOSE_BLIT(RLECLIPBLIT, alpha, fmt); | |
839 | |
840 #undef RLECLIPBLIT | |
841 | |
842 } | |
843 | |
844 | |
845 /* blit a colorkeyed RLE surface */ | |
846 int SDL_RLEBlit(SDL_Surface *src, SDL_Rect *srcrect, | |
847 SDL_Surface *dst, SDL_Rect *dstrect) | |
848 { | |
849 Uint8 *dstbuf; | |
850 Uint8 *srcbuf; | |
851 int x, y; | |
852 int w = src->w; | |
853 unsigned alpha; | |
854 | |
855 /* Lock the destination if necessary */ | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
856 if ( SDL_MUSTLOCK(dst) ) { |
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
857 if ( SDL_LockSurface(dst) < 0 ) { |
0 | 858 return(-1); |
859 } | |
860 } | |
861 | |
862 /* Set up the source and destination pointers */ | |
863 x = dstrect->x; | |
864 y = dstrect->y; | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
865 dstbuf = (Uint8 *)dst->pixels |
0 | 866 + y * dst->pitch + x * src->format->BytesPerPixel; |
867 srcbuf = (Uint8 *)src->map->sw_data->aux_data; | |
868 | |
869 { | |
870 /* skip lines at the top if neccessary */ | |
871 int vskip = srcrect->y; | |
872 int ofs = 0; | |
873 if(vskip) { | |
874 | |
875 #define RLESKIP(bpp, Type) \ | |
876 for(;;) { \ | |
877 int run; \ | |
878 ofs += *(Type *)srcbuf; \ | |
879 run = ((Type *)srcbuf)[1]; \ | |
880 srcbuf += sizeof(Type) * 2; \ | |
881 if(run) { \ | |
882 srcbuf += run * bpp; \ | |
883 ofs += run; \ | |
884 } else if(!ofs) \ | |
885 goto done; \ | |
886 if(ofs == w) { \ | |
887 ofs = 0; \ | |
888 if(!--vskip) \ | |
889 break; \ | |
890 } \ | |
891 } | |
892 | |
893 switch(src->format->BytesPerPixel) { | |
894 case 1: RLESKIP(1, Uint8); break; | |
895 case 2: RLESKIP(2, Uint8); break; | |
896 case 3: RLESKIP(3, Uint8); break; | |
897 case 4: RLESKIP(4, Uint16); break; | |
898 } | |
899 | |
900 #undef RLESKIP | |
901 | |
902 } | |
903 } | |
904 | |
905 alpha = (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA | |
906 ? src->format->alpha : 255; | |
907 /* if left or right edge clipping needed, call clip blit */ | |
908 if ( srcrect->x || srcrect->w != src->w ) { | |
909 RLEClipBlit(w, srcbuf, dst, dstbuf, srcrect, alpha); | |
910 } else { | |
911 SDL_PixelFormat *fmt = src->format; | |
912 | |
913 #define RLEBLIT(bpp, Type, do_blit) \ | |
914 do { \ | |
915 int linecount = srcrect->h; \ | |
916 int ofs = 0; \ | |
917 for(;;) { \ | |
918 unsigned run; \ | |
919 ofs += *(Type *)srcbuf; \ | |
920 run = ((Type *)srcbuf)[1]; \ | |
921 srcbuf += 2 * sizeof(Type); \ | |
922 if(run) { \ | |
923 do_blit(dstbuf + ofs * bpp, srcbuf, run, bpp, alpha); \ | |
924 srcbuf += run * bpp; \ | |
925 ofs += run; \ | |
926 } else if(!ofs) \ | |
927 break; \ | |
928 if(ofs == w) { \ | |
929 ofs = 0; \ | |
930 dstbuf += dst->pitch; \ | |
931 if(!--linecount) \ | |
932 break; \ | |
933 } \ | |
934 } \ | |
935 } while(0) | |
936 | |
937 CHOOSE_BLIT(RLEBLIT, alpha, fmt); | |
938 | |
939 #undef RLEBLIT | |
940 } | |
941 | |
942 done: | |
943 /* Unlock the destination if necessary */ | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
944 if ( SDL_MUSTLOCK(dst) ) { |
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
945 SDL_UnlockSurface(dst); |
0 | 946 } |
947 return(0); | |
948 } | |
949 | |
950 #undef OPAQUE_BLIT | |
951 | |
952 /* | |
953 * Per-pixel blitting macros for translucent pixels: | |
954 * These use the same techniques as the per-surface blitting macros | |
955 */ | |
956 | |
957 /* | |
958 * For 32bpp pixels, we have made sure the alpha is stored in the top | |
959 * 8 bits, so proceed as usual | |
960 */ | |
961 #define BLIT_TRANSL_888(src, dst) \ | |
962 do { \ | |
963 Uint32 s = src; \ | |
964 Uint32 d = dst; \ | |
965 unsigned alpha = s >> 24; \ | |
966 Uint32 s1 = s & 0xff00ff; \ | |
967 Uint32 d1 = d & 0xff00ff; \ | |
968 d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \ | |
969 s &= 0xff00; \ | |
970 d &= 0xff00; \ | |
971 d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ | |
972 dst = d1 | d; \ | |
973 } while(0) | |
974 | |
975 /* | |
976 * For 16bpp pixels, we have stored the 5 most significant alpha bits in | |
977 * bits 5-10. As before, we can process all 3 RGB components at the same time. | |
978 */ | |
979 #define BLIT_TRANSL_565(src, dst) \ | |
980 do { \ | |
981 Uint32 s = src; \ | |
982 Uint32 d = dst; \ | |
983 unsigned alpha = (s & 0x3e0) >> 5; \ | |
984 s &= 0x07e0f81f; \ | |
985 d = (d | d << 16) & 0x07e0f81f; \ | |
986 d += (s - d) * alpha >> 5; \ | |
987 d &= 0x07e0f81f; \ | |
988 dst = d | d >> 16; \ | |
989 } while(0) | |
990 | |
991 #define BLIT_TRANSL_555(src, dst) \ | |
992 do { \ | |
993 Uint32 s = src; \ | |
994 Uint32 d = dst; \ | |
995 unsigned alpha = (s & 0x3e0) >> 5; \ | |
996 s &= 0x03e07c1f; \ | |
997 d = (d | d << 16) & 0x03e07c1f; \ | |
998 d += (s - d) * alpha >> 5; \ | |
999 d &= 0x03e07c1f; \ | |
1000 dst = d | d >> 16; \ | |
1001 } while(0) | |
1002 | |
1003 /* used to save the destination format in the encoding. Designed to be | |
1004 macro-compatible with SDL_PixelFormat but without the unneeded fields */ | |
1005 typedef struct { | |
1006 Uint8 BytesPerPixel; | |
1007 Uint8 Rloss; | |
1008 Uint8 Gloss; | |
1009 Uint8 Bloss; | |
1010 Uint8 Rshift; | |
1011 Uint8 Gshift; | |
1012 Uint8 Bshift; | |
1013 Uint8 Ashift; | |
1014 Uint32 Rmask; | |
1015 Uint32 Gmask; | |
1016 Uint32 Bmask; | |
1017 Uint32 Amask; | |
1018 } RLEDestFormat; | |
1019 | |
1020 /* blit a pixel-alpha RLE surface clipped at the right and/or left edges */ | |
1021 static void RLEAlphaClipBlit(int w, Uint8 *srcbuf, SDL_Surface *dst, | |
1022 Uint8 *dstbuf, SDL_Rect *srcrect) | |
1023 { | |
1024 SDL_PixelFormat *df = dst->format; | |
1025 /* | |
1026 * clipped blitter: Ptype is the destination pixel type, | |
1027 * Ctype the translucent count type, and do_blend the macro | |
1028 * to blend one pixel. | |
1029 */ | |
1030 #define RLEALPHACLIPBLIT(Ptype, Ctype, do_blend) \ | |
1031 do { \ | |
1032 int linecount = srcrect->h; \ | |
1033 int left = srcrect->x; \ | |
1034 int right = left + srcrect->w; \ | |
1035 dstbuf -= left * sizeof(Ptype); \ | |
1036 do { \ | |
1037 int ofs = 0; \ | |
1038 /* blit opaque pixels on one line */ \ | |
1039 do { \ | |
1040 unsigned run; \ | |
1041 ofs += ((Ctype *)srcbuf)[0]; \ | |
1042 run = ((Ctype *)srcbuf)[1]; \ | |
1043 srcbuf += 2 * sizeof(Ctype); \ | |
1044 if(run) { \ | |
1045 /* clip to left and right borders */ \ | |
1046 int cofs = ofs; \ | |
1047 int crun = run; \ | |
1048 if(left - cofs > 0) { \ | |
1049 crun -= left - cofs; \ | |
1050 cofs = left; \ | |
1051 } \ | |
1052 if(crun > right - cofs) \ | |
1053 crun = right - cofs; \ | |
1054 if(crun > 0) \ | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
1055 PIXEL_COPY(dstbuf + cofs * sizeof(Ptype), \ |
0 | 1056 srcbuf + (cofs - ofs) * sizeof(Ptype), \ |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
1057 (unsigned)crun, sizeof(Ptype)); \ |
0 | 1058 srcbuf += run * sizeof(Ptype); \ |
1059 ofs += run; \ | |
1060 } else if(!ofs) \ | |
1061 return; \ | |
1062 } while(ofs < w); \ | |
1063 /* skip padding if necessary */ \ | |
1064 if(sizeof(Ptype) == 2) \ | |
1065 srcbuf += (unsigned long)srcbuf & 2; \ | |
1066 /* blit translucent pixels on the same line */ \ | |
1067 ofs = 0; \ | |
1068 do { \ | |
1069 unsigned run; \ | |
1070 ofs += ((Uint16 *)srcbuf)[0]; \ | |
1071 run = ((Uint16 *)srcbuf)[1]; \ | |
1072 srcbuf += 4; \ | |
1073 if(run) { \ | |
1074 /* clip to left and right borders */ \ | |
1075 int cofs = ofs; \ | |
1076 int crun = run; \ | |
1077 if(left - cofs > 0) { \ | |
1078 crun -= left - cofs; \ | |
1079 cofs = left; \ | |
1080 } \ | |
1081 if(crun > right - cofs) \ | |
1082 crun = right - cofs; \ | |
1083 if(crun > 0) { \ | |
1084 Ptype *dst = (Ptype *)dstbuf + cofs; \ | |
1085 Uint32 *src = (Uint32 *)srcbuf + (cofs - ofs); \ | |
1086 int i; \ | |
1087 for(i = 0; i < crun; i++) \ | |
1088 do_blend(src[i], dst[i]); \ | |
1089 } \ | |
1090 srcbuf += run * 4; \ | |
1091 ofs += run; \ | |
1092 } \ | |
1093 } while(ofs < w); \ | |
1094 dstbuf += dst->pitch; \ | |
1095 } while(--linecount); \ | |
1096 } while(0) | |
1097 | |
1098 switch(df->BytesPerPixel) { | |
1099 case 2: | |
1100 if(df->Gmask == 0x07e0 || df->Rmask == 0x07e0 | |
1101 || df->Bmask == 0x07e0) | |
1102 RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_565); | |
1103 else | |
1104 RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_555); | |
1105 break; | |
1106 case 4: | |
1107 RLEALPHACLIPBLIT(Uint32, Uint16, BLIT_TRANSL_888); | |
1108 break; | |
1109 } | |
1110 } | |
1111 | |
1112 /* blit a pixel-alpha RLE surface */ | |
1113 int SDL_RLEAlphaBlit(SDL_Surface *src, SDL_Rect *srcrect, | |
1114 SDL_Surface *dst, SDL_Rect *dstrect) | |
1115 { | |
1116 int x, y; | |
1117 int w = src->w; | |
1118 Uint8 *srcbuf, *dstbuf; | |
1119 SDL_PixelFormat *df = dst->format; | |
1120 | |
1121 /* Lock the destination if necessary */ | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
1122 if ( SDL_MUSTLOCK(dst) ) { |
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
1123 if ( SDL_LockSurface(dst) < 0 ) { |
0 | 1124 return -1; |
1125 } | |
1126 } | |
1127 | |
1128 x = dstrect->x; | |
1129 y = dstrect->y; | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
1130 dstbuf = (Uint8 *)dst->pixels |
0 | 1131 + y * dst->pitch + x * df->BytesPerPixel; |
1132 srcbuf = (Uint8 *)src->map->sw_data->aux_data + sizeof(RLEDestFormat); | |
1133 | |
1134 { | |
1135 /* skip lines at the top if necessary */ | |
1136 int vskip = srcrect->y; | |
1137 if(vskip) { | |
1138 int ofs; | |
1139 if(df->BytesPerPixel == 2) { | |
1140 /* the 16/32 interleaved format */ | |
1141 do { | |
1142 /* skip opaque line */ | |
1143 ofs = 0; | |
1144 do { | |
1145 int run; | |
1146 ofs += srcbuf[0]; | |
1147 run = srcbuf[1]; | |
1148 srcbuf += 2; | |
1149 if(run) { | |
1150 srcbuf += 2 * run; | |
1151 ofs += run; | |
1152 } else if(!ofs) | |
1153 goto done; | |
1154 } while(ofs < w); | |
1155 | |
1156 /* skip padding */ | |
1157 srcbuf += (unsigned long)srcbuf & 2; | |
1158 | |
1159 /* skip translucent line */ | |
1160 ofs = 0; | |
1161 do { | |
1162 int run; | |
1163 ofs += ((Uint16 *)srcbuf)[0]; | |
1164 run = ((Uint16 *)srcbuf)[1]; | |
1165 srcbuf += 4 * (run + 1); | |
1166 ofs += run; | |
1167 } while(ofs < w); | |
1168 } while(--vskip); | |
1169 } else { | |
1170 /* the 32/32 interleaved format */ | |
1171 vskip <<= 1; /* opaque and translucent have same format */ | |
1172 do { | |
1173 ofs = 0; | |
1174 do { | |
1175 int run; | |
1176 ofs += ((Uint16 *)srcbuf)[0]; | |
1177 run = ((Uint16 *)srcbuf)[1]; | |
1178 srcbuf += 4; | |
1179 if(run) { | |
1180 srcbuf += 4 * run; | |
1181 ofs += run; | |
1182 } else if(!ofs) | |
1183 goto done; | |
1184 } while(ofs < w); | |
1185 } while(--vskip); | |
1186 } | |
1187 } | |
1188 } | |
1189 | |
1190 /* if left or right edge clipping needed, call clip blit */ | |
1191 if(srcrect->x || srcrect->w != src->w) { | |
1192 RLEAlphaClipBlit(w, srcbuf, dst, dstbuf, srcrect); | |
1193 } else { | |
1194 | |
1195 /* | |
1196 * non-clipped blitter. Ptype is the destination pixel type, | |
1197 * Ctype the translucent count type, and do_blend the | |
1198 * macro to blend one pixel. | |
1199 */ | |
1200 #define RLEALPHABLIT(Ptype, Ctype, do_blend) \ | |
1201 do { \ | |
1202 int linecount = srcrect->h; \ | |
1203 do { \ | |
1204 int ofs = 0; \ | |
1205 /* blit opaque pixels on one line */ \ | |
1206 do { \ | |
1207 unsigned run; \ | |
1208 ofs += ((Ctype *)srcbuf)[0]; \ | |
1209 run = ((Ctype *)srcbuf)[1]; \ | |
1210 srcbuf += 2 * sizeof(Ctype); \ | |
1211 if(run) { \ | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
1212 PIXEL_COPY(dstbuf + ofs * sizeof(Ptype), srcbuf, \ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
1213 run, sizeof(Ptype)); \ |
0 | 1214 srcbuf += run * sizeof(Ptype); \ |
1215 ofs += run; \ | |
1216 } else if(!ofs) \ | |
1217 goto done; \ | |
1218 } while(ofs < w); \ | |
1219 /* skip padding if necessary */ \ | |
1220 if(sizeof(Ptype) == 2) \ | |
1221 srcbuf += (unsigned long)srcbuf & 2; \ | |
1222 /* blit translucent pixels on the same line */ \ | |
1223 ofs = 0; \ | |
1224 do { \ | |
1225 unsigned run; \ | |
1226 ofs += ((Uint16 *)srcbuf)[0]; \ | |
1227 run = ((Uint16 *)srcbuf)[1]; \ | |
1228 srcbuf += 4; \ | |
1229 if(run) { \ | |
1230 Ptype *dst = (Ptype *)dstbuf + ofs; \ | |
1231 unsigned i; \ | |
1232 for(i = 0; i < run; i++) { \ | |
1233 Uint32 src = *(Uint32 *)srcbuf; \ | |
1234 do_blend(src, *dst); \ | |
1235 srcbuf += 4; \ | |
1236 dst++; \ | |
1237 } \ | |
1238 ofs += run; \ | |
1239 } \ | |
1240 } while(ofs < w); \ | |
1241 dstbuf += dst->pitch; \ | |
1242 } while(--linecount); \ | |
1243 } while(0) | |
1244 | |
1245 switch(df->BytesPerPixel) { | |
1246 case 2: | |
1247 if(df->Gmask == 0x07e0 || df->Rmask == 0x07e0 | |
1248 || df->Bmask == 0x07e0) | |
1249 RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_565); | |
1250 else | |
1251 RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_555); | |
1252 break; | |
1253 case 4: | |
1254 RLEALPHABLIT(Uint32, Uint16, BLIT_TRANSL_888); | |
1255 break; | |
1256 } | |
1257 } | |
1258 | |
1259 done: | |
1260 /* Unlock the destination if necessary */ | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
1261 if ( SDL_MUSTLOCK(dst) ) { |
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
1262 SDL_UnlockSurface(dst); |
0 | 1263 } |
1264 return 0; | |
1265 } | |
1266 | |
1267 /* | |
1268 * Auxiliary functions: | |
1269 * The encoding functions take 32bpp rgb + a, and | |
1270 * return the number of bytes copied to the destination. | |
1271 * The decoding functions copy to 32bpp rgb + a, and | |
1272 * return the number of bytes copied from the source. | |
1273 * These are only used in the encoder and un-RLE code and are therefore not | |
1274 * highly optimised. | |
1275 */ | |
1276 | |
1277 /* encode 32bpp rgb + a into 16bpp rgb, losing alpha */ | |
1278 static int copy_opaque_16(void *dst, Uint32 *src, int n, | |
1279 SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) | |
1280 { | |
1281 int i; | |
1282 Uint16 *d = dst; | |
1283 for(i = 0; i < n; i++) { | |
1284 unsigned r, g, b; | |
1285 RGB_FROM_PIXEL(*src, sfmt, r, g, b); | |
1286 PIXEL_FROM_RGB(*d, dfmt, r, g, b); | |
1287 src++; | |
1288 d++; | |
1289 } | |
1290 return n * 2; | |
1291 } | |
1292 | |
1293 /* decode opaque pixels from 16bpp to 32bpp rgb + a */ | |
1294 static int uncopy_opaque_16(Uint32 *dst, void *src, int n, | |
1295 RLEDestFormat *sfmt, SDL_PixelFormat *dfmt) | |
1296 { | |
1297 int i; | |
1298 Uint16 *s = src; | |
1299 unsigned alpha = dfmt->Amask ? 255 : 0; | |
1300 for(i = 0; i < n; i++) { | |
1301 unsigned r, g, b; | |
1302 RGB_FROM_PIXEL(*s, sfmt, r, g, b); | |
1303 PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, alpha); | |
1304 s++; | |
1305 dst++; | |
1306 } | |
1307 return n * 2; | |
1308 } | |
1309 | |
1310 | |
1311 | |
1312 /* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 565 */ | |
1313 static int copy_transl_565(void *dst, Uint32 *src, int n, | |
1314 SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) | |
1315 { | |
1316 int i; | |
1317 Uint32 *d = dst; | |
1318 for(i = 0; i < n; i++) { | |
1319 unsigned r, g, b, a; | |
1320 Uint16 pix; | |
1321 RGBA_FROM_8888(*src, sfmt, r, g, b, a); | |
1322 PIXEL_FROM_RGB(pix, dfmt, r, g, b); | |
1323 *d = ((pix & 0x7e0) << 16) | (pix & 0xf81f) | ((a << 2) & 0x7e0); | |
1324 src++; | |
1325 d++; | |
1326 } | |
1327 return n * 4; | |
1328 } | |
1329 | |
1330 /* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 555 */ | |
1331 static int copy_transl_555(void *dst, Uint32 *src, int n, | |
1332 SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) | |
1333 { | |
1334 int i; | |
1335 Uint32 *d = dst; | |
1336 for(i = 0; i < n; i++) { | |
1337 unsigned r, g, b, a; | |
1338 Uint16 pix; | |
1339 RGBA_FROM_8888(*src, sfmt, r, g, b, a); | |
1340 PIXEL_FROM_RGB(pix, dfmt, r, g, b); | |
1341 *d = ((pix & 0x3e0) << 16) | (pix & 0xfc1f) | ((a << 2) & 0x3e0); | |
1342 src++; | |
1343 d++; | |
1344 } | |
1345 return n * 4; | |
1346 } | |
1347 | |
1348 /* decode translucent pixels from 32bpp GORAB to 32bpp rgb + a */ | |
1349 static int uncopy_transl_16(Uint32 *dst, void *src, int n, | |
1350 RLEDestFormat *sfmt, SDL_PixelFormat *dfmt) | |
1351 { | |
1352 int i; | |
1353 Uint32 *s = src; | |
1354 for(i = 0; i < n; i++) { | |
1355 unsigned r, g, b, a; | |
1356 Uint32 pix = *s++; | |
1357 a = (pix & 0x3e0) >> 2; | |
1358 pix = (pix & ~0x3e0) | pix >> 16; | |
1359 RGB_FROM_PIXEL(pix, sfmt, r, g, b); | |
1360 PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a); | |
1361 dst++; | |
1362 } | |
1363 return n * 4; | |
1364 } | |
1365 | |
1366 /* encode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */ | |
1367 static int copy_32(void *dst, Uint32 *src, int n, | |
1368 SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) | |
1369 { | |
1370 int i; | |
1371 Uint32 *d = dst; | |
1372 for(i = 0; i < n; i++) { | |
1373 unsigned r, g, b, a; | |
1374 Uint32 pixel; | |
1375 RGBA_FROM_8888(*src, sfmt, r, g, b, a); | |
1376 PIXEL_FROM_RGB(pixel, dfmt, r, g, b); | |
1377 *d++ = pixel | a << 24; | |
1378 src++; | |
1379 } | |
1380 return n * 4; | |
1381 } | |
1382 | |
1383 /* decode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */ | |
1384 static int uncopy_32(Uint32 *dst, void *src, int n, | |
1385 RLEDestFormat *sfmt, SDL_PixelFormat *dfmt) | |
1386 { | |
1387 int i; | |
1388 Uint32 *s = src; | |
1389 for(i = 0; i < n; i++) { | |
1390 unsigned r, g, b, a; | |
1391 Uint32 pixel = *s++; | |
1392 RGB_FROM_PIXEL(pixel, sfmt, r, g, b); | |
1393 a = pixel >> 24; | |
1394 PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a); | |
1395 dst++; | |
1396 } | |
1397 return n * 4; | |
1398 } | |
1399 | |
1400 #define ISOPAQUE(pixel, fmt) ((((pixel) & fmt->Amask) >> fmt->Ashift) == 255) | |
1401 | |
1402 #define ISTRANSL(pixel, fmt) \ | |
1403 ((unsigned)((((pixel) & fmt->Amask) >> fmt->Ashift) - 1U) < 254U) | |
1404 | |
1405 /* convert surface to be quickly alpha-blittable onto dest, if possible */ | |
1406 static int RLEAlphaSurface(SDL_Surface *surface) | |
1407 { | |
1408 SDL_Surface *dest; | |
1409 SDL_PixelFormat *df; | |
1410 int maxsize = 0; | |
1411 int max_opaque_run; | |
1412 int max_transl_run = 65535; | |
1413 unsigned masksum; | |
1414 Uint8 *rlebuf, *dst; | |
1415 int (*copy_opaque)(void *, Uint32 *, int, | |
1416 SDL_PixelFormat *, SDL_PixelFormat *); | |
1417 int (*copy_transl)(void *, Uint32 *, int, | |
1418 SDL_PixelFormat *, SDL_PixelFormat *); | |
1419 | |
1420 dest = surface->map->dst; | |
1421 if(!dest) | |
1422 return -1; | |
1423 df = dest->format; | |
1424 if(surface->format->BitsPerPixel != 32) | |
1425 return -1; /* only 32bpp source supported */ | |
1426 | |
1427 /* find out whether the destination is one we support, | |
1428 and determine the max size of the encoded result */ | |
1429 masksum = df->Rmask | df->Gmask | df->Bmask; | |
1430 switch(df->BytesPerPixel) { | |
1431 case 2: | |
1432 /* 16bpp: only support 565 and 555 formats */ | |
1433 switch(masksum) { | |
1434 case 0xffff: | |
1435 if(df->Gmask == 0x07e0 | |
1436 || df->Rmask == 0x07e0 || df->Bmask == 0x07e0) { | |
1437 copy_opaque = copy_opaque_16; | |
1438 copy_transl = copy_transl_565; | |
1439 } else | |
1440 return -1; | |
1441 break; | |
1442 case 0x7fff: | |
1443 if(df->Gmask == 0x03e0 | |
1444 || df->Rmask == 0x03e0 || df->Bmask == 0x03e0) { | |
1445 copy_opaque = copy_opaque_16; | |
1446 copy_transl = copy_transl_555; | |
1447 } else | |
1448 return -1; | |
1449 break; | |
1450 default: | |
1451 return -1; | |
1452 } | |
1453 max_opaque_run = 255; /* runs stored as bytes */ | |
1454 | |
1455 /* worst case is alternating opaque and translucent pixels, | |
1456 with room for alignment padding between lines */ | |
1457 maxsize = surface->h * (2 + (4 + 2) * (surface->w + 1)) + 2; | |
1458 break; | |
1459 case 4: | |
1460 if(masksum != 0x00ffffff) | |
1461 return -1; /* requires unused high byte */ | |
1462 copy_opaque = copy_32; | |
1463 copy_transl = copy_32; | |
1464 max_opaque_run = 255; /* runs stored as short ints */ | |
1465 | |
1466 /* worst case is alternating opaque and translucent pixels */ | |
1467 maxsize = surface->h * 2 * 4 * (surface->w + 1) + 4; | |
1468 break; | |
1469 default: | |
1470 return -1; /* anything else unsupported right now */ | |
1471 } | |
1472 | |
1473 maxsize += sizeof(RLEDestFormat); | |
1474 rlebuf = (Uint8 *)malloc(maxsize); | |
1475 if(!rlebuf) { | |
1476 SDL_OutOfMemory(); | |
1477 return -1; | |
1478 } | |
1479 { | |
1480 /* save the destination format so we can undo the encoding later */ | |
1481 RLEDestFormat *r = (RLEDestFormat *)rlebuf; | |
1482 r->BytesPerPixel = df->BytesPerPixel; | |
1483 r->Rloss = df->Rloss; | |
1484 r->Gloss = df->Gloss; | |
1485 r->Bloss = df->Bloss; | |
1486 r->Rshift = df->Rshift; | |
1487 r->Gshift = df->Gshift; | |
1488 r->Bshift = df->Bshift; | |
1489 r->Ashift = df->Ashift; | |
1490 r->Rmask = df->Rmask; | |
1491 r->Gmask = df->Gmask; | |
1492 r->Bmask = df->Bmask; | |
1493 r->Amask = df->Amask; | |
1494 } | |
1495 dst = rlebuf + sizeof(RLEDestFormat); | |
1496 | |
1497 /* Do the actual encoding */ | |
1498 { | |
1499 int x, y; | |
1500 int h = surface->h, w = surface->w; | |
1501 SDL_PixelFormat *sf = surface->format; | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
1502 Uint32 *src = (Uint32 *)surface->pixels; |
0 | 1503 Uint8 *lastline = dst; /* end of last non-blank line */ |
1504 | |
1505 /* opaque counts are 8 or 16 bits, depending on target depth */ | |
1506 #define ADD_OPAQUE_COUNTS(n, m) \ | |
1507 if(df->BytesPerPixel == 4) { \ | |
1508 ((Uint16 *)dst)[0] = n; \ | |
1509 ((Uint16 *)dst)[1] = m; \ | |
1510 dst += 4; \ | |
1511 } else { \ | |
1512 dst[0] = n; \ | |
1513 dst[1] = m; \ | |
1514 dst += 2; \ | |
1515 } | |
1516 | |
1517 /* translucent counts are always 16 bit */ | |
1518 #define ADD_TRANSL_COUNTS(n, m) \ | |
1519 (((Uint16 *)dst)[0] = n, ((Uint16 *)dst)[1] = m, dst += 4) | |
1520 | |
1521 for(y = 0; y < h; y++) { | |
1522 int runstart, skipstart; | |
1523 int blankline = 0; | |
1524 /* First encode all opaque pixels of a scan line */ | |
1525 x = 0; | |
1526 do { | |
1527 int run, skip, len; | |
1528 skipstart = x; | |
1529 while(x < w && !ISOPAQUE(src[x], sf)) | |
1530 x++; | |
1531 runstart = x; | |
1532 while(x < w && ISOPAQUE(src[x], sf)) | |
1533 x++; | |
1534 skip = runstart - skipstart; | |
1535 if(skip == w) | |
1536 blankline = 1; | |
1537 run = x - runstart; | |
1538 while(skip > max_opaque_run) { | |
1539 ADD_OPAQUE_COUNTS(max_opaque_run, 0); | |
1540 skip -= max_opaque_run; | |
1541 } | |
1542 len = MIN(run, max_opaque_run); | |
1543 ADD_OPAQUE_COUNTS(skip, len); | |
1544 dst += copy_opaque(dst, src + runstart, len, sf, df); | |
1545 runstart += len; | |
1546 run -= len; | |
1547 while(run) { | |
1548 len = MIN(run, max_opaque_run); | |
1549 ADD_OPAQUE_COUNTS(0, len); | |
1550 dst += copy_opaque(dst, src + runstart, len, sf, df); | |
1551 runstart += len; | |
1552 run -= len; | |
1553 } | |
1554 } while(x < w); | |
1555 | |
1556 /* Make sure the next output address is 32-bit aligned */ | |
1557 dst += (unsigned long)dst & 2; | |
1558 | |
1559 /* Next, encode all translucent pixels of the same scan line */ | |
1560 x = 0; | |
1561 do { | |
1562 int run, skip, len; | |
1563 skipstart = x; | |
1564 while(x < w && !ISTRANSL(src[x], sf)) | |
1565 x++; | |
1566 runstart = x; | |
1567 while(x < w && ISTRANSL(src[x], sf)) | |
1568 x++; | |
1569 skip = runstart - skipstart; | |
1570 blankline &= (skip == w); | |
1571 run = x - runstart; | |
1572 while(skip > max_transl_run) { | |
1573 ADD_TRANSL_COUNTS(max_transl_run, 0); | |
1574 skip -= max_transl_run; | |
1575 } | |
1576 len = MIN(run, max_transl_run); | |
1577 ADD_TRANSL_COUNTS(skip, len); | |
1578 dst += copy_transl(dst, src + runstart, len, sf, df); | |
1579 runstart += len; | |
1580 run -= len; | |
1581 while(run) { | |
1582 len = MIN(run, max_transl_run); | |
1583 ADD_TRANSL_COUNTS(0, len); | |
1584 dst += copy_transl(dst, src + runstart, len, sf, df); | |
1585 runstart += len; | |
1586 run -= len; | |
1587 } | |
1588 if(!blankline) | |
1589 lastline = dst; | |
1590 } while(x < w); | |
1591 | |
1592 src += surface->pitch >> 2; | |
1593 } | |
1594 dst = lastline; /* back up past trailing blank lines */ | |
1595 ADD_OPAQUE_COUNTS(0, 0); | |
1596 } | |
1597 | |
1598 #undef ADD_OPAQUE_COUNTS | |
1599 #undef ADD_TRANSL_COUNTS | |
1600 | |
1601 /* Now that we have it encoded, release the original pixels */ | |
1602 if((surface->flags & SDL_PREALLOC) != SDL_PREALLOC | |
1603 && (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) { | |
1604 free( surface->pixels ); | |
1605 surface->pixels = NULL; | |
1606 } | |
1607 | |
1608 /* realloc the buffer to release unused memory */ | |
1609 { | |
1610 Uint8 *p = realloc(rlebuf, dst - rlebuf); | |
1611 if(!p) | |
1612 p = rlebuf; | |
1613 surface->map->sw_data->aux_data = p; | |
1614 } | |
1615 | |
1616 return 0; | |
1617 } | |
1618 | |
1619 static Uint32 getpix_8(Uint8 *srcbuf) | |
1620 { | |
1621 return *srcbuf; | |
1622 } | |
1623 | |
1624 static Uint32 getpix_16(Uint8 *srcbuf) | |
1625 { | |
1626 return *(Uint16 *)srcbuf; | |
1627 } | |
1628 | |
1629 static Uint32 getpix_24(Uint8 *srcbuf) | |
1630 { | |
1631 if(SDL_BYTEORDER == SDL_LIL_ENDIAN) | |
1632 return srcbuf[0] + (srcbuf[1] << 8) + (srcbuf[2] << 16); | |
1633 else | |
1634 return (srcbuf[0] << 16) + (srcbuf[1] << 8) + srcbuf[2]; | |
1635 } | |
1636 | |
1637 static Uint32 getpix_32(Uint8 *srcbuf) | |
1638 { | |
1639 return *(Uint32 *)srcbuf; | |
1640 } | |
1641 | |
1642 typedef Uint32 (*getpix_func)(Uint8 *); | |
1643 | |
1644 static getpix_func getpixes[4] = { | |
1645 getpix_8, getpix_16, getpix_24, getpix_32 | |
1646 }; | |
1647 | |
1648 static int RLEColorkeySurface(SDL_Surface *surface) | |
1649 { | |
1650 Uint8 *rlebuf, *dst; | |
1651 int maxn; | |
1652 int y; | |
1653 Uint8 *srcbuf, *curbuf, *lastline; | |
1654 int maxsize = 0; | |
1655 int skip, run; | |
1656 int bpp = surface->format->BytesPerPixel; | |
1657 getpix_func getpix; | |
1658 Uint32 ckey, rgbmask; | |
1659 int w, h; | |
1660 | |
1661 /* calculate the worst case size for the compressed surface */ | |
1662 switch(bpp) { | |
1663 case 1: | |
1664 /* worst case is alternating opaque and transparent pixels, | |
1665 starting with an opaque pixel */ | |
1666 maxsize = surface->h * 3 * (surface->w / 2 + 1) + 2; | |
1667 break; | |
1668 case 2: | |
1669 case 3: | |
1670 /* worst case is solid runs, at most 255 pixels wide */ | |
1671 maxsize = surface->h * (2 * (surface->w / 255 + 1) | |
1672 + surface->w * bpp) + 2; | |
1673 break; | |
1674 case 4: | |
1675 /* worst case is solid runs, at most 65535 pixels wide */ | |
1676 maxsize = surface->h * (4 * (surface->w / 65535 + 1) | |
1677 + surface->w * 4) + 4; | |
1678 break; | |
1679 } | |
1680 | |
1681 rlebuf = (Uint8 *)malloc(maxsize); | |
1682 if ( rlebuf == NULL ) { | |
1683 SDL_OutOfMemory(); | |
1684 return(-1); | |
1685 } | |
1686 | |
1687 /* Set up the conversion */ | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
1688 srcbuf = (Uint8 *)surface->pixels; |
0 | 1689 curbuf = srcbuf; |
1690 maxn = bpp == 4 ? 65535 : 255; | |
1691 skip = run = 0; | |
1692 dst = rlebuf; | |
1693 rgbmask = ~surface->format->Amask; | |
1694 ckey = surface->format->colorkey & rgbmask; | |
1695 lastline = dst; | |
1696 getpix = getpixes[bpp - 1]; | |
1697 w = surface->w; | |
1698 h = surface->h; | |
1699 | |
1700 #define ADD_COUNTS(n, m) \ | |
1701 if(bpp == 4) { \ | |
1702 ((Uint16 *)dst)[0] = n; \ | |
1703 ((Uint16 *)dst)[1] = m; \ | |
1704 dst += 4; \ | |
1705 } else { \ | |
1706 dst[0] = n; \ | |
1707 dst[1] = m; \ | |
1708 dst += 2; \ | |
1709 } | |
1710 | |
1711 for(y = 0; y < h; y++) { | |
1712 int x = 0; | |
1713 int blankline = 0; | |
1714 do { | |
1715 int run, skip, len; | |
1716 int runstart; | |
1717 int skipstart = x; | |
1718 | |
1719 /* find run of transparent, then opaque pixels */ | |
1720 while(x < w && (getpix(srcbuf + x * bpp) & rgbmask) == ckey) | |
1721 x++; | |
1722 runstart = x; | |
1723 while(x < w && (getpix(srcbuf + x * bpp) & rgbmask) != ckey) | |
1724 x++; | |
1725 skip = runstart - skipstart; | |
1726 if(skip == w) | |
1727 blankline = 1; | |
1728 run = x - runstart; | |
1729 | |
1730 /* encode segment */ | |
1731 while(skip > maxn) { | |
1732 ADD_COUNTS(maxn, 0); | |
1733 skip -= maxn; | |
1734 } | |
1735 len = MIN(run, maxn); | |
1736 ADD_COUNTS(skip, len); | |
1737 memcpy(dst, srcbuf + runstart * bpp, len * bpp); | |
1738 dst += len * bpp; | |
1739 run -= len; | |
1740 runstart += len; | |
1741 while(run) { | |
1742 len = MIN(run, maxn); | |
1743 ADD_COUNTS(0, len); | |
1744 memcpy(dst, srcbuf + runstart * bpp, len * bpp); | |
1745 dst += len * bpp; | |
1746 runstart += len; | |
1747 run -= len; | |
1748 } | |
1749 if(!blankline) | |
1750 lastline = dst; | |
1751 } while(x < w); | |
1752 | |
1753 srcbuf += surface->pitch; | |
1754 } | |
1755 dst = lastline; /* back up bast trailing blank lines */ | |
1756 ADD_COUNTS(0, 0); | |
1757 | |
1758 #undef ADD_COUNTS | |
1759 | |
1760 /* Now that we have it encoded, release the original pixels */ | |
1761 if((surface->flags & SDL_PREALLOC) != SDL_PREALLOC | |
1762 && (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) { | |
1763 free( surface->pixels ); | |
1764 surface->pixels = NULL; | |
1765 } | |
1766 | |
1767 /* realloc the buffer to release unused memory */ | |
1768 { | |
1769 /* If realloc returns NULL, the original block is left intact */ | |
1770 Uint8 *p = realloc(rlebuf, dst - rlebuf); | |
1771 if(!p) | |
1772 p = rlebuf; | |
1773 surface->map->sw_data->aux_data = p; | |
1774 } | |
1775 | |
1776 return(0); | |
1777 } | |
1778 | |
1779 int SDL_RLESurface(SDL_Surface *surface) | |
1780 { | |
1781 int retcode; | |
1782 | |
1783 /* Clear any previous RLE conversion */ | |
1784 if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { | |
1785 SDL_UnRLESurface(surface, 1); | |
1786 } | |
1787 | |
1788 /* We don't support RLE encoding of bitmaps */ | |
1789 if ( surface->format->BitsPerPixel < 8 ) { | |
1790 return(-1); | |
1791 } | |
1792 | |
1793 /* Lock the surface if it's in hardware */ | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
1794 if ( SDL_MUSTLOCK(surface) ) { |
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
1795 if ( SDL_LockSurface(surface) < 0 ) { |
0 | 1796 return(-1); |
1797 } | |
1798 } | |
1799 | |
1800 /* Encode */ | |
1801 if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { | |
1802 retcode = RLEColorkeySurface(surface); | |
1803 } else { | |
1804 if((surface->flags & SDL_SRCALPHA) == SDL_SRCALPHA | |
1805 && surface->format->Amask != 0) | |
1806 retcode = RLEAlphaSurface(surface); | |
1807 else | |
1808 retcode = -1; /* no RLE for per-surface alpha sans ckey */ | |
1809 } | |
1810 | |
1811 /* Unlock the surface if it's in hardware */ | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
1812 if ( SDL_MUSTLOCK(surface) ) { |
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
1813 SDL_UnlockSurface(surface); |
0 | 1814 } |
1815 | |
1816 if(retcode < 0) | |
1817 return -1; | |
1818 | |
1819 /* The surface is now accelerated */ | |
1820 surface->flags |= SDL_RLEACCEL; | |
1821 | |
1822 return(0); | |
1823 } | |
1824 | |
1825 /* | |
1826 * Un-RLE a surface with pixel alpha | |
1827 * This may not give back exactly the image before RLE-encoding; all | |
1828 * completely transparent pixels will be lost, and colour and alpha depth | |
1829 * may have been reduced (when encoding for 16bpp targets). | |
1830 */ | |
1831 static void UnRLEAlpha(SDL_Surface *surface) | |
1832 { | |
1833 Uint8 *srcbuf; | |
1834 Uint32 *dst; | |
1835 SDL_PixelFormat *sf = surface->format; | |
1836 RLEDestFormat *df = surface->map->sw_data->aux_data; | |
1837 int (*uncopy_opaque)(Uint32 *, void *, int, | |
1838 RLEDestFormat *, SDL_PixelFormat *); | |
1839 int (*uncopy_transl)(Uint32 *, void *, int, | |
1840 RLEDestFormat *, SDL_PixelFormat *); | |
1841 int w = surface->w; | |
1842 int bpp = df->BytesPerPixel; | |
1843 | |
1844 if(bpp == 2) { | |
1845 uncopy_opaque = uncopy_opaque_16; | |
1846 uncopy_transl = uncopy_transl_16; | |
1847 } else { | |
1848 uncopy_opaque = uncopy_transl = uncopy_32; | |
1849 } | |
1850 | |
1851 surface->pixels = malloc(surface->h * surface->pitch); | |
1852 /* fill background with transparent pixels */ | |
1853 memset(surface->pixels, 0, surface->h * surface->pitch); | |
1854 | |
1855 dst = surface->pixels; | |
1856 srcbuf = (Uint8 *)(df + 1); | |
1857 for(;;) { | |
1858 /* copy opaque pixels */ | |
1859 int ofs = 0; | |
1860 do { | |
1861 unsigned run; | |
1862 if(bpp == 2) { | |
1863 ofs += srcbuf[0]; | |
1864 run = srcbuf[1]; | |
1865 srcbuf += 2; | |
1866 } else { | |
1867 ofs += ((Uint16 *)srcbuf)[0]; | |
1868 run = ((Uint16 *)srcbuf)[1]; | |
1869 srcbuf += 4; | |
1870 } | |
1871 if(run) { | |
1872 srcbuf += uncopy_opaque(dst + ofs, srcbuf, run, df, sf); | |
1873 ofs += run; | |
1874 } else if(!ofs) | |
1875 return; | |
1876 } while(ofs < w); | |
1877 | |
1878 /* skip padding if needed */ | |
1879 if(bpp == 2) | |
1880 srcbuf += (unsigned long)srcbuf & 2; | |
1881 | |
1882 /* copy translucent pixels */ | |
1883 ofs = 0; | |
1884 do { | |
1885 unsigned run; | |
1886 ofs += ((Uint16 *)srcbuf)[0]; | |
1887 run = ((Uint16 *)srcbuf)[1]; | |
1888 srcbuf += 4; | |
1889 if(run) { | |
1890 srcbuf += uncopy_transl(dst + ofs, srcbuf, run, df, sf); | |
1891 ofs += run; | |
1892 } | |
1893 } while(ofs < w); | |
1894 dst += surface->pitch >> 2; | |
1895 } | |
1896 } | |
1897 | |
1898 void SDL_UnRLESurface(SDL_Surface *surface, int recode) | |
1899 { | |
1900 if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { | |
1901 surface->flags &= ~SDL_RLEACCEL; | |
1902 | |
1903 if(recode && (surface->flags & SDL_PREALLOC) != SDL_PREALLOC | |
1904 && (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) { | |
1905 if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { | |
1906 SDL_Rect full; | |
1907 unsigned alpha_flag; | |
1908 | |
1909 /* re-create the original surface */ | |
1910 surface->pixels = malloc(surface->h * surface->pitch); | |
1911 | |
1912 /* fill it with the background colour */ | |
1913 SDL_FillRect(surface, NULL, surface->format->colorkey); | |
1914 | |
1915 /* now render the encoded surface */ | |
1916 full.x = full.y = 0; | |
1917 full.w = surface->w; | |
1918 full.h = surface->h; | |
1919 alpha_flag = surface->flags & SDL_SRCALPHA; | |
1920 surface->flags &= ~SDL_SRCALPHA; /* opaque blit */ | |
1921 SDL_RLEBlit(surface, &full, surface, &full); | |
1922 surface->flags |= alpha_flag; | |
1923 } else | |
1924 UnRLEAlpha(surface); | |
1925 } | |
1926 | |
1927 if ( surface->map && surface->map->sw_data->aux_data ) { | |
1928 free(surface->map->sw_data->aux_data); | |
1929 surface->map->sw_data->aux_data = NULL; | |
1930 } | |
1931 } | |
1932 } | |
1933 | |
1934 |