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