FreeBASIC  0.91.0
gfx_put_add.c
Go to the documentation of this file.
1 /* ADD drawing method for PUT statement */
2 
3 #include "fb_gfx.h"
4 
5 
6 extern void fb_hPutOrC(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param);
7 
8 #ifdef HOST_X86
9 
10 #include "x86/fb_gfx_mmx.h"
11 
12 extern void fb_hPutOrMMX(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param);
13 extern void fb_hPutAdd2MMX(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param);
14 extern void fb_hPutAdd4MMX(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param);
15 
16 #endif
17 
18 
19 /*:::::*/
20 static void fb_hPutAdd2C(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param)
21 {
22  unsigned short *s = (unsigned short *)src, *d;
23  unsigned int sc, dc, overflow;
24  int x;
25 
26  alpha = (alpha + 7) >> 3;
27  src_pitch = (src_pitch >> 1) - w;
28  for (; h; h--) {
29  d = (unsigned short *)dest;
30  for (x = w; x; x--) {
31  sc = *s;
32  dc = *d;
33  if (sc != MASK_COLOR_16) {
34  sc = ((sc << 16) | sc) & 0x07C0F81F;
35  sc = ((sc * alpha) >> 5) & 0x07C0F81F;
36  dc = ((dc << 16) | dc) & 0x07C0F81F;
37  sc += dc;
38  overflow = sc & 0x08010020;
39  overflow -= (overflow >> 5);
40  sc |= overflow;
41  sc &= 0x07C0F81F;
42  sc |= (sc >> 16);
43  *d = sc & 0xFFFF;
44  }
45  s++;
46  d++;
47  }
48  s += src_pitch;
49  dest += dest_pitch;
50  }
51 }
52 
53 
54 /*:::::*/
55 static void fb_hPutAdd4C(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param)
56 {
57  unsigned int *s = (unsigned int *)src, *d;
58  unsigned int sc, dc, temp1, temp2;
59  int x;
60 
61  src_pitch = (src_pitch >> 2) - w;
62  for (; h; h--) {
63  d = (unsigned int *)dest;
64  for (x = w; x; x--) {
65  sc = *s;
66  dc = *d;
67  if ((sc & 0xFFFFFF) != MASK_COLOR_32) {
68  temp1 = sc & 0xFF00FF;
69  temp2 = (sc >> 8) & 0xFF00FF;
70  temp1 = ((temp1 * alpha) >> 8) & 0xFF00FF;
71  temp2 = (temp2 * alpha) & 0xFF00FF00;
72  sc = temp1 | temp2;
73  temp1 = sc & 0x80808080;
74  temp2 = dc & 0x80808080;
75  sc = (sc & 0x7F7F7F7F) + (dc & 0x7F7F7F7F);
76  dc = temp1;
77  temp1 = temp1 | temp2;
78  temp2 = dc & temp2;
79  dc = temp1 & sc;
80  sc |= ((((temp2 | dc) >> 7) + 0x7F7F7F7F) ^ 0x7F7F7F7F) | temp1;
81  *d = sc;
82  }
83  s++;
84  d++;
85  }
86  s += src_pitch;
87  dest += dest_pitch;
88  }
89 }
90 
91 
92 /*:::::*/
93 void fb_hPutAdd(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param)
94 {
95  static PUTTER *all_putters[] = {
97 #ifdef HOST_X86
98  fb_hPutOrMMX, fb_hPutAdd2MMX, NULL, fb_hPutAdd4MMX,
99 #endif
100  };
101  PUTTER *putter;
103 
104  if (!context->putter[PUT_MODE_ADD]) {
105 #ifdef HOST_X86
106  if (__fb_gfx->flags & HAS_MMX)
107  context->putter[PUT_MODE_ADD] = &all_putters[4];
108  else
109 #endif
110  context->putter[PUT_MODE_ADD] = &all_putters[0];
111  }
112  putter = context->putter[PUT_MODE_ADD][context->target_bpp - 1];
113  alpha &= 0xFF;
114 
115  putter(src, dest, w, h, src_pitch, dest_pitch, alpha, blender, param);
116 }