1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 *
11 * Interpolation routines for hicolor and truecolor pixels.
12 *
13 * By Cloud Wu and Burton Radons.
14 *
15 * Alpha blending optimised by Peter Cech.
16 *
17 * See readme.txt for copyright information.
18 */
19
20
21 #include "allegro.h"
22 #include "allegro/internal/aintern.h"
23
24
25
26 #define BLEND(bpp, r, g, b) _blender_trans##bpp(makecol##bpp(r, g, b), y, n)
27
28 #define T(x, y, n) (((y) - (x)) * (n) / 255 + (x))
29
30
31
32 /* _blender_black:
33 * Fallback routine for when we don't have anything better to do.
34 */
_blender_black(unsigned long x,unsigned long y,unsigned long n)35 unsigned long _blender_black(unsigned long x, unsigned long y, unsigned long n)
36 {
37 return 0;
38 }
39
40
41
42 #if (defined ALLEGRO_COLOR24) || (defined ALLEGRO_COLOR32)
43
44
45
46 #if (defined ALLEGRO_NO_ASM) || (!defined ALLEGRO_I386)
47 /* i386 asm version is in imisc.s */
48
49
50 /* _blender_trans24:
51 * 24 bit trans blender function.
52 */
_blender_trans24(unsigned long x,unsigned long y,unsigned long n)53 unsigned long _blender_trans24(unsigned long x, unsigned long y, unsigned long n)
54 {
55 unsigned long res, g;
56
57 if (n)
58 n++;
59
60 res = ((x & 0xFF00FF) - (y & 0xFF00FF)) * n / 256 + y;
61 y &= 0xFF00;
62 x &= 0xFF00;
63 g = (x - y) * n / 256 + y;
64
65 res &= 0xFF00FF;
66 g &= 0xFF00;
67
68 return res | g;
69 }
70
71
72 #endif /* C version */
73
74
75
76 /* _blender_alpha24:
77 * Combines a 32 bit RGBA sprite with a 24 bit RGB destination.
78 */
_blender_alpha24(unsigned long x,unsigned long y,unsigned long n)79 unsigned long _blender_alpha24(unsigned long x, unsigned long y, unsigned long n)
80 {
81 unsigned long xx = makecol24(getr32(x), getg32(x), getb32(x));
82 unsigned long res, g;
83
84 n = geta32(x);
85
86 if (n)
87 n++;
88
89 res = ((xx & 0xFF00FF) - (y & 0xFF00FF)) * n / 256 + y;
90 y &= 0xFF00;
91 xx &= 0xFF00;
92 g = (xx - y) * n / 256 + y;
93
94 res &= 0xFF00FF;
95 g &= 0xFF00;
96
97 return res | g;
98 }
99
100
101
102 /* _blender_alpha32:
103 * Combines a 32 bit RGBA sprite with a 32 bit RGB destination.
104 */
_blender_alpha32(unsigned long x,unsigned long y,unsigned long n)105 unsigned long _blender_alpha32(unsigned long x, unsigned long y, unsigned long n)
106 {
107 unsigned long res, g;
108
109 n = geta32(x);
110
111 if (n)
112 n++;
113
114 res = ((x & 0xFF00FF) - (y & 0xFF00FF)) * n / 256 + y;
115 y &= 0xFF00;
116 x &= 0xFF00;
117 g = (x - y) * n / 256 + y;
118
119 res &= 0xFF00FF;
120 g &= 0xFF00;
121
122 return res | g;
123 }
124
125
126
127 /* _blender_alpha24_bgr:
128 * Combines a 32 bit RGBA sprite with a 24 bit RGB destination, optimised
129 * for when one is in a BGR format and the other is RGB.
130 */
_blender_alpha24_bgr(unsigned long x,unsigned long y,unsigned long n)131 unsigned long _blender_alpha24_bgr(unsigned long x, unsigned long y, unsigned long n)
132 {
133 unsigned long res, g;
134
135 n = x >> 24;
136
137 if (n)
138 n++;
139
140 x = ((x>>16)&0xFF) | (x&0xFF00) | ((x<<16)&0xFF0000);
141
142 res = ((x & 0xFF00FF) - (y & 0xFF00FF)) * n / 256 + y;
143 y &= 0xFF00;
144 x &= 0xFF00;
145 g = (x - y) * n / 256 + y;
146
147 res &= 0xFF00FF;
148 g &= 0xFF00;
149
150 return res | g;
151 }
152
153
154
155 /* _blender_add24:
156 * 24 bit additive blender function.
157 */
_blender_add24(unsigned long x,unsigned long y,unsigned long n)158 unsigned long _blender_add24(unsigned long x, unsigned long y, unsigned long n)
159 {
160 int r = getr24(y) + getr24(x) * n / 256;
161 int g = getg24(y) + getg24(x) * n / 256;
162 int b = getb24(y) + getb24(x) * n / 256;
163
164 r = MIN(r, 255);
165 g = MIN(g, 255);
166 b = MIN(b, 255);
167
168 return makecol24(r, g, b);
169 }
170
171
172
173 /* _blender_burn24:
174 * 24 bit burn blender function.
175 */
_blender_burn24(unsigned long x,unsigned long y,unsigned long n)176 unsigned long _blender_burn24(unsigned long x, unsigned long y, unsigned long n)
177 {
178 return BLEND(24, MAX(getr24(x) - getr24(y), 0),
179 MAX(getg24(x) - getg24(y), 0),
180 MAX(getb24(x) - getb24(y), 0));
181 }
182
183
184
185 /* _blender_color24:
186 * 24 bit color blender function.
187 */
_blender_color24(unsigned long x,unsigned long y,unsigned long n)188 unsigned long _blender_color24(unsigned long x, unsigned long y, unsigned long n)
189 {
190 float xh, xs, xv;
191 float yh, ys, yv;
192 int r, g, b;
193
194 rgb_to_hsv(getr24(x), getg24(x), getb24(x), &xh, &xs, &xv);
195 rgb_to_hsv(getr24(y), getg24(y), getb24(y), &yh, &ys, &yv);
196
197 xs = T(xs, ys, n);
198 xh = T(xh, yh, n);
199
200 hsv_to_rgb(xh, xs, xv, &r, &g, &b);
201
202 return makecol24(r, g, b);
203 }
204
205
206
207 /* _blender_difference24:
208 * 24 bit difference blender function.
209 */
_blender_difference24(unsigned long x,unsigned long y,unsigned long n)210 unsigned long _blender_difference24(unsigned long x, unsigned long y, unsigned long n)
211 {
212 return BLEND(24, ABS(getr24(y) - getr24(x)),
213 ABS(getg24(y) - getg24(x)),
214 ABS(getb24(y) - getb24(x)));
215 }
216
217
218
219 /* _blender_dissolve24:
220 * 24 bit dissolve blender function.
221 */
_blender_dissolve24(unsigned long x,unsigned long y,unsigned long n)222 unsigned long _blender_dissolve24(unsigned long x, unsigned long y, unsigned long n)
223 {
224 if (n == 255)
225 return x;
226
227 return ((_al_rand() & 255) < (int)n) ? x : y;
228 }
229
230
231
232 /* _blender_dodge24:
233 * 24 bit dodge blender function.
234 */
_blender_dodge24(unsigned long x,unsigned long y,unsigned long n)235 unsigned long _blender_dodge24(unsigned long x, unsigned long y, unsigned long n)
236 {
237 return BLEND(24, getr24(x) + (getr24(y) * n / 256),
238 getg24(x) + (getg24(y) * n / 256),
239 getb24(x) + (getb24(y) * n / 256));
240 }
241
242
243
244 /* _blender_hue24:
245 * 24 bit hue blender function.
246 */
_blender_hue24(unsigned long x,unsigned long y,unsigned long n)247 unsigned long _blender_hue24(unsigned long x, unsigned long y, unsigned long n)
248 {
249 float xh, xs, xv;
250 float yh, ys, yv;
251 int r, g, b;
252
253 rgb_to_hsv(getr24(x), getg24(x), getb24(x), &xh, &xs, &xv);
254 rgb_to_hsv(getr24(y), getg24(y), getb24(y), &yh, &ys, &yv);
255
256 xh = T(xh, yh, n);
257
258 hsv_to_rgb(xh, xs, xv, &r, &g, &b);
259
260 return makecol24(r, g, b);
261 }
262
263
264
265 /* _blender_invert24:
266 * 24 bit invert blender function.
267 */
_blender_invert24(unsigned long x,unsigned long y,unsigned long n)268 unsigned long _blender_invert24(unsigned long x, unsigned long y, unsigned long n)
269 {
270 return BLEND(24, 255-getr24(x), 255-getg24(x), 255-getb24(x));
271 }
272
273
274
275 /* _blender_luminance24:
276 * 24 bit luminance blender function.
277 */
_blender_luminance24(unsigned long x,unsigned long y,unsigned long n)278 unsigned long _blender_luminance24(unsigned long x, unsigned long y, unsigned long n)
279 {
280 float xh, xs, xv;
281 float yh, ys, yv;
282 int r, g, b;
283
284 rgb_to_hsv(getr24(x), getg24(x), getb24(x), &xh, &xs, &xv);
285 rgb_to_hsv(getr24(y), getg24(y), getb24(y), &yh, &ys, &yv);
286
287 xv = T(xv, yv, n);
288
289 hsv_to_rgb(xh, xs, xv, &r, &g, &b);
290
291 return makecol24(r, g, b);
292 }
293
294
295
296 /* _blender_multiply24:
297 * 24 bit multiply blender function.
298 */
_blender_multiply24(unsigned long x,unsigned long y,unsigned long n)299 unsigned long _blender_multiply24(unsigned long x, unsigned long y, unsigned long n)
300 {
301 return BLEND(24, getr24(x) * getr24(y) / 256,
302 getg24(x) * getg24(y) / 256,
303 getb24(x) * getb24(y) / 256);
304 }
305
306
307
308 /* _blender_saturation24:
309 * 24 bit saturation blender function.
310 */
_blender_saturation24(unsigned long x,unsigned long y,unsigned long n)311 unsigned long _blender_saturation24(unsigned long x, unsigned long y, unsigned long n)
312 {
313 float xh, xs, xv;
314 float yh, ys, yv;
315 int r, g, b;
316
317 rgb_to_hsv(getr24(x), getg24(x), getb24(x), &xh, &xs, &xv);
318 rgb_to_hsv(getr24(y), getg24(y), getb24(y), &yh, &ys, &yv);
319
320 xs = T(xs, ys, n);
321
322 hsv_to_rgb(xh, xs, xv, &r, &g, &b);
323
324 return makecol24(r, g, b);
325 }
326
327
328
329 /* _blender_screen24:
330 * 24 bit screen blender function.
331 */
_blender_screen24(unsigned long x,unsigned long y,unsigned long n)332 unsigned long _blender_screen24(unsigned long x, unsigned long y, unsigned long n)
333 {
334 return BLEND(24, 255 - ((255 - getr24(x)) * (255 - getr24(y))) / 256,
335 255 - ((255 - getg24(x)) * (255 - getg24(y))) / 256,
336 255 - ((255 - getb24(x)) * (255 - getb24(y))) / 256);
337 }
338
339
340
341 #endif /* end of 24/32 bit routines */
342
343
344 #if (defined ALLEGRO_COLOR15) || (defined ALLEGRO_COLOR16)
345
346
347
348 /* _blender_trans16:
349 * 16 bit trans blender function.
350 */
_blender_trans16(unsigned long x,unsigned long y,unsigned long n)351 unsigned long _blender_trans16(unsigned long x, unsigned long y, unsigned long n)
352 {
353 unsigned long result;
354
355 if (n)
356 n = (n + 1) / 8;
357
358 x = ((x & 0xFFFF) | (x << 16)) & 0x7E0F81F;
359 y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F;
360
361 result = ((x - y) * n / 32 + y) & 0x7E0F81F;
362
363 return ((result & 0xFFFF) | (result >> 16));
364 }
365
366
367
368 /* _blender_alpha16:
369 * Combines a 32 bit RGBA sprite with a 16 bit RGB destination.
370 */
_blender_alpha16(unsigned long x,unsigned long y,unsigned long n)371 unsigned long _blender_alpha16(unsigned long x, unsigned long y, unsigned long n)
372 {
373 unsigned long result;
374
375 n = geta32(x);
376
377 if (n)
378 n = (n + 1) / 8;
379
380 x = makecol16(getr32(x), getg32(x), getb32(x));
381
382 x = (x | (x << 16)) & 0x7E0F81F;
383 y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F;
384
385 result = ((x - y) * n / 32 + y) & 0x7E0F81F;
386
387 return ((result & 0xFFFF) | (result >> 16));
388 }
389
390
391
392 /* _blender_alpha16_rgb
393 * Combines a 32 bit RGBA sprite with a 16 bit RGB destination, optimised
394 * for when both pixels are in an RGB layout.
395 */
_blender_alpha16_rgb(unsigned long x,unsigned long y,unsigned long n)396 unsigned long _blender_alpha16_rgb(unsigned long x, unsigned long y, unsigned long n)
397 {
398 unsigned long result;
399
400 n = x >> 24;
401
402 if (n)
403 n = (n + 1) / 8;
404
405 x = ((x>>3)&0x001F) | ((x>>5)&0x07E0) | ((x>>8)&0xF800);
406
407 x = (x | (x << 16)) & 0x7E0F81F;
408 y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F;
409
410 result = ((x - y) * n / 32 + y) & 0x7E0F81F;
411
412 return ((result & 0xFFFF) | (result >> 16));
413 }
414
415
416
417 /* _blender_alpha16_bgr
418 * Combines a 32 bit RGBA sprite with a 16 bit RGB destination, optimised
419 * for when one pixel is in an RGB layout and the other is BGR.
420 */
_blender_alpha16_bgr(unsigned long x,unsigned long y,unsigned long n)421 unsigned long _blender_alpha16_bgr(unsigned long x, unsigned long y, unsigned long n)
422 {
423 unsigned long result;
424
425 n = x >> 24;
426
427 if (n)
428 n = (n + 1) / 8;
429
430 x = ((x>>19)&0x001F) | ((x>>5)&0x07E0) | ((x<<8)&0xF800);
431
432 x = (x | (x << 16)) & 0x7E0F81F;
433 y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F;
434
435 result = ((x - y) * n / 32 + y) & 0x7E0F81F;
436
437 return ((result & 0xFFFF) | (result >> 16));
438 }
439
440
441
442 /* _blender_add16:
443 * 16 bit additive blender function.
444 */
_blender_add16(unsigned long x,unsigned long y,unsigned long n)445 unsigned long _blender_add16(unsigned long x, unsigned long y, unsigned long n)
446 {
447 int r = getr16(y) + getr16(x) * n / 256;
448 int g = getg16(y) + getg16(x) * n / 256;
449 int b = getb16(y) + getb16(x) * n / 256;
450
451 r = MIN(r, 255);
452 g = MIN(g, 255);
453 b = MIN(b, 255);
454
455 return makecol16(r, g, b);
456 }
457
458
459
460 /* _blender_burn16:
461 * 16 bit burn blender function.
462 */
_blender_burn16(unsigned long x,unsigned long y,unsigned long n)463 unsigned long _blender_burn16(unsigned long x, unsigned long y, unsigned long n)
464 {
465 return BLEND(16, MAX(getr16(x) - getr16(y), 0),
466 MAX(getg16(x) - getg16(y), 0),
467 MAX(getb16(x) - getb16(y), 0));
468 }
469
470
471
472 /* _blender_color16:
473 * 16 bit color blender function.
474 */
_blender_color16(unsigned long x,unsigned long y,unsigned long n)475 unsigned long _blender_color16(unsigned long x, unsigned long y, unsigned long n)
476 {
477 float xh, xs, xv;
478 float yh, ys, yv;
479 int r, g, b;
480
481 rgb_to_hsv(getr16(x), getg16(x), getb16(x), &xh, &xs, &xv);
482 rgb_to_hsv(getr16(y), getg16(y), getb16(y), &yh, &ys, &yv);
483
484 xs = T(xs, ys, n);
485 xh = T(xh, yh, n);
486
487 hsv_to_rgb(xh, xs, xv, &r, &g, &b);
488
489 return makecol16(r, g, b);
490 }
491
492
493
494 /* _blender_difference16:
495 * 16 bit difference blender function.
496 */
_blender_difference16(unsigned long x,unsigned long y,unsigned long n)497 unsigned long _blender_difference16(unsigned long x, unsigned long y, unsigned long n)
498 {
499 return BLEND(16, ABS(getr16(y) - getr16(x)),
500 ABS(getg16(y) - getg16(x)),
501 ABS(getb16(y) - getb16(x)));
502 }
503
504
505
506 /* _blender_dissolve16:
507 * 16 bit dissolve blender function.
508 */
_blender_dissolve16(unsigned long x,unsigned long y,unsigned long n)509 unsigned long _blender_dissolve16(unsigned long x, unsigned long y, unsigned long n)
510 {
511 if (n == 255)
512 return x;
513
514 return ((_al_rand() & 255) < (int)n) ? x : y;
515 }
516
517
518
519 /* _blender_dodge16:
520 * 16 bit dodge blender function.
521 */
_blender_dodge16(unsigned long x,unsigned long y,unsigned long n)522 unsigned long _blender_dodge16(unsigned long x, unsigned long y, unsigned long n)
523 {
524 return BLEND(16, getr16(x) + (getr16(y) * n / 256),
525 getg16(x) + (getg16(y) * n / 256),
526 getb16(x) + (getb16(y) * n / 256));
527 }
528
529
530
531 /* _blender_hue16:
532 * 16 bit hue blender function.
533 */
_blender_hue16(unsigned long x,unsigned long y,unsigned long n)534 unsigned long _blender_hue16(unsigned long x, unsigned long y, unsigned long n)
535 {
536 float xh, xs, xv;
537 float yh, ys, yv;
538 int r, g, b;
539
540 rgb_to_hsv(getr16(x), getg16(x), getb16(x), &xh, &xs, &xv);
541 rgb_to_hsv(getr16(y), getg16(y), getb16(y), &yh, &ys, &yv);
542
543 xh = T(xh, yh, n);
544
545 hsv_to_rgb(xh, xs, xv, &r, &g, &b);
546
547 return makecol16(r, g, b);
548 }
549
550
551
552 /* _blender_invert16:
553 * 16 bit invert blender function.
554 */
_blender_invert16(unsigned long x,unsigned long y,unsigned long n)555 unsigned long _blender_invert16(unsigned long x, unsigned long y, unsigned long n)
556 {
557 return BLEND(16, 255-getr16(x), 255-getg16(x), 255-getb16(x));
558 }
559
560
561
562 /* _blender_luminance16:
563 * 16 bit luminance blender function.
564 */
_blender_luminance16(unsigned long x,unsigned long y,unsigned long n)565 unsigned long _blender_luminance16(unsigned long x, unsigned long y, unsigned long n)
566 {
567 float xh, xs, xv;
568 float yh, ys, yv;
569 int r, g, b;
570
571 rgb_to_hsv(getr16(x), getg16(x), getb16(x), &xh, &xs, &xv);
572 rgb_to_hsv(getr16(y), getg16(y), getb16(y), &yh, &ys, &yv);
573
574 xv = T(xv, yv, n);
575
576 hsv_to_rgb(xh, xs, xv, &r, &g, &b);
577
578 return makecol16(r, g, b);
579 }
580
581
582
583 /* _blender_multiply16:
584 * 16 bit multiply blender function.
585 */
_blender_multiply16(unsigned long x,unsigned long y,unsigned long n)586 unsigned long _blender_multiply16(unsigned long x, unsigned long y, unsigned long n)
587 {
588 return BLEND(16, getr16(x) * getr16(y) / 256,
589 getg16(x) * getg16(y) / 256,
590 getb16(x) * getb16(y) / 256);
591 }
592
593
594
595 /* _blender_saturation16:
596 * 16 bit saturation blender function.
597 */
_blender_saturation16(unsigned long x,unsigned long y,unsigned long n)598 unsigned long _blender_saturation16(unsigned long x, unsigned long y, unsigned long n)
599 {
600 float xh, xs, xv;
601 float yh, ys, yv;
602 int r, g, b;
603
604 rgb_to_hsv(getr16(x), getg16(x), getb16(x), &xh, &xs, &xv);
605 rgb_to_hsv(getr16(y), getg16(y), getb16(y), &yh, &ys, &yv);
606
607 xs = T(xs, ys, n);
608
609 hsv_to_rgb(xh, xs, xv, &r, &g, &b);
610
611 return makecol16(r, g, b);
612 }
613
614
615
616 /* _blender_screen16:
617 * 16 bit screen blender function.
618 */
_blender_screen16(unsigned long x,unsigned long y,unsigned long n)619 unsigned long _blender_screen16(unsigned long x, unsigned long y, unsigned long n)
620 {
621 return BLEND(16, 255 - ((255 - getr16(x)) * (255 - getr16(y))) / 256,
622 255 - ((255 - getg16(x)) * (255 - getg16(y))) / 256,
623 255 - ((255 - getb16(x)) * (255 - getb16(y))) / 256);
624 }
625
626
627
628 /* _blender_trans15:
629 * 15 bit trans blender function.
630 */
_blender_trans15(unsigned long x,unsigned long y,unsigned long n)631 unsigned long _blender_trans15(unsigned long x, unsigned long y, unsigned long n)
632 {
633 unsigned long result;
634
635 if (n)
636 n = (n + 1) / 8;
637
638 x = ((x & 0xFFFF) | (x << 16)) & 0x3E07C1F;
639 y = ((y & 0xFFFF) | (y << 16)) & 0x3E07C1F;
640
641 result = ((x - y) * n / 32 + y) & 0x3E07C1F;
642
643 return ((result & 0xFFFF) | (result >> 16));
644 }
645
646
647
648 /* _blender_alpha15:
649 * Combines a 32 bit RGBA sprite with a 15 bit RGB destination.
650 */
_blender_alpha15(unsigned long x,unsigned long y,unsigned long n)651 unsigned long _blender_alpha15(unsigned long x, unsigned long y, unsigned long n)
652 {
653 unsigned long result;
654
655 n = geta32(x);
656
657 if (n)
658 n = (n + 1) / 8;
659
660 x = makecol15(getr32(x), getg32(x), getb32(x));
661
662 x = (x | (x << 16)) & 0x3E07C1F;
663 y = ((y & 0xFFFF) | (y << 16)) & 0x3E07C1F;
664
665 result = ((x - y) * n / 32 + y) & 0x3E07C1F;
666
667 return ((result & 0xFFFF) | (result >> 16));
668 }
669
670
671
672 /* _blender_alpha15_rgb
673 * Combines a 32 bit RGBA sprite with a 15 bit RGB destination, optimised
674 * for when both pixels are in an RGB layout.
675 */
_blender_alpha15_rgb(unsigned long x,unsigned long y,unsigned long n)676 unsigned long _blender_alpha15_rgb(unsigned long x, unsigned long y, unsigned long n)
677 {
678 unsigned long result;
679
680 n = x >> 24;
681
682 if (n)
683 n = (n + 1) / 8;
684
685 x = ((x>>3)&0x001F) | ((x>>6)&0x03E0) | ((x>>9)&0xEC00);
686
687 x = (x | (x << 16)) & 0x3E07C1F;
688 y = ((y & 0xFFFF) | (y << 16)) & 0x3E07C1F;
689
690 result = ((x - y) * n / 32 + y) & 0x3E07C1F;
691
692 return ((result & 0xFFFF) | (result >> 16));
693 }
694
695
696
697 /* _blender_alpha15_bgr
698 * Combines a 32 bit RGBA sprite with a 15 bit RGB destination, optimised
699 * for when one pixel is in an RGB layout and the other is BGR.
700 */
_blender_alpha15_bgr(unsigned long x,unsigned long y,unsigned long n)701 unsigned long _blender_alpha15_bgr(unsigned long x, unsigned long y, unsigned long n)
702 {
703 unsigned long result;
704
705 n = x >> 24;
706
707 if (n)
708 n = (n + 1) / 8;
709
710 x = ((x>>19)&0x001F) | ((x>>6)&0x03E0) | ((x<<7)&0xEC00);
711
712 x = (x | (x << 16)) & 0x3E07C1F;
713 y = ((y & 0xFFFF) | (y << 16)) & 0x3E07C1F;
714
715 result = ((x - y) * n / 32 + y) & 0x3E07C1F;
716
717 return ((result & 0xFFFF) | (result >> 16));
718 }
719
720
721
722 /* _blender_add15:
723 * 15 bit additive blender function.
724 */
_blender_add15(unsigned long x,unsigned long y,unsigned long n)725 unsigned long _blender_add15(unsigned long x, unsigned long y, unsigned long n)
726 {
727 int r = getr15(y) + getr15(x) * n / 256;
728 int g = getg15(y) + getg15(x) * n / 256;
729 int b = getb15(y) + getb15(x) * n / 256;
730
731 r = MIN(r, 255);
732 g = MIN(g, 255);
733 b = MIN(b, 255);
734
735 return makecol15(r, g, b);
736 }
737
738
739
740 /* _blender_burn15:
741 * 15 bit burn blender function.
742 */
_blender_burn15(unsigned long x,unsigned long y,unsigned long n)743 unsigned long _blender_burn15(unsigned long x, unsigned long y, unsigned long n)
744 {
745 return BLEND(15, MAX(getr15(x) - getr15(y), 0),
746 MAX(getg15(x) - getg15(y), 0),
747 MAX(getb15(x) - getb15(y), 0));
748 }
749
750
751
752 /* _blender_color15:
753 * 15 bit color blender function.
754 */
_blender_color15(unsigned long x,unsigned long y,unsigned long n)755 unsigned long _blender_color15(unsigned long x, unsigned long y, unsigned long n)
756 {
757 float xh, xs, xv;
758 float yh, ys, yv;
759 int r, g, b;
760
761 rgb_to_hsv(getr15(x), getg15(x), getb15(x), &xh, &xs, &xv);
762 rgb_to_hsv(getr15(y), getg15(y), getb15(y), &yh, &ys, &yv);
763
764 xs = T(xs, ys, n);
765 xh = T(xh, yh, n);
766
767 hsv_to_rgb(xh, xs, xv, &r, &g, &b);
768
769 return makecol15(r, g, b);
770 }
771
772
773
774 /* _blender_difference15:
775 * 15 bit difference blender function.
776 */
_blender_difference15(unsigned long x,unsigned long y,unsigned long n)777 unsigned long _blender_difference15(unsigned long x, unsigned long y, unsigned long n)
778 {
779 return BLEND(15, ABS(getr15(y) - getr15(x)),
780 ABS(getg15(y) - getg15(x)),
781 ABS(getb15(y) - getb15(x)));
782 }
783
784
785
786 /* _blender_dissolve15:
787 * 15 bit dissolve blender function.
788 */
_blender_dissolve15(unsigned long x,unsigned long y,unsigned long n)789 unsigned long _blender_dissolve15(unsigned long x, unsigned long y, unsigned long n)
790 {
791 if (n == 255)
792 return x;
793
794 return ((_al_rand() & 255) < (int)n) ? x : y;
795 }
796
797
798
799 /* _blender_dodge15:
800 * 15 bit dodge blender function.
801 */
_blender_dodge15(unsigned long x,unsigned long y,unsigned long n)802 unsigned long _blender_dodge15(unsigned long x, unsigned long y, unsigned long n)
803 {
804 return BLEND(15, getr15(x) + (getr15(y) * n / 256),
805 getg15(x) + (getg15(y) * n / 256),
806 getb15(x) + (getb15(y) * n / 256));
807 }
808
809
810
811 /* _blender_hue15:
812 * 15 bit hue blender function.
813 */
_blender_hue15(unsigned long x,unsigned long y,unsigned long n)814 unsigned long _blender_hue15(unsigned long x, unsigned long y, unsigned long n)
815 {
816 float xh, xs, xv;
817 float yh, ys, yv;
818 int r, g, b;
819
820 rgb_to_hsv(getr15(x), getg15(x), getb15(x), &xh, &xs, &xv);
821 rgb_to_hsv(getr15(y), getg15(y), getb15(y), &yh, &ys, &yv);
822
823 xh = T(xh, yh, n);
824
825 hsv_to_rgb(xh, xs, xv, &r, &g, &b);
826
827 return makecol15(r, g, b);
828 }
829
830
831
832 /* _blender_invert15:
833 * 15 bit invert blender function.
834 */
_blender_invert15(unsigned long x,unsigned long y,unsigned long n)835 unsigned long _blender_invert15(unsigned long x, unsigned long y, unsigned long n)
836 {
837 return BLEND(15, 255-getr15(x), 255-getg15(x), 255-getb15(x));
838 }
839
840
841
842 /* _blender_luminance15:
843 * 15 bit luminance blender function.
844 */
_blender_luminance15(unsigned long x,unsigned long y,unsigned long n)845 unsigned long _blender_luminance15(unsigned long x, unsigned long y, unsigned long n)
846 {
847 float xh, xs, xv;
848 float yh, ys, yv;
849 int r, g, b;
850
851 rgb_to_hsv(getr15(x), getg15(x), getb15(x), &xh, &xs, &xv);
852 rgb_to_hsv(getr15(y), getg15(y), getb15(y), &yh, &ys, &yv);
853
854 xv = T(xv, yv, n);
855
856 hsv_to_rgb(xh, xs, xv, &r, &g, &b);
857
858 return makecol15(r, g, b);
859 }
860
861
862
863 /* _blender_multiply15:
864 * 15 bit multiply blender function.
865 */
_blender_multiply15(unsigned long x,unsigned long y,unsigned long n)866 unsigned long _blender_multiply15(unsigned long x, unsigned long y, unsigned long n)
867 {
868 return BLEND(15, getr15(x) * getr15(y) / 256,
869 getg15(x) * getg15(y) / 256,
870 getb15(x) * getb15(y) / 256);
871 }
872
873
874
875 /* _blender_saturation15:
876 * 15 bit saturation blender function.
877 */
_blender_saturation15(unsigned long x,unsigned long y,unsigned long n)878 unsigned long _blender_saturation15(unsigned long x, unsigned long y, unsigned long n)
879 {
880 float xh, xs, xv;
881 float yh, ys, yv;
882 int r, g, b;
883
884 rgb_to_hsv(getr15(x), getg15(x), getb15(x), &xh, &xs, &xv);
885 rgb_to_hsv(getr15(y), getg15(y), getb15(y), &yh, &ys, &yv);
886
887 xs = T(xs, ys, n);
888
889 hsv_to_rgb(xh, xs, xv, &r, &g, &b);
890
891 return makecol15(r, g, b);
892 }
893
894
895
896 /* _blender_screen15:
897 * 15 bit screen blender function.
898 */
_blender_screen15(unsigned long x,unsigned long y,unsigned long n)899 unsigned long _blender_screen15(unsigned long x, unsigned long y, unsigned long n)
900 {
901 return BLEND(15, 255 - ((255 - getr15(x)) * (255 - getr15(y))) / 256,
902 255 - ((255 - getg15(x)) * (255 - getg15(y))) / 256,
903 255 - ((255 - getb15(x)) * (255 - getb15(y))) / 256);
904 }
905
906
907
908 #endif /* end of 15/16 bit routines */
909
910
911
912 #ifdef ALLEGRO_COLOR16
913 #define BF16(name) name
914 #else
915 #define BF16(name) _blender_black
916 #endif
917
918
919 #if (defined ALLEGRO_COLOR24) || (defined ALLEGRO_COLOR32)
920 #define BF24(name) name
921 #else
922 #define BF24(name) _blender_black
923 #endif
924
925
926
927 /* these functions are all the same, so we can generate them with a macro */
928 #define SET_BLENDER_FUNC(name) \
929 void set_##name##_blender(int r, int g, int b, int a) \
930 { \
931 if (gfx_driver && gfx_driver->set_blender_mode) \
932 gfx_driver->set_blender_mode(blender_mode_##name, r, g, b, a);\
933 set_blender_mode(BF16(_blender_##name##15), \
934 BF16(_blender_##name##16), \
935 BF24(_blender_##name##24), \
936 r, g, b, a); \
937 }
938
939
940 SET_BLENDER_FUNC(trans);
941 SET_BLENDER_FUNC(add);
942 SET_BLENDER_FUNC(burn);
943 SET_BLENDER_FUNC(color);
944 SET_BLENDER_FUNC(difference);
945 SET_BLENDER_FUNC(dissolve);
946 SET_BLENDER_FUNC(dodge);
947 SET_BLENDER_FUNC(hue);
948 SET_BLENDER_FUNC(invert);
949 SET_BLENDER_FUNC(luminance);
950 SET_BLENDER_FUNC(multiply);
951 SET_BLENDER_FUNC(saturation);
952 SET_BLENDER_FUNC(screen);
953
954
955
956 /* set_alpha_blender:
957 * Sets the special RGBA blending mode.
958 */
set_alpha_blender(void)959 void set_alpha_blender(void)
960 {
961 BLENDER_FUNC f15, f16, f24, f32;
962 int r, b;
963
964 /* Call gfx_driver->set_blender_mode() for hardware acceleration */
965 if (gfx_driver && gfx_driver->set_blender_mode)
966 gfx_driver->set_blender_mode(blender_mode_alpha, 0, 0, 0, 0);
967
968 /* check which way around the 32 bit pixels are */
969 if ((_rgb_g_shift_32 == 8) && (_rgb_a_shift_32 == 24)) {
970 r = (_rgb_r_shift_32) ? 1 : 0;
971 b = (_rgb_b_shift_32) ? 1 : 0;
972 }
973 else
974 r = b = 0;
975
976 #ifdef ALLEGRO_COLOR16
977
978 /* decide which 15 bit blender to use */
979 if ((_rgb_r_shift_15 == r*10) && (_rgb_g_shift_15 == 5) && (_rgb_b_shift_15 == b*10))
980 f15 = _blender_alpha15_rgb;
981 else if ((_rgb_r_shift_15 == b*10) && (_rgb_g_shift_15 == 5) && (_rgb_b_shift_15 == r*10))
982 f15 = _blender_alpha15_bgr;
983 else
984 f15 = _blender_alpha15;
985
986 /* decide which 16 bit blender to use */
987 if ((_rgb_r_shift_16 == r*11) && (_rgb_g_shift_16 == 5) && (_rgb_b_shift_16 == b*11))
988 f16 = _blender_alpha16_rgb;
989 else if ((_rgb_r_shift_16 == b*11) && (_rgb_g_shift_16 == 5) && (_rgb_b_shift_16 == r*11))
990 f16 = _blender_alpha16_bgr;
991 else
992 f16 = _blender_alpha16;
993
994 #else
995
996 /* hicolor not included in this build */
997 f15 = _blender_black;
998 f16 = _blender_black;
999
1000 #endif
1001
1002 #ifdef ALLEGRO_COLOR24
1003
1004 /* decide which 24 bit blender to use */
1005 if ((_rgb_r_shift_24 == r*16) && (_rgb_g_shift_24 == 8) && (_rgb_b_shift_24 == b*16))
1006 f24 = _blender_alpha32;
1007 else if ((_rgb_r_shift_24 == b*16) && (_rgb_g_shift_24 == 8) && (_rgb_b_shift_24 == r*16))
1008 f24 = _blender_alpha24_bgr;
1009 else
1010 f24 = _blender_alpha24;
1011
1012 #else
1013
1014 /* 24 bit color not included in this build */
1015 f24 = _blender_black;
1016
1017 #endif
1018
1019 #ifdef ALLEGRO_COLOR32
1020 f32 = _blender_alpha32;
1021 #else
1022 f32 = _blender_black;
1023 #endif
1024
1025 set_blender_mode_ex(_blender_black, _blender_black, _blender_black,
1026 f32, f15, f16, f24, 0, 0, 0, 0);
1027 }
1028
1029
1030
1031 #ifdef ALLEGRO_COLOR32
1032
1033 /* _blender_write_alpha:
1034 * Overlays an alpha channel onto an existing 32 bit RGBA bitmap.
1035 */
_blender_write_alpha(unsigned long x,unsigned long y,unsigned long n)1036 unsigned long _blender_write_alpha(unsigned long x, unsigned long y, unsigned long n)
1037 {
1038 return (y & 0xFFFFFF) | (x << 24);
1039 }
1040
1041 #endif
1042
1043
1044
1045 /* set_write_alpha_blender:
1046 * Sets the special RGBA editing mode.
1047 */
set_write_alpha_blender(void)1048 void set_write_alpha_blender(void)
1049 {
1050 BLENDER_FUNC f32;
1051
1052 #ifdef ALLEGRO_COLOR32
1053 f32 = _blender_write_alpha;
1054 #else
1055 f32 = _blender_black;
1056 #endif
1057
1058 set_blender_mode_ex(_blender_black, _blender_black, _blender_black,
1059 f32,
1060 _blender_black, _blender_black, _blender_black,
1061 0, 0, 0, 0);
1062 }
1063
1064