22 #include "graphics/blit.h" 30 template<
bool rgbmod,
bool alphamod>
34 ca(alphamod ? ((color >> BlendBlit::kAModShift) & 0xFF) : 255),
35 cr(rgbmod ? ((color >> BlendBlit::kRModShift) & 0xFF) : 255),
36 cg(rgbmod ? ((color >> BlendBlit::kGModShift) & 0xFF) : 255),
37 cb(rgbmod ? ((color >> BlendBlit::kBModShift) & 0xFF) : 255) {}
40 const byte ca, cr, cg, cb;
43 template<
bool rgbmod,
bool alphamod>
48 inline void normal(
const byte *in, byte *out)
const {
52 ina = in[BlendBlit::kAIndex] * this->ca >> 8;
54 ina = in[BlendBlit::kAIndex];
59 out[BlendBlit::kAIndex] = 255;
60 out[BlendBlit::kBIndex] = (in[BlendBlit::kBIndex] * this->cb >> 8);
61 out[BlendBlit::kGIndex] = (in[BlendBlit::kGIndex] * this->cg >> 8);
62 out[BlendBlit::kRIndex] = (in[BlendBlit::kRIndex] * this->cr >> 8);
64 out[BlendBlit::kAIndex] = 255;
65 out[BlendBlit::kBIndex] = in[BlendBlit::kBIndex];
66 out[BlendBlit::kGIndex] = in[BlendBlit::kGIndex];
67 out[BlendBlit::kRIndex] = in[BlendBlit::kRIndex];
69 }
else if (ina != 0) {
71 const uint outb = (out[BlendBlit::kBIndex] * (255 - ina) >> 8);
72 const uint outg = (out[BlendBlit::kGIndex] * (255 - ina) >> 8);
73 const uint outr = (out[BlendBlit::kRIndex] * (255 - ina) >> 8);
75 out[BlendBlit::kAIndex] = 255;
76 out[BlendBlit::kBIndex] = outb + (in[BlendBlit::kBIndex] * ina * this->cb >> 16);
77 out[BlendBlit::kGIndex] = outg + (in[BlendBlit::kGIndex] * ina * this->cg >> 16);
78 out[BlendBlit::kRIndex] = outr + (in[BlendBlit::kRIndex] * ina * this->cr >> 16);
80 out[BlendBlit::kAIndex] = 255;
81 out[BlendBlit::kBIndex] = (out[BlendBlit::kBIndex] * (255 - ina) + in[BlendBlit::kBIndex] * ina) >> 8;
82 out[BlendBlit::kGIndex] = (out[BlendBlit::kGIndex] * (255 - ina) + in[BlendBlit::kGIndex] * ina) >> 8;
83 out[BlendBlit::kRIndex] = (out[BlendBlit::kRIndex] * (255 - ina) + in[BlendBlit::kRIndex] * ina) >> 8;
89 inline void fill(byte *out)
const {
90 uint32 ina = this->ca;
106 const uint outb = (out[BlendBlit::kBIndex] * (255 - ina) >> 8);
107 const uint outg = (out[BlendBlit::kGIndex] * (255 - ina) >> 8);
108 const uint outr = (out[BlendBlit::kRIndex] * (255 - ina) >> 8);
110 out[BlendBlit::kAIndex] = 255;
111 out[BlendBlit::kBIndex] = outb + (255 * ina * this->cb >> 16);
112 out[BlendBlit::kGIndex] = outg + (255 * ina * this->cg >> 16);
113 out[BlendBlit::kRIndex] = outr + (255 * ina * this->cr >> 16);
115 out[BlendBlit::kAIndex] = 255;
116 out[BlendBlit::kBIndex] = (out[BlendBlit::kBIndex] * (255 - ina) + 255 * ina) >> 8;
117 out[BlendBlit::kGIndex] = (out[BlendBlit::kGIndex] * (255 - ina) + 255 * ina) >> 8;
118 out[BlendBlit::kRIndex] = (out[BlendBlit::kRIndex] * (255 - ina) + 255 * ina) >> 8;
125 template<
bool rgbmod,
bool alphamod>
130 inline void normal(
const byte *in, byte *out)
const {
134 ina = in[BlendBlit::kAIndex] * this->ca >> 8;
136 ina = in[BlendBlit::kAIndex];
141 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] * ((in[BlendBlit::kBIndex] * this->cb) >> 8) >> 8;
142 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] * ((in[BlendBlit::kGIndex] * this->cg) >> 8) >> 8;
143 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] * ((in[BlendBlit::kRIndex] * this->cr) >> 8) >> 8;
145 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] * in[BlendBlit::kBIndex] >> 8;
146 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] * in[BlendBlit::kGIndex] >> 8;
147 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] * in[BlendBlit::kRIndex] >> 8;
149 }
else if (ina != 0) {
151 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] * ((in[BlendBlit::kBIndex] * this->cb * ina) >> 16) >> 8;
152 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] * ((in[BlendBlit::kGIndex] * this->cg * ina) >> 16) >> 8;
153 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] * ((in[BlendBlit::kRIndex] * this->cr * ina) >> 16) >> 8;
155 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] * ((in[BlendBlit::kBIndex] * ina) >> 8) >> 8;
156 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] * ((in[BlendBlit::kGIndex] * ina) >> 8) >> 8;
157 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] * ((in[BlendBlit::kRIndex] * ina) >> 8) >> 8;
162 inline void fill(byte *out)
const {
163 uint32 ina = this->ca;
167 out[BlendBlit::kBIndex] = (out[BlendBlit::kBIndex] * this->cb) >> 8;
168 out[BlendBlit::kGIndex] = (out[BlendBlit::kGIndex] * this->cg) >> 8;
169 out[BlendBlit::kRIndex] = (out[BlendBlit::kRIndex] * this->cr) >> 8;
171 }
else if (ina != 0) {
173 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] * ((this->cb * ina) >> 8) >> 8;
174 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] * ((this->cg * ina) >> 8) >> 8;
175 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] * ((this->cr * ina) >> 8) >> 8;
177 out[BlendBlit::kBIndex] = (out[BlendBlit::kBIndex] * ina) >> 8;
178 out[BlendBlit::kGIndex] = (out[BlendBlit::kGIndex] * ina) >> 8;
179 out[BlendBlit::kRIndex] = (out[BlendBlit::kRIndex] * ina) >> 8;
185 template<
bool rgbmod,
bool alphamod>
190 inline void normal(
const byte *in, byte *out)
const {
191 *(uint32 *)out = *(
const uint32 *)in | BlendBlit::kAModMask;
195 template<
bool rgbmod,
bool alphamod>
200 inline void normal(
const byte *in, byte *out)
const {
201 uint32 pix = *(
const uint32 *)in;
202 uint32 a = pix & BlendBlit::kAModMask;
205 *(uint32 *)out = pix | BlendBlit::kAModMask;
210 template<
bool rgbmod,
bool alphamod>
215 inline void normal(
const byte *in, byte *out)
const {
219 ina = in[BlendBlit::kAIndex] * this->ca >> 8;
221 ina = in[BlendBlit::kAIndex];
226 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] + ((in[BlendBlit::kBIndex] * this->cb) >> 8);
227 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] + ((in[BlendBlit::kGIndex] * this->cg) >> 8);
228 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] + ((in[BlendBlit::kRIndex] * this->cr) >> 8);
230 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] + in[BlendBlit::kBIndex];
231 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] + in[BlendBlit::kGIndex];
232 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] + in[BlendBlit::kRIndex];
234 }
else if (ina != 0) {
236 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] + ((in[BlendBlit::kBIndex] * this->cb * ina) >> 16);
237 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] + ((in[BlendBlit::kGIndex] * this->cg * ina) >> 16);
238 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] + ((in[BlendBlit::kRIndex] * this->cr * ina) >> 16);
240 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] + ((in[BlendBlit::kBIndex] * ina) >> 8);
241 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] + ((in[BlendBlit::kGIndex] * ina) >> 8);
242 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] + ((in[BlendBlit::kRIndex] * ina) >> 8);
247 inline void fill(byte *out)
const {
248 uint32 ina = this->ca;
252 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] + this->cb;
253 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] + this->cg;
254 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] + this->cr;
256 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] + 255;
257 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] + 255;
258 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] + 255;
260 }
else if (ina != 0) {
262 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] + ((this->cb * ina) >> 8);
263 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] + ((this->cg * ina) >> 8);
264 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] + ((this->cr * ina) >> 8);
266 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] + ina;
267 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] + ina;
268 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] + ina;
274 template<
bool rgbmod,
bool alphamod>
279 inline void normal(
const byte *in, byte *out)
const {
280 uint32 ina = in[BlendBlit::kAIndex];
281 out[BlendBlit::kAIndex] = 255;
285 out[BlendBlit::kBIndex] = MAX<int32>(out[BlendBlit::kBIndex] - ((in[BlendBlit::kBIndex] * this->cb * (out[BlendBlit::kBIndex])) >> 16), 0);
286 out[BlendBlit::kGIndex] = MAX<int32>(out[BlendBlit::kGIndex] - ((in[BlendBlit::kGIndex] * this->cg * (out[BlendBlit::kGIndex])) >> 16), 0);
287 out[BlendBlit::kRIndex] = MAX<int32>(out[BlendBlit::kRIndex] - ((in[BlendBlit::kRIndex] * this->cr * (out[BlendBlit::kRIndex])) >> 16), 0);
289 out[BlendBlit::kBIndex] = MAX<int32>(out[BlendBlit::kBIndex] - ((in[BlendBlit::kBIndex] * (out[BlendBlit::kBIndex])) >> 8), 0);
290 out[BlendBlit::kGIndex] = MAX<int32>(out[BlendBlit::kGIndex] - ((in[BlendBlit::kGIndex] * (out[BlendBlit::kGIndex])) >> 8), 0);
291 out[BlendBlit::kRIndex] = MAX<int32>(out[BlendBlit::kRIndex] - ((in[BlendBlit::kRIndex] * (out[BlendBlit::kRIndex])) >> 8), 0);
293 }
else if (ina != 0) {
295 out[BlendBlit::kBIndex] = MAX<int32>(out[BlendBlit::kBIndex] - ((in[BlendBlit::kBIndex] * this->cb * (out[BlendBlit::kBIndex]) * ina) >> 24), 0);
296 out[BlendBlit::kGIndex] = MAX<int32>(out[BlendBlit::kGIndex] - ((in[BlendBlit::kGIndex] * this->cg * (out[BlendBlit::kGIndex]) * ina) >> 24), 0);
297 out[BlendBlit::kRIndex] = MAX<int32>(out[BlendBlit::kRIndex] - ((in[BlendBlit::kRIndex] * this->cr * (out[BlendBlit::kRIndex]) * ina) >> 24), 0);
299 out[BlendBlit::kBIndex] = MAX<int32>(out[BlendBlit::kBIndex] - ((in[BlendBlit::kBIndex] * (out[BlendBlit::kBIndex]) * ina) >> 16), 0);
300 out[BlendBlit::kGIndex] = MAX<int32>(out[BlendBlit::kGIndex] - ((in[BlendBlit::kGIndex] * (out[BlendBlit::kGIndex]) * ina) >> 16), 0);
301 out[BlendBlit::kRIndex] = MAX<int32>(out[BlendBlit::kRIndex] - ((in[BlendBlit::kRIndex] * (out[BlendBlit::kRIndex]) * ina) >> 16), 0);
306 inline void fill(byte *out)
const {
307 out[BlendBlit::kAIndex] = 255;
310 out[BlendBlit::kBIndex] = MAX<int32>(out[BlendBlit::kBIndex] - ((this->cb * out[BlendBlit::kBIndex]) >> 8), 0);
311 out[BlendBlit::kGIndex] = MAX<int32>(out[BlendBlit::kGIndex] - ((this->cg * out[BlendBlit::kGIndex]) >> 8), 0);
312 out[BlendBlit::kRIndex] = MAX<int32>(out[BlendBlit::kRIndex] - ((this->cr * out[BlendBlit::kRIndex]) >> 8), 0);
314 out[BlendBlit::kBIndex] = 0;
315 out[BlendBlit::kGIndex] = 0;
316 out[BlendBlit::kRIndex] = 0;
324 void BlendBlit::blitT(Args &args,
const TSpriteBlendMode &blendMode,
const AlphaType &alphaType) {
325 bool rgbmod = ((args.color & kRGBModMask) != kRGBModMask);
326 bool alphamod = ((args.color & kAModMask) != kAModMask);
327 if (args.scaleX == SCALE_THRESHOLD && args.scaleY == SCALE_THRESHOLD) {
328 if (args.color == 0xffffffff && blendMode == BLEND_NORMAL && alphaType == ALPHA_OPAQUE) {
329 T::template blitInnerLoop<T::template OpaqueBlend, false, false, false>(args);
330 }
else if (args.color == 0xffffffff && blendMode == BLEND_NORMAL && alphaType == ALPHA_BINARY) {
331 T::template blitInnerLoop<T::template BinaryBlend, false, false, false>(args);
333 if (blendMode == BLEND_ADDITIVE) {
336 T::template blitInnerLoop<T::template AdditiveBlend, false, true, true>(args);
338 T::template blitInnerLoop<T::template AdditiveBlend, false, true, false>(args);
342 T::template blitInnerLoop<T::template AdditiveBlend, false, false, true>(args);
344 T::template blitInnerLoop<T::template AdditiveBlend, false, false, false>(args);
347 }
else if (blendMode == BLEND_SUBTRACTIVE) {
349 T::template blitInnerLoop<T::template SubtractiveBlend, false, true, false>(args);
351 T::template blitInnerLoop<T::template SubtractiveBlend, false, false, false>(args);
353 }
else if (blendMode == BLEND_MULTIPLY) {
356 T::template blitInnerLoop<T::template MultiplyBlend, false, true, true>(args);
358 T::template blitInnerLoop<T::template MultiplyBlend, false, true, false>(args);
362 T::template blitInnerLoop<T::template MultiplyBlend, false, false, true>(args);
364 T::template blitInnerLoop<T::template MultiplyBlend, false, false, false>(args);
368 assert(blendMode == BLEND_NORMAL);
371 T::template blitInnerLoop<T::template AlphaBlend, false, true, true>(args);
373 T::template blitInnerLoop<T::template AlphaBlend, false, true, false>(args);
377 T::template blitInnerLoop<T::template AlphaBlend, false, false, true>(args);
379 T::template blitInnerLoop<T::template AlphaBlend, false, false, false>(args);
385 if (args.color == 0xffffffff && blendMode == BLEND_NORMAL && alphaType == ALPHA_OPAQUE) {
386 T::template blitInnerLoop<T::template OpaqueBlend, true, false, false>(args);
387 }
else if (args.color == 0xffffffff && blendMode == BLEND_NORMAL && alphaType == ALPHA_BINARY) {
388 T::template blitInnerLoop<T::template BinaryBlend, true, false, false>(args);
390 if (blendMode == BLEND_ADDITIVE) {
393 T::template blitInnerLoop<T::template AdditiveBlend, true, true, true>(args);
395 T::template blitInnerLoop<T::template AdditiveBlend, true, true, false>(args);
399 T::template blitInnerLoop<T::template AdditiveBlend, true, false, true>(args);
401 T::template blitInnerLoop<T::template AdditiveBlend, true, false, false>(args);
404 }
else if (blendMode == BLEND_SUBTRACTIVE) {
406 T::template blitInnerLoop<T::template SubtractiveBlend, true, true, false>(args);
408 T::template blitInnerLoop<T::template SubtractiveBlend, true, false, false>(args);
410 }
else if (blendMode == BLEND_MULTIPLY) {
413 T::template blitInnerLoop<T::template MultiplyBlend, true, true, true>(args);
415 T::template blitInnerLoop<T::template MultiplyBlend, true, true, false>(args);
419 T::template blitInnerLoop<T::template MultiplyBlend, true, false, true>(args);
421 T::template blitInnerLoop<T::template MultiplyBlend, true, false, false>(args);
425 assert(blendMode == BLEND_NORMAL);
428 T::template blitInnerLoop<T::template AlphaBlend, true, true, true>(args);
430 T::template blitInnerLoop<T::template AlphaBlend, true, true, false>(args);
434 T::template blitInnerLoop<T::template AlphaBlend, true, false, true>(args);
436 T::template blitInnerLoop<T::template AlphaBlend, true, false, false>(args);
445 void BlendBlit::fillT(Args &args,
const TSpriteBlendMode &blendMode) {
446 bool rgbmod = ((args.color & kRGBModMask) != kRGBModMask);
447 bool alphamod = ((args.color & kAModMask) != kAModMask);
449 if (blendMode == BLEND_ADDITIVE) {
452 T::template fillInnerLoop<T::template AdditiveBlend, true, true>(args);
454 T::template fillInnerLoop<T::template AdditiveBlend, true, false>(args);
458 T::template fillInnerLoop<T::template AdditiveBlend, false, true>(args);
460 T::template fillInnerLoop<T::template AdditiveBlend, false, false>(args);
463 }
else if (blendMode == BLEND_SUBTRACTIVE) {
465 T::template fillInnerLoop<T::template SubtractiveBlend, true, false>(args);
467 T::template fillInnerLoop<T::template SubtractiveBlend, false, false>(args);
469 }
else if (blendMode == BLEND_MULTIPLY) {
472 T::template fillInnerLoop<T::template MultiplyBlend, true, true>(args);
474 T::template fillInnerLoop<T::template MultiplyBlend, true, false>(args);
478 T::template fillInnerLoop<T::template MultiplyBlend, false, true>(args);
480 T::template fillInnerLoop<T::template MultiplyBlend, false, false>(args);
484 assert(blendMode == BLEND_NORMAL);
487 T::template fillInnerLoop<T::template AlphaBlend, true, true>(args);
489 T::template fillInnerLoop<T::template AlphaBlend, true, false>(args);
493 T::template fillInnerLoop<T::template AlphaBlend, false, true>(args);
495 T::template fillInnerLoop<T::template AlphaBlend, false, false>(args);
Definition: blit-alpha.h:44
Definition: blit-alpha.h:211
Definition: blit-alpha.h:196
Definition: formatinfo.h:28
Definition: blit-alpha.h:275
signed char * fill(signed char *first, signed char *last, Value val)
Definition: algorithm.h:168
Definition: blit-alpha.h:126
Definition: blit-alpha.h:31
Definition: blit-alpha.h:186
Definition: blit-alpha.h:26