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