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;
90 template<
bool rgbmod,
bool alphamod>
95 inline void normal(
const byte *in, byte *out)
const {
99 ina = in[BlendBlit::kAIndex] * this->ca >> 8;
101 ina = in[BlendBlit::kAIndex];
106 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] * ((in[BlendBlit::kBIndex] * this->cb) >> 8) >> 8;
107 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] * ((in[BlendBlit::kGIndex] * this->cg) >> 8) >> 8;
108 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] * ((in[BlendBlit::kRIndex] * this->cr) >> 8) >> 8;
110 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] * in[BlendBlit::kBIndex] >> 8;
111 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] * in[BlendBlit::kGIndex] >> 8;
112 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] * in[BlendBlit::kRIndex] >> 8;
114 }
else if (ina != 0) {
116 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] * ((in[BlendBlit::kBIndex] * this->cb * ina) >> 16) >> 8;
117 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] * ((in[BlendBlit::kGIndex] * this->cg * ina) >> 16) >> 8;
118 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] * ((in[BlendBlit::kRIndex] * this->cr * ina) >> 16) >> 8;
120 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] * ((in[BlendBlit::kBIndex] * ina) >> 8) >> 8;
121 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] * ((in[BlendBlit::kGIndex] * ina) >> 8) >> 8;
122 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] * ((in[BlendBlit::kRIndex] * ina) >> 8) >> 8;
128 template<
bool rgbmod,
bool alphamod>
133 inline void normal(
const byte *in, byte *out)
const {
134 *(uint32 *)out = *(
const uint32 *)in | BlendBlit::kAModMask;
138 template<
bool rgbmod,
bool alphamod>
143 inline void normal(
const byte *in, byte *out)
const {
144 uint32 pix = *(
const uint32 *)in;
145 uint32 a = pix & BlendBlit::kAModMask;
148 *(uint32 *)out = pix | BlendBlit::kAModMask;
153 template<
bool rgbmod,
bool alphamod>
158 inline void normal(
const byte *in, byte *out)
const {
162 ina = in[BlendBlit::kAIndex] * this->ca >> 8;
164 ina = in[BlendBlit::kAIndex];
169 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] + ((in[BlendBlit::kBIndex] * this->cb) >> 8);
170 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] + ((in[BlendBlit::kGIndex] * this->cg) >> 8);
171 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] + ((in[BlendBlit::kRIndex] * this->cr) >> 8);
173 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] + in[BlendBlit::kBIndex];
174 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] + in[BlendBlit::kGIndex];
175 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] + in[BlendBlit::kRIndex];
177 }
else if (ina != 0) {
179 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] + ((in[BlendBlit::kBIndex] * this->cb * ina) >> 16);
180 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] + ((in[BlendBlit::kGIndex] * this->cg * ina) >> 16);
181 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] + ((in[BlendBlit::kRIndex] * this->cr * ina) >> 16);
183 out[BlendBlit::kBIndex] = out[BlendBlit::kBIndex] + ((in[BlendBlit::kBIndex] * ina) >> 8);
184 out[BlendBlit::kGIndex] = out[BlendBlit::kGIndex] + ((in[BlendBlit::kGIndex] * ina) >> 8);
185 out[BlendBlit::kRIndex] = out[BlendBlit::kRIndex] + ((in[BlendBlit::kRIndex] * ina) >> 8);
191 template<
bool rgbmod,
bool alphamod>
196 inline void normal(
const byte *in, byte *out)
const {
197 uint32 ina = in[BlendBlit::kAIndex];
198 out[BlendBlit::kAIndex] = 255;
202 out[BlendBlit::kBIndex] = MAX<int32>(out[BlendBlit::kBIndex] - ((in[BlendBlit::kBIndex] * this->cb * (out[BlendBlit::kBIndex])) >> 16), 0);
203 out[BlendBlit::kGIndex] = MAX<int32>(out[BlendBlit::kGIndex] - ((in[BlendBlit::kGIndex] * this->cg * (out[BlendBlit::kGIndex])) >> 16), 0);
204 out[BlendBlit::kRIndex] = MAX<int32>(out[BlendBlit::kRIndex] - ((in[BlendBlit::kRIndex] * this->cr * (out[BlendBlit::kRIndex])) >> 16), 0);
206 out[BlendBlit::kBIndex] = MAX<int32>(out[BlendBlit::kBIndex] - ((in[BlendBlit::kBIndex] * (out[BlendBlit::kBIndex])) >> 8), 0);
207 out[BlendBlit::kGIndex] = MAX<int32>(out[BlendBlit::kGIndex] - ((in[BlendBlit::kGIndex] * (out[BlendBlit::kGIndex])) >> 8), 0);
208 out[BlendBlit::kRIndex] = MAX<int32>(out[BlendBlit::kRIndex] - ((in[BlendBlit::kRIndex] * (out[BlendBlit::kRIndex])) >> 8), 0);
210 }
else if (ina != 0) {
212 out[BlendBlit::kBIndex] = MAX<int32>(out[BlendBlit::kBIndex] - ((in[BlendBlit::kBIndex] * this->cb * (out[BlendBlit::kBIndex]) * ina) >> 24), 0);
213 out[BlendBlit::kGIndex] = MAX<int32>(out[BlendBlit::kGIndex] - ((in[BlendBlit::kGIndex] * this->cg * (out[BlendBlit::kGIndex]) * ina) >> 24), 0);
214 out[BlendBlit::kRIndex] = MAX<int32>(out[BlendBlit::kRIndex] - ((in[BlendBlit::kRIndex] * this->cr * (out[BlendBlit::kRIndex]) * ina) >> 24), 0);
216 out[BlendBlit::kBIndex] = MAX<int32>(out[BlendBlit::kBIndex] - ((in[BlendBlit::kBIndex] * (out[BlendBlit::kBIndex]) * ina) >> 16), 0);
217 out[BlendBlit::kGIndex] = MAX<int32>(out[BlendBlit::kGIndex] - ((in[BlendBlit::kGIndex] * (out[BlendBlit::kGIndex]) * ina) >> 16), 0);
218 out[BlendBlit::kRIndex] = MAX<int32>(out[BlendBlit::kRIndex] - ((in[BlendBlit::kRIndex] * (out[BlendBlit::kRIndex]) * ina) >> 16), 0);
227 void BlendBlit::blitT(Args &args,
const TSpriteBlendMode &blendMode,
const AlphaType &alphaType) {
228 bool rgbmod = ((args.color & kRGBModMask) != kRGBModMask);
229 bool alphamod = ((args.color & kAModMask) != kAModMask);
230 if (args.scaleX == SCALE_THRESHOLD && args.scaleY == SCALE_THRESHOLD) {
231 if (args.color == 0xffffffff && blendMode == BLEND_NORMAL && alphaType == ALPHA_OPAQUE) {
232 T::template blitInnerLoop<T::template OpaqueBlend, false, false, false>(args);
233 }
else if (args.color == 0xffffffff && blendMode == BLEND_NORMAL && alphaType == ALPHA_BINARY) {
234 T::template blitInnerLoop<T::template BinaryBlend, false, false, false>(args);
236 if (blendMode == BLEND_ADDITIVE) {
239 T::template blitInnerLoop<T::template AdditiveBlend, false, true, true>(args);
241 T::template blitInnerLoop<T::template AdditiveBlend, false, true, false>(args);
245 T::template blitInnerLoop<T::template AdditiveBlend, false, false, true>(args);
247 T::template blitInnerLoop<T::template AdditiveBlend, false, false, false>(args);
250 }
else if (blendMode == BLEND_SUBTRACTIVE) {
252 T::template blitInnerLoop<T::template SubtractiveBlend, false, true, false>(args);
254 T::template blitInnerLoop<T::template SubtractiveBlend, false, false, false>(args);
256 }
else if (blendMode == BLEND_MULTIPLY) {
259 T::template blitInnerLoop<T::template MultiplyBlend, false, true, true>(args);
261 T::template blitInnerLoop<T::template MultiplyBlend, false, true, false>(args);
265 T::template blitInnerLoop<T::template MultiplyBlend, false, false, true>(args);
267 T::template blitInnerLoop<T::template MultiplyBlend, false, false, false>(args);
271 assert(blendMode == BLEND_NORMAL);
274 T::template blitInnerLoop<T::template AlphaBlend, false, true, true>(args);
276 T::template blitInnerLoop<T::template AlphaBlend, false, true, false>(args);
280 T::template blitInnerLoop<T::template AlphaBlend, false, false, true>(args);
282 T::template blitInnerLoop<T::template AlphaBlend, false, false, false>(args);
288 if (args.color == 0xffffffff && blendMode == BLEND_NORMAL && alphaType == ALPHA_OPAQUE) {
289 T::template blitInnerLoop<T::template OpaqueBlend, true, false, false>(args);
290 }
else if (args.color == 0xffffffff && blendMode == BLEND_NORMAL && alphaType == ALPHA_BINARY) {
291 T::template blitInnerLoop<T::template BinaryBlend, true, false, false>(args);
293 if (blendMode == BLEND_ADDITIVE) {
296 T::template blitInnerLoop<T::template AdditiveBlend, true, true, true>(args);
298 T::template blitInnerLoop<T::template AdditiveBlend, true, true, false>(args);
302 T::template blitInnerLoop<T::template AdditiveBlend, true, false, true>(args);
304 T::template blitInnerLoop<T::template AdditiveBlend, true, false, false>(args);
307 }
else if (blendMode == BLEND_SUBTRACTIVE) {
309 T::template blitInnerLoop<T::template SubtractiveBlend, true, true, false>(args);
311 T::template blitInnerLoop<T::template SubtractiveBlend, true, false, false>(args);
313 }
else if (blendMode == BLEND_MULTIPLY) {
316 T::template blitInnerLoop<T::template MultiplyBlend, true, true, true>(args);
318 T::template blitInnerLoop<T::template MultiplyBlend, true, true, false>(args);
322 T::template blitInnerLoop<T::template MultiplyBlend, true, false, true>(args);
324 T::template blitInnerLoop<T::template MultiplyBlend, true, false, false>(args);
328 assert(blendMode == BLEND_NORMAL);
331 T::template blitInnerLoop<T::template AlphaBlend, true, true, true>(args);
333 T::template blitInnerLoop<T::template AlphaBlend, true, true, false>(args);
337 T::template blitInnerLoop<T::template AlphaBlend, true, false, true>(args);
339 T::template blitInnerLoop<T::template AlphaBlend, true, false, false>(args);
Definition: blit-alpha.h:44
Definition: blit-alpha.h:154
Definition: blit-alpha.h:139
Definition: formatinfo.h:28
Definition: blit-alpha.h:192
Definition: blit-alpha.h:91
Definition: blit-alpha.h:31
Definition: blit-alpha.h:129
Definition: blit-alpha.h:26