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