1 /*
2 (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
3 (c) Copyright 2000-2004 Convergence (integrated media) GmbH
4
5 All rights reserved.
6
7 Written by Denis Oliver Kropp <dok@directfb.org>,
8 Andreas Hundt <andi@fischlustig.de>,
9 Sven Neumann <neo@directfb.org>,
10 Ville Syrjälä <syrjala@sci.fi> and
11 Claudio Ciccani <klan@users.sf.net>.
12
13 This library is free software; you can redistribute it and/or
14 modify it under the terms of the GNU Lesser General Public
15 License as published by the Free Software Foundation; either
16 version 2 of the License, or (at your option) any later version.
17
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Lesser General Public License for more details.
22
23 You should have received a copy of the GNU Lesser General Public
24 License along with this library; if not, write to the
25 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 Boston, MA 02111-1307, USA.
27 */
28
29 /*
30 * Example:
31 * #define A_SHIFT 15
32 * #define R_SHIFT 10
33 * #define G_SHIFT 5
34 * #define B_SHIFT 0
35 * #define A_MASK 0x8000
36 * #define R_MASK 0x7c00
37 * #define G_MASK 0x03e0
38 * #define B_MASK 0x001f
39 * #define PIXEL_OUT( a, r, g, b ) PIXEL_ARGB1555( a, r, g, b )
40 * #define EXPAND_Ato8( a ) EXPAND_1to8( a )
41 * #define EXPAND_Rto8( r ) EXPAND_5to8( r )
42 * #define EXPAND_Gto8( g ) EXPAND_5to8( g )
43 * #define EXPAND_Bto8( b ) EXPAND_5to8( b )
44 * #define Sop_PFI_OP_Dacc( op ) Sop_argb1555_##op##_Dacc
45 * #define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_argb1555
46 * #include "template_acc_16.h"
47 */
48
49 #define RGB_MASK (R_MASK | G_MASK | B_MASK)
50
51 #if RGB_MASK == 0xffff
52 #define MASK_RGB( p ) (p)
53 #else
54 #define MASK_RGB( p ) ((p) & RGB_MASK)
55 #endif
56
57 #define PIXEL( x ) PIXEL_OUT( ((x).RGB.a & 0xFF00) ? 0xFF : (x).RGB.a, \
58 ((x).RGB.r & 0xFF00) ? 0xFF : (x).RGB.r, \
59 ((x).RGB.g & 0xFF00) ? 0xFF : (x).RGB.g, \
60 ((x).RGB.b & 0xFF00) ? 0xFF : (x).RGB.b )
61
62 #define EXPAND( d, s ) do { \
63 (d).RGB.a = EXPAND_Ato8( (s & A_MASK) >> A_SHIFT ); \
64 (d).RGB.r = EXPAND_Rto8( (s & R_MASK) >> R_SHIFT ); \
65 (d).RGB.g = EXPAND_Gto8( (s & G_MASK) >> G_SHIFT ); \
66 (d).RGB.b = EXPAND_Bto8( (s & B_MASK) >> B_SHIFT ); \
67 } while (0)
68
69 /********************************* Sop_PFI_Sto_Dacc ***************************/
70
Sop_PFI_OP_Dacc(Sto)71 static void Sop_PFI_OP_Dacc(Sto)( GenefxState *gfxs )
72 {
73 int l = gfxs->length+1;
74 int i = gfxs->Xphase;
75 int SperD = gfxs->SperD;
76 u16 *S = gfxs->Sop[0];
77 int Ostep = gfxs->Ostep;
78 GenefxAccumulator *D = gfxs->Dacc;
79
80 if (Ostep != 1)
81 D_UNIMPLEMENTED();
82
83 while (--l) {
84 u16 s = S[i>>16];
85
86 EXPAND( *D, s );
87
88 ++D;
89 i += SperD;
90 }
91 }
92
93 /********************************* Sop_PFI_SKto_Dacc **************************/
94
Sop_PFI_OP_Dacc(SKto)95 static void Sop_PFI_OP_Dacc(SKto)( GenefxState *gfxs )
96 {
97 int l = gfxs->length+1;
98 int i = gfxs->Xphase;
99 int SperD = gfxs->SperD;
100 u16 *S = gfxs->Sop[0];
101 int Ostep = gfxs->Ostep;
102 GenefxAccumulator *D = gfxs->Dacc;
103 u16 Skey = gfxs->Skey;
104
105 if (Ostep != 1)
106 D_UNIMPLEMENTED();
107
108 while (--l) {
109 u16 s = S[i>>16];
110
111 if (MASK_RGB( s ) != Skey)
112 EXPAND( *D, s );
113 else
114 D->RGB.a = 0xF000;
115
116 ++D;
117 i += SperD;
118 }
119 }
120
121 /********************************* Sop_PFI_to_Dacc ****************************/
122
Sop_PFI_OP_Dacc(to)123 static void Sop_PFI_OP_Dacc(to)( GenefxState *gfxs )
124 {
125 int w, l = gfxs->length;
126 u16 *S = gfxs->Sop[0];
127 GenefxAccumulator *D = gfxs->Dacc;
128 int Ostep = gfxs->Ostep;
129
130 if (Ostep != 1) {
131 l++;
132 while (--l) {
133 u16 s = *S;
134
135 EXPAND( *D, s );
136
137 S += Ostep;
138
139 ++D;
140 }
141 return;
142 }
143
144 if ((long)S & 2) {
145 u16 s = *S++;
146
147 EXPAND( *D, s );
148
149 ++D;
150 --l;
151 }
152
153 w = (l >> 1) +1;
154 while (--w) {
155 u32 s = *(u32 *) S;
156
157 #ifdef WORDS_BIGENDIAN
158 EXPAND( D[0], s >> 16 );
159 EXPAND( D[1], s );
160 #else
161 EXPAND( D[0], s );
162 EXPAND( D[1], s >> 16);
163 #endif
164
165 S += 2;
166 D += 2;
167 }
168
169 if (l & 1) {
170 u16 s = *S;
171
172 EXPAND( *D, s );
173 }
174 }
175
176 /********************************* Sop_PFI_Kto_Dacc ***************************/
177
Sop_PFI_OP_Dacc(Kto)178 static void Sop_PFI_OP_Dacc(Kto)( GenefxState *gfxs )
179 {
180 int l = gfxs->length+1;
181 u16 *S = gfxs->Sop[0];
182 GenefxAccumulator *D = gfxs->Dacc;
183 u16 Skey = gfxs->Skey;
184 int Ostep = gfxs->Ostep;
185
186 while (--l) {
187 u16 s = *S;
188
189 if (MASK_RGB( s ) != Skey)
190 EXPAND( *D, s );
191 else
192 D->RGB.a = 0xF000;
193
194 S += Ostep;
195 ++D;
196 }
197 }
198
199 /********************************* Sacc_to_Aop_PFI ****************************/
200
Sacc_OP_Aop_PFI(to)201 static void Sacc_OP_Aop_PFI(to)( GenefxState *gfxs )
202 {
203 int w, l = gfxs->length;
204 GenefxAccumulator *S = gfxs->Sacc;
205 u16 *D = gfxs->Aop[0];
206 int Dstep = gfxs->Astep;
207
208 if (Dstep != 1) {
209 l++;
210 while (--l) {
211 if (!(S->RGB.a & 0xF000))
212 *D = PIXEL( *S );
213
214 ++S;
215 D += Dstep;
216 }
217 return;
218 }
219
220 if ((long)D & 2) {
221 if (!(S->RGB.a & 0xF000))
222 *D = PIXEL( *S );
223
224 ++S;
225 ++D;
226 --l;
227 }
228
229 w = (l >> 1) +1;
230 while (--w) {
231 u32 *D2 = (u32 *) D;
232
233 if (!(S[0].RGB.a & 0xF000) && !(S[1].RGB.a & 0xF000)) {
234 #ifdef WORDS_BIGENDIAN
235 *D2 = PIXEL( S[1] ) | PIXEL( S[0] ) << 16;
236 #else
237 *D2 = PIXEL( S[0] ) | PIXEL( S[1] ) << 16;
238 #endif
239 } else {
240 if (!(S[0].RGB.a & 0xF000))
241 D[0] = PIXEL( S[0] );
242 else if (!(S[1].RGB.a & 0xF000))
243 D[1] = PIXEL( S[1] );
244 }
245
246 S += 2;
247 D += 2;
248 }
249
250 if (l & 1) {
251 if (!(S->RGB.a & 0xF000))
252 *D = PIXEL( *S );
253 }
254 }
255
256 /********************************* Sacc_Sto_Aop_PFI ***************************/
257
Sacc_OP_Aop_PFI(Sto)258 static void Sacc_OP_Aop_PFI(Sto)( GenefxState *gfxs )
259 {
260 int w, l = gfxs->length;
261 int i = gfxs->Xphase;
262 int SperD = gfxs->SperD;
263 GenefxAccumulator *Sacc = gfxs->Sacc;
264 u16 *D = gfxs->Aop[0];
265 int Dstep = gfxs->Astep;
266
267 if (Dstep != 1) {
268 l++;
269 while (--l) {
270 GenefxAccumulator *S = &Sacc[i>>16];
271
272 if (!(S->RGB.a & 0xF000))
273 *D = PIXEL( *S );
274
275 D += Dstep;
276 i += SperD;
277 }
278 return;
279 }
280 if ((long)D & 2) {
281 GenefxAccumulator *S = Sacc;
282
283 if (!(S->RGB.a & 0xF000))
284 *D = PIXEL( *S );
285
286 ++D;
287 --l;
288 i += SperD;
289 }
290
291 w = (l >> 1) +1;
292 while (--w) {
293 GenefxAccumulator *S0 = &Sacc[i>>16];
294 GenefxAccumulator *S1 = &Sacc[(i+SperD)>>16];
295 u32 *D2 = (u32 *) D;
296
297 if (!(S0->RGB.a & 0xF000) && !(S1->RGB.a & 0xF000)) {
298 #ifdef WORDS_BIGENDIAN
299 *D2 = PIXEL( *S1 ) | PIXEL( *S0 ) << 16;
300 #else
301 *D2 = PIXEL( *S0 ) | PIXEL( *S1 ) << 16;
302 #endif
303 } else {
304 if (!(S0->RGB.a & 0xF000))
305 D[0] = PIXEL( *S0 );
306 else if (!(S1->RGB.a & 0xF000))
307 D[1] = PIXEL( *S1 );
308 }
309
310 D += 2;
311 i += SperD << 1;
312 }
313
314 if (l & 1) {
315 GenefxAccumulator *S = &Sacc[i>>16];
316
317 if (!(S->RGB.a & 0xF000))
318 *D = PIXEL( *S );
319 }
320 }
321
322 /********************************* Sacc_toK_Aop_PFI ***************************/
323
Sacc_OP_Aop_PFI(toK)324 static void Sacc_OP_Aop_PFI(toK)( GenefxState *gfxs )
325 {
326 int l = gfxs->length+1;
327 GenefxAccumulator *S = gfxs->Sacc;
328 u16 *D = gfxs->Aop[0];
329 u16 Dkey = gfxs->Dkey;
330 int Dstep = gfxs->Astep;
331
332 while (--l) {
333 if (!(S->RGB.a & 0xF000) && MASK_RGB( *D ) == Dkey)
334 *D = PIXEL( *S );
335
336 ++S;
337 D += Dstep;
338 }
339 }
340
341 /********************************* Sacc_StoK_Aop_PFI **************************/
342
Sacc_OP_Aop_PFI(StoK)343 static void Sacc_OP_Aop_PFI(StoK)( GenefxState *gfxs )
344 {
345 int l = gfxs->length+1;
346 int i = gfxs->Xphase;
347 int SperD = gfxs->SperD;
348 GenefxAccumulator *Sacc = gfxs->Sacc;
349 u16 *D = gfxs->Aop[0];
350 u16 Dkey = gfxs->Dkey;
351 int Dstep = gfxs->Astep;
352
353 while (--l) {
354 GenefxAccumulator *S = &Sacc[i>>16];
355
356 if (!(S->RGB.a & 0xF000) && MASK_RGB( *D ) == Dkey)
357 *D = PIXEL( *S );
358
359 D += Dstep;
360 i += SperD;
361 }
362 }
363
364 /********************************* Sop_PFI_TEX_to_Dacc ***************************/
365
Sop_PFI_OP_Dacc(TEX_to)366 static void Sop_PFI_OP_Dacc(TEX_to)( GenefxState *gfxs )
367 {
368 int l = gfxs->length+1;
369 int s = gfxs->s;
370 int t = gfxs->t;
371 int SperD = gfxs->SperD;
372 int TperD = gfxs->TperD;
373 u16 *S = gfxs->Sop[0];
374 int Ostep = gfxs->Ostep;
375 GenefxAccumulator *D = gfxs->Dacc;
376 int sp2 = gfxs->src_pitch / 2;
377
378 if (Ostep != 1)
379 D_UNIMPLEMENTED();
380
381 while (--l) {
382 u16 p = S[(s>>16) + (t>>16) * sp2];
383
384 EXPAND( *D, p );
385
386 ++D;
387 s += SperD;
388 t += TperD;
389 }
390 }
391
392 /********************************* Sop_PFI_TEX_Kto_Dacc ***************************/
393
Sop_PFI_OP_Dacc(TEX_Kto)394 static void Sop_PFI_OP_Dacc(TEX_Kto)( GenefxState *gfxs )
395 {
396 int l = gfxs->length+1;
397 int s = gfxs->s;
398 int t = gfxs->t;
399 int SperD = gfxs->SperD;
400 int TperD = gfxs->TperD;
401 u16 *S = gfxs->Sop[0];
402 u16 Skey = gfxs->Skey;
403 int Ostep = gfxs->Ostep;
404 GenefxAccumulator *D = gfxs->Dacc;
405 int sp2 = gfxs->src_pitch / 2;
406
407 if (Ostep != 1)
408 D_UNIMPLEMENTED();
409
410 while (--l) {
411 u16 p = S[(s>>16) + (t>>16) * sp2];
412
413 if ((p & RGB_MASK) != Skey)
414 EXPAND( *D, p );
415 else
416 D->RGB.a = 0xF000;
417
418 ++D;
419 s += SperD;
420 t += TperD;
421 }
422 }
423
424 /******************************************************************************/
425
426 #undef RGB_MASK
427 #undef MASK_RGB
428 #undef PIXEL
429 #undef EXPAND
430
431 #undef A_SHIFT
432 #undef R_SHIFT
433 #undef G_SHIFT
434 #undef B_SHIFT
435 #undef A_MASK
436 #undef R_MASK
437 #undef G_MASK
438 #undef B_MASK
439 #undef PIXEL_OUT
440 #undef EXPAND_Ato8
441 #undef EXPAND_Rto8
442 #undef EXPAND_Gto8
443 #undef EXPAND_Bto8
444 #undef Sop_PFI_OP_Dacc
445 #undef Sacc_OP_Aop_PFI
446