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