1 // BlinkenSisters - Hunt for the Lost Pixels
2 // Bringing back the fun of the 80s
3 //
4 // (C) 2005-07 Rene Schickbauer, Wolfgang Dautermann
5 //
6 // See License.txt for licensing information
7 //
8
9
10 #include "globals.h"
11 #include "blending.h"
12
blend_avg(const Uint32 source,const Uint32 target)13 Uint32 blend_avg(const Uint32 source, const Uint32 target)
14 {
15 Uint32 sourcer = (source >> 0) & 0xff;
16 Uint32 sourceg = (source >> 8) & 0xff;
17 Uint32 sourceb = (source >> 16) & 0xff;
18 Uint32 targetr = (target >> 0) & 0xff;
19 Uint32 targetg = (target >> 8) & 0xff;
20 Uint32 targetb = (target >> 16) & 0xff;
21
22 targetr = (sourcer + targetr) >> 1;
23 targetg = (sourceg + targetg) >> 1;
24 targetb = (sourceb + targetb) >> 1;
25
26 return (targetr << 0) |
27 (targetg << 8) |
28 (targetb << 16);
29 }
30
blend_mul(const Uint32 source,const Uint32 target)31 Uint32 blend_mul(const Uint32 source, const Uint32 target)
32 {
33 Uint32 sourcer = (source >> 0) & 0xff;
34 Uint32 sourceg = (source >> 8) & 0xff;
35 Uint32 sourceb = (source >> 16) & 0xff;
36 Uint32 targetr = (target >> 0) & 0xff;
37 Uint32 targetg = (target >> 8) & 0xff;
38 Uint32 targetb = (target >> 16) & 0xff;
39
40 targetr = (sourcer * targetr) >> 8;
41 targetg = (sourceg * targetg) >> 8;
42 targetb = (sourceb * targetb) >> 8;
43
44 return (targetr << 0) |
45 (targetg << 8) |
46 (targetb << 16);
47 }
48
blend_add(const Uint32 source,const Uint32 target)49 Uint32 blend_add(const Uint32 source, const Uint32 target)
50 {
51 Uint32 sourcer = (source >> 0) & 0xff;
52 Uint32 sourceg = (source >> 8) & 0xff;
53 Uint32 sourceb = (source >> 16) & 0xff;
54 Uint32 targetr = (target >> 0) & 0xff;
55 Uint32 targetg = (target >> 8) & 0xff;
56 Uint32 targetb = (target >> 16) & 0xff;
57
58 targetr += sourcer;
59 targetg += sourceg;
60 targetb += sourceb;
61
62 if (targetr > 0xff) targetr = 0xff;
63 if (targetg > 0xff) targetg = 0xff;
64 if (targetb > 0xff) targetb = 0xff;
65
66 return (targetr << 0) |
67 (targetg << 8) |
68 (targetb << 16);
69 }
70
blend_alpha(const Uint32 source,const Uint32 target,const Uint32 factor)71 Uint32 blend_alpha(const Uint32 source, const Uint32 target, const Uint32 factor)
72 {
73
74 double sfact = (255.0 - (double)factor) / 255.0;
75 double tfact = (double)factor / 255.0;
76
77 Uint32 sourcer = (source >> 0) & 0xff;
78 Uint32 sourceg = (source >> 8) & 0xff;
79 Uint32 sourceb = (source >> 16) & 0xff;
80 Uint32 targetr = (target >> 0) & 0xff;
81 Uint32 targetg = (target >> 8) & 0xff;
82 Uint32 targetb = (target >> 16) & 0xff;
83
84 sourcer = (Uint32)((double)sourcer * sfact);
85 sourceg = (Uint32)((double)sourceg * sfact);
86 sourceb = (Uint32)((double)sourceb * sfact);
87
88 if (sourcer > 0xff) sourcer = 0xff;
89 if (sourceg > 0xff) sourceg = 0xff;
90 if (sourceb > 0xff) sourceb = 0xff;
91
92 targetr = (Uint32)((double)targetr * tfact);
93 targetg = (Uint32)((double)targetg * tfact);
94 targetb = (Uint32)((double)targetb * tfact);
95
96 if (targetr > 0xff) targetr = 0xff;
97 if (targetg > 0xff) targetg = 0xff;
98 if (targetb > 0xff) targetb = 0xff;
99
100 targetr = sourcer + targetr;
101 targetg = sourcer + targetg;
102 targetb = sourcer + targetb;
103
104 return (targetr << 0) | (targetg << 8) | (targetb << 16);
105
106 }
107
blend_darkenRect(const Sint32 x,const Sint32 y,const Sint32 width,const Sint32 height,const Uint32 factor)108 void blend_darkenRect(const Sint32 x, const Sint32 y, const Sint32 width, const Sint32 height, const Uint32 factor)
109 {
110 Sint32 i, j;
111 Sint32 pitch = gScreen->pitch / 4;
112
113 if ( SDL_MUSTLOCK(gScreen) )
114 {
115 if ( SDL_LockSurface(gScreen) < 0 ) {
116 return;
117 }
118 }
119
120
121 for (i = 0; i < height; i++)
122 {
123 // vertical clipping: (top and bottom)
124 if ((y + i) >= 0 && (y + i) < SCR_HEIGHT)
125 {
126 Sint32 len = width;
127 Sint32 xofs = x;
128
129 // left border
130 if (xofs < 0)
131 {
132 len += xofs;
133 xofs = 0;
134 }
135
136 // right border
137 if (xofs + len >= SCR_WIDTH)
138 {
139 len -= (xofs + len) - SCR_WIDTH;
140 }
141 Sint32 ofs = (i + y) * pitch + xofs;
142
143 // note that len may be 0 at this point,
144 // and no pixels get drawn!
145
146 for (j = 0; j < len; j++) {
147 //((Uint32*)gScreen->pixels)[ofs + j] = c;
148 ((Uint32*)gScreen->pixels)[ofs + j] = blend_mul(((Uint32*)gScreen->pixels)[ofs + j], factor);
149 }
150 }
151 }
152
153 if (SDL_MUSTLOCK(gScreen)) SDL_UnlockSurface(gScreen);
154 }
155
blend_brightenRect(const Sint32 x,const Sint32 y,const Sint32 width,const Sint32 height,const Uint32 factor)156 void blend_brightenRect(const Sint32 x, const Sint32 y, const Sint32 width, const Sint32 height, const Uint32 factor)
157 {
158 Sint32 i, j;
159 Sint32 pitch = gScreen->pitch / 4;
160
161 if ( SDL_MUSTLOCK(gScreen) )
162 {
163 if ( SDL_LockSurface(gScreen) < 0 ) {
164 return;
165 }
166 }
167
168 for (i = 0; i < height; i++)
169 {
170 // vertical clipping: (top and bottom)
171 if ((y + i) >= 0 && (y + i) < SCR_HEIGHT)
172 {
173 Sint32 len = width;
174 Sint32 xofs = x;
175
176 // left border
177 if (xofs < 0)
178 {
179 len += xofs;
180 xofs = 0;
181 }
182
183 // right border
184 if (xofs + len >= SCR_WIDTH)
185 {
186 len -= (xofs + len) - SCR_WIDTH;
187 }
188 Sint32 ofs = (i + y) * pitch + xofs;
189
190 // note that len may be 0 at this point,
191 // and no pixels get drawn!
192
193 for (j = 0; j < len; j++) {
194 //((Uint32*)gScreen->pixels)[ofs + j] = c;
195 ((Uint32*)gScreen->pixels)[ofs + j] = blend_add(((Uint32*)gScreen->pixels)[ofs + j], factor);
196 }
197 }
198 }
199 if (SDL_MUSTLOCK(gScreen)) SDL_UnlockSurface(gScreen);
200 }
201