37 #include <boost/math/constants/constants.hpp>
66 result.r = (0x00FF0000 & rgb )>> 16;
67 result.g = (0x0000FF00 & rgb) >> 8;
68 result.b = (0x000000FF & rgb);
70 result.unused = SDL_ALPHA_OPAQUE;
72 result.a = SDL_ALPHA_OPAQUE;
81 std::vector<Uint32> temp_rgb;
82 if(
string2rgb(color_string, temp_rgb) && !temp_rgb.empty()) {
92 ,
unsigned char alpha)
105 return SDL_GetKeyFromName(keyname.c_str());
115 return (surf->format->BytesPerPixel == 4 &&
116 surf->format->Rmask == 0xFF0000u &&
117 (surf->format->Amask | 0xFF000000u) == 0xFF000000u);
122 static bool first_time =
true;
123 static SDL_PixelFormat
format;
127 surface surf(SDL_CreateRGBSurface(SDL_SWSURFACE,1,1,32,0xFF0000,0xFF00,0xFF,0xFF000000));
128 format = *surf->format;
129 format.palette =
nullptr;
137 if(surf ==
nullptr) {
138 std::cerr <<
"null neutral surface...\n";
143 if(result !=
nullptr) {
152 if (w < 0 || h < 0) {
153 std::cerr <<
"error : neutral surface with negative dimensions\n";
179 const surface&
surf,
const unsigned w,
const bool optimize)
182 assert(SDL_ALPHA_TRANSPARENT==0);
187 if(static_cast<int>(w) == surf->w) {
197 if(src ==
nullptr || dst ==
nullptr) {
198 std::cerr <<
"Could not create surface to scale onto\n";
207 const Uint32*
const src_pixels = src_lock.
pixels();
208 Uint32* dst_pixels = dst_lock.
pixels();
211 const Uint32 pixel = src_pixels [
y * src->w];
212 for(
unsigned x = 0;
x <
w; ++
x) {
214 *dst_pixels++ = pixel;
224 const surface&
surf,
const unsigned h,
const bool optimize)
227 assert(SDL_ALPHA_TRANSPARENT==0);
232 if(static_cast<int>(h) == surf->h) {
242 if(src ==
nullptr || dst ==
nullptr) {
243 std::cerr <<
"Could not create surface to scale onto\n";
252 const Uint32*
const src_pixels = src_lock.
pixels();
253 Uint32* dst_pixels = dst_lock.
pixels();
258 *dst_pixels++ = src_pixels[
x];
273 const Uint32*
const src_pixels = src_lock.pixels();
274 Uint32*
const dst_pixels = dst_lock.pixels();
283 for( ; y_dst != h_dst; ++y_dst, y_src = y_src_next) {
289 }
while(y_step >= h_dst);
298 for( ; x_dst != w_dst; ++x_dst, x_src = x_src_next) {
304 }
while(x_step >= w_dst);
306 int r_sum = 0, g_sum = 0, b_sum = 0, a_sum = 0;
311 for(
int x = x_src;
x < x_src_next; ++
x) {
312 for(
int y = y_src;
y < y_src_next; ++
y) {
316 const Uint32 pixel = src_pixels[y_src * w_src + x_src];
317 const Uint8
a = pixel >> 24;
320 r_sum += a *
static_cast<Uint8
>(pixel >> 16);
321 g_sum += a *
static_cast<Uint8
>(pixel >> 8);
322 b_sum += a *
static_cast<Uint8
>(pixel);
329 const int adjustment = (a_sum | 1) >> 1;
338 assert(samples == (x_src_next - x_src) * (y_src_next - y_src));
340 a_sum += (samples | 1) >> 1;
345 dst_pixels[y_dst * w_dst + x_dst] =
346 static_cast<Uint8
>(a_sum) << 24
347 | static_cast<Uint8>(r_sum) << 16
348 |
static_cast<Uint8
>(g_sum) << 8
349 | static_cast<Uint8>(b_sum);
359 if(r < drop) r = 0;
else r -= drop;
360 if(g < drop) g = 0;
else g -= drop;
361 if(b < drop) b = 0;
else b -= drop;
363 return SDL_MapRGBA(surf->format, r, g, b, a);
372 std::cerr <<
"Cannot use xbrz scaling with zoom factor > 5." << std::endl;
384 std::cerr <<
"Create an empty image\n";
390 if(src ==
nullptr || dst ==
nullptr) {
391 std::cerr <<
"Could not create surface to scale onto\n";
407 assert(SDL_ALPHA_TRANSPARENT==0);
412 if(w == surf->w && h == surf->h) {
420 if (w == 0 || h ==0) {
421 std::cerr <<
"Create an empty image\n";
428 if(src ==
nullptr || dst ==
nullptr) {
429 std::cerr <<
"Could not create surface to scale onto\n";
450 assert(SDL_ALPHA_TRANSPARENT==0);
455 if(w == surf->w && h == surf->h) {
463 if (w == 0 || h ==0) {
464 std::cerr <<
"Create an empty image\n";
471 if(src ==
nullptr || dst ==
nullptr) {
472 std::cerr <<
"Could not create surface to scale onto\n";
480 const Uint32*
const src_pixels = src_lock.
pixels();
481 Uint32*
const dst_pixels = dst_lock.
pixels();
487 for(
int ydst = 0; ydst !=
h; ++ydst, ysrc += yratio) {
489 for(
int xdst = 0; xdst !=
w; ++xdst, xsrc += xratio) {
490 const int xsrcint =
fxptoi(xsrc);
491 const int ysrcint =
fxptoi(ysrc);
493 const Uint32*
const src_word = src_pixels + ysrcint*src->w + xsrcint;
494 Uint32*
const dst_word = dst_pixels + ydst*dst->w + xdst;
495 const int dx = (xsrcint + 1 < src->w) ? 1 : 0;
496 const int dy = (ysrcint + 1 < src->h) ? src->w : 0;
499 Uint32 rr,gg,bb,aa, temp;
501 Uint32 pix[4], bilin[4];
524 const fixed_t e = 0x000000FF & xsrc;
525 const fixed_t s = 0x000000FF & ysrc;
530 pix[1] = *(src_word + dx);
531 pix[2] = *(src_word + dy);
532 pix[3] = *(src_word + dx + dy);
540 rr = bb = gg = aa = 0;
541 for (loc=0; loc<4; loc++) {
553 temp = (
a * bilin[loc]);
569 *dst_word = (
a << 24) + (r << 16) + (g << 8) + b;
580 assert(SDL_ALPHA_TRANSPARENT==0);
585 if(w == surf->w && h == surf->h) {
593 if (w == 0 || h ==0) {
594 std::cerr <<
"Create an empty image\n";
601 if(src ==
nullptr || dst ==
nullptr) {
602 std::cerr <<
"Could not create surface to scale onto\n";
607 scale_surface_down(dst, src, w, h);
613 const Uint32*
const src_pixels = src_lock.
pixels();
614 Uint32*
const dst_pixels = dst_lock.
pixels();
620 for(
int ydst = 0; ydst !=
h; ++ydst, ysrc += yratio) {
622 for(
int xdst = 0; xdst !=
w; ++xdst, xsrc += xratio) {
629 for(
tfloat xloc = xsrc; xloc < xsrc+xratio; xloc += 1) {
630 const tfloat xsize = std::min<tfloat>(
floor(xloc + 1)-xloc,xsrc+xratio-xloc);
632 for(
tfloat yloc = ysrc; yloc < ysrc+yratio; yloc += 1) {
633 const int xsrcint = std::max<int>(0,std::min<int>(src->w-1,xsrc.to_int()));
634 const int ysrcint = std::max<int>(0,std::min<int>(src->h-1,ysrc.to_int()));
635 const tfloat ysize = std::min<tfloat>(
floor(yloc+1)-yloc,ysrc+yratio-yloc);
639 SDL_GetRGBA(src_pixels[ysrcint*src->w + xsrcint],src->format,&r,&g,&b,&a);
652 red = red / alpha + 0.5;
653 green = green / alpha + 0.5;
654 blue = blue / alpha + 0.5;
655 alpha = alpha / summation + 0.5;
658 dst_pixels[ydst*dst->w + xdst] = SDL_MapRGBA(
676 if (surf->w == w && surf->h == h) {
683 if (src ==
nullptr || dest ==
nullptr) {
684 std::cerr <<
"failed to make neutral surface\n";
692 const Uint32* srcpixels = srclock.
pixels();
693 Uint32* destpixels = destlock.
pixels();
695 const int&
sw = src->w;
696 const int& sh = src->h;
698 const int xoff = (w -
sw) / 2;
699 const int yoff = (h - sh) / 2;
701 for (
int i = 0;
i<w*
h; ++
i) {
702 int x = ((
i %
w) - xoff);
703 int y = ((
i /
w) - yoff);
705 while ((x += sw) < 0) { }
706 while ((y += sh) < 0) { }
708 const int sx = x %
sw;
709 const int sy = y % sh;
711 destpixels[
i] = srcpixels[sy*sw + sx];
723 if((red == 0 && green == 0 && blue == 0))
728 if(nsurf ==
nullptr) {
729 std::cerr <<
"failed to make neutral surface\n";
735 Uint32* beg = lock.
pixels();
736 Uint32*
end = beg + nsurf->w*surf->h;
739 Uint8
alpha = (*beg) >> 24;
747 r = std::max<int>(0,std::min<int>(255,
int(r)+red));
748 g = std::max<int>(0,std::min<int>(255,
int(g)+
green));
749 b = std::max<int>(0,std::min<int>(255,
int(b)+
blue));
751 *beg = (alpha << 24) + (r << 16) + (g << 8) + b;
767 if(nsurf ==
nullptr) {
768 std::cerr <<
"failed to make neutral surface\n";
774 Uint32* beg = lock.
pixels();
775 Uint32*
end = beg + nsurf->w*surf->h;
778 Uint8
alpha = (*beg) >> 24;
791 const Uint8 avg =
static_cast<Uint8
>((
792 77 *
static_cast<Uint16
>(
r) +
793 150 * static_cast<Uint16>(g) +
794 29 *
static_cast<Uint16
>(
b) ) / 256);
796 *beg = (alpha << 24) | (avg << 16) | (avg << 8) | avg;
812 if(nsurf ==
nullptr) {
813 std::cerr <<
"failed to make neutral surface\n";
819 Uint32* beg = lock.
pixels();
820 Uint32*
end = beg + nsurf->w*surf->h;
823 Uint8
alpha = (*beg) >> 24;
834 result =
static_cast<Uint8
>(0.299 * r + 0.587 * g + 0.114 *
b) > threshold ? 255 : 0;
836 *beg = (alpha << 24) | (result << 16) | (result << 8) | result;
852 if(nsurf ==
nullptr) {
853 std::cerr <<
"failed to make neutral surface\n";
859 Uint32* beg = lock.
pixels();
860 Uint32*
end = beg + nsurf->w*surf->h;
863 Uint8
alpha = (*beg) >> 24;
874 Uint8 outRed = std::min(255, static_cast<int>((r * 0.393) + (g * 0.769) + (b * 0.189)));
875 Uint8 outGreen = std::min(255, static_cast<int>((r * 0.349) + (g * 0.686) + (b * 0.168)));
876 Uint8 outBlue = std::min(255, static_cast<int>((r * 0.272) + (g * 0.534) + (b * 0.131)));
878 *beg = (alpha << 24) | (outRed << 16) | (outGreen << 8) | (outBlue);
894 if(nsurf ==
nullptr) {
895 std::cerr <<
"failed to make neutral surface\n";
901 Uint32* beg = lock.
pixels();
902 Uint32*
end = beg + nsurf->w*surf->h;
905 Uint8
alpha = (*beg) >> 24;
908 Uint8
r,
g,
b, newR, newG, newB;
917 newR = r > thresholdR ? 255 - r :
r;
918 newG = g > thresholdG ? 255 - g :
g;
919 newB = b > thresholdB ? 255 - b :
b;
921 *beg = (alpha << 24) | (newR << 16) | (newG << 8) | (newB);
937 if(nsurf ==
nullptr) {
938 std::cerr <<
"failed to make neutral surface\n";
944 Uint32* beg = lock.
pixels();
945 Uint32*
end = beg + nsurf->w*surf->h;
948 Uint8
alpha = (*beg) >> 24;
950 *beg = (0xff << 24) | (alpha << 16) | (alpha << 8) | alpha;
965 if(nsurf ==
nullptr) {
966 std::cerr <<
"failed to make neutral surface\n";
972 Uint32* beg = lock.
pixels();
973 Uint32*
end = beg + nsurf->w*surf->h;
977 *beg = 0xff000000 | *beg;
995 if(nsurf ==
nullptr) {
996 std::cerr <<
"failed to blur the shadow surface\n";
1002 Uint32* beg = lock.
pixels();
1003 Uint32*
end = beg + nsurf->w*surf->h;
1006 Uint8
alpha = (*beg) >> 24;
1012 *beg = (alpha*4) << 24;
1029 if(nsurf ==
nullptr) {
1030 std::cerr <<
"failed to make neutral surface\n";
1036 Uint32* beg = lock.
pixels();
1037 Uint32*
end = beg + nsurf->w*surf->h;
1040 Uint8
alpha = (*beg) >> 24;
1043 Uint8 red,
green,
blue, newRed, newGreen, newBlue, newAlpha;
1045 green = (*beg) >> 8;
1116 *beg = (newAlpha << 24) | (newRed << 16) | (newGreen << 8) | newBlue;
1130 if(!map_rgb.empty()){
1132 if(nsurf ==
nullptr) {
1133 std::cerr <<
"failed to make neutral surface\n";
1138 Uint32* beg = lock.
pixels();
1139 Uint32*
end = beg + nsurf->w*surf->h;
1142 Uint8
alpha = (*beg) >> 24;
1146 Uint32 oldrgb = (*beg) & 0x00FFFFFF;
1147 std::map<Uint32, Uint32>::const_iterator
i = map_rgb.find(oldrgb);
1148 if(i != map_rgb.end()){
1149 *beg = (alpha << 24) + i->second;
1162 if(surf ==
nullptr) {
1168 if(nsurf ==
nullptr) {
1169 std::cerr <<
"could not make neutral surface...\n";
1175 Uint32* beg = lock.
pixels();
1176 Uint32*
end = beg + nsurf->w*surf->h;
1178 if (amount < 0) amount = 0;
1180 Uint8
alpha = (*beg) >> 24;
1188 r = std::min<unsigned>(unsigned(
fxpmult(r, amount)),255);
1189 g = std::min<unsigned>(unsigned(
fxpmult(g, amount)),255);
1190 b = std::min<unsigned>(unsigned(
fxpmult(b, amount)),255);
1192 *beg = (alpha << 24) + (r << 16) + (g << 8) + b;
1204 if(surf==
nullptr) {
1210 if(nsurf ==
nullptr) {
1211 std::cerr <<
"could not make neutral surface...\n";
1217 Uint32* beg = lock.
pixels();
1218 Uint32*
end = beg + nsurf->w*surf->h;
1220 if (amount < 0) amount = 0;
1222 Uint8
alpha = (*beg) >> 24;
1230 alpha = std::min<unsigned>(unsigned(
fxpmult(alpha,amount)),255);
1231 *beg = (alpha << 24) + (r << 16) + (g << 8) + b;
1243 if(surf==
nullptr) {
1249 if(nsurf ==
nullptr) {
1250 std::cerr <<
"could not make neutral surface...\n";
1256 Uint32* beg = lock.
pixels();
1257 Uint32*
end = beg + nsurf->w*surf->h;
1260 Uint8
alpha = (*beg) >> 24;
1268 alpha = Uint8(std::max<int>(0,std::min<int>(255,
int(alpha) + amount)));
1269 *beg = (alpha << 24) + (r << 16) + (g << 8) + b;
1281 if(surf ==
nullptr) {
1284 if(mask ==
nullptr) {
1291 if(nsurf ==
nullptr || nmask ==
nullptr) {
1292 std::cerr <<
"could not make neutral surface...\n";
1295 if (nsurf->w != nmask->w) {
1300 std::stringstream ss;
1301 ss <<
"Detected an image with bad dimensions: ";
1302 if(!filename.empty()) ss << filename <<
": ";
1303 ss << nsurf->w <<
"x" << nsurf->h <<
"\n";
1304 std::cerr << ss.str();
1305 std::cerr <<
"It will not be masked, please use: "<< nmask->w <<
"x" << nmask->h <<
"\n";
1314 Uint32* beg = lock.
pixels();
1315 Uint32*
end = beg + nsurf->w*surf->h;
1316 const Uint32* mbeg = mlock.
pixels();
1317 const Uint32* mend = mbeg + nmask->w*nmask->h;
1319 while(beg != end && mbeg != mend) {
1320 Uint8
alpha = (*beg) >> 24;
1328 Uint8 malpha = (*mbeg) >> 24;
1329 if (alpha > malpha) {
1335 *beg = (alpha << 24) + (r << 16) + (g << 8) + b;
1343 *empty_result = empty;
1351 if(surf ==
nullptr) {
1354 if(mask ==
nullptr){
1358 if (surf->w != mask->w || surf->h != mask->h ) {
1366 if(nsurf ==
nullptr || nmask ==
nullptr) {
1367 std::cerr <<
"could not make neutral surface...\n";
1375 const Uint32* mbeg = mlock.
pixels();
1376 const Uint32* mend = mbeg + nmask->w*nmask->h;
1377 Uint32* beg = lock.
pixels();
1380 while(mbeg != mend) {
1381 Uint8 malpha = (*mbeg) >> 24;
1383 Uint8
alpha = (*beg) >> 24;
1397 if(surf==
nullptr) {
1406 Uint32* beg = lock.
pixels();
1407 Uint32*
limit = beg + (nsurf->h-
depth) * nsurf->w ;
1408 Uint32*
end = beg + nsurf->w * nsurf->h;
1412 Uint8
alpha = (*beg) >> 24;
1419 int d = (beg-
limit)/nsurf->w;
1420 float a = alpha_base - d * alpha_delta;
1422 alpha = std::min<unsigned>(unsigned(
fxpmult(alpha,
amount)),255);
1423 *beg = (alpha << 24) + (r << 16) + (g << 8) + b;
1460 if(surf ==
nullptr) {
1463 if(lightmap ==
nullptr) {
1469 if(nsurf ==
nullptr) {
1470 std::cerr <<
"could not make neutral surface...\n";
1473 if (nsurf->w != lightmap->w) {
1478 std::cerr <<
"Detected an image with bad dimensions: " << nsurf->w <<
"x" << nsurf->h <<
"\n";
1479 std::cerr <<
"It will not be lighted, please use: "<< lightmap->w <<
"x" << lightmap->h <<
"\n";
1486 Uint32* beg = lock.
pixels();
1487 Uint32*
end = beg + nsurf->w * nsurf->h;
1488 const Uint32* lbeg = llock.
pixels();
1489 const Uint32* lend = lbeg + lightmap->w * lightmap->h;
1491 while(beg != end && lbeg != lend) {
1492 Uint8
alpha = (*beg) >> 24;
1505 int dr = (
static_cast<int>(lr) - 128) * 2;
1506 int dg = (
static_cast<int>(lg) - 128) * 2;
1507 int db = (
static_cast<int>(lb) - 128) * 2;
1509 r = std::max<int>(0,std::min<int>(255, r + dr));
1510 g = std::max<int>(0,std::min<int>(255, g + dg));
1511 b = std::max<int>(0,std::min<int>(255, b + db));
1513 *beg = (alpha << 24) + (r << 16) + (g << 8) + b;
1526 if(surf ==
nullptr) {
1532 if(res ==
nullptr) {
1533 std::cerr <<
"could not make neutral surface...\n";
1545 if(surf ==
nullptr) {
1549 const int max_blur = 256;
1550 if(depth > max_blur) {
1554 Uint32 queue[max_blur];
1555 const Uint32* end_queue = queue + max_blur;
1557 const Uint32 ff = 0xff;
1559 const unsigned pixel_offset = rect.y * surf->w + rect.x;
1562 for(
int y = 0;
y < rect.h; ++
y) {
1563 const Uint32* front = &queue[0];
1564 Uint32* back = &queue[0];
1565 Uint32 red = 0,
green = 0,
blue = 0, avg = 0;
1566 Uint32*
p = lock.
pixels() + pixel_offset +
y * surf->w;
1567 for(
int x = 0;
x <= depth &&
x < rect.w; ++
x, ++
p) {
1568 red += ((*p) >> 16)&0xFF;
1569 green += ((*p) >> 8)&0xFF;
1573 if(back == end_queue) {
1578 p = lock.
pixels() + pixel_offset +
y * surf->w;
1579 for(
int x = 0;
x < rect.w; ++
x, ++
p) {
1581 | (std::min(red/avg,ff) << 16)
1582 | (std::min(
green/avg,ff) << 8)
1583 | std::min(
blue/avg,ff);
1586 red -= ((*front) >> 16)&0xFF;
1587 green -= ((*front) >> 8)&0xFF;
1588 blue -= *front&0xFF;
1591 if(front == end_queue) {
1596 if(
x + depth+1 < rect.w) {
1597 Uint32*
q = p + depth+1;
1598 red += ((*q) >> 16)&0xFF;
1599 green += ((*q) >> 8)&0xFF;
1603 if(back == end_queue) {
1610 for(
int x = 0;
x < rect.w; ++
x) {
1611 const Uint32* front = &queue[0];
1612 Uint32* back = &queue[0];
1613 Uint32 red = 0,
green = 0,
blue = 0, avg = 0;
1614 Uint32*
p = lock.
pixels() + pixel_offset +
x;
1615 for(
int y = 0;
y <= depth &&
y < rect.h; ++
y, p += surf->w) {
1616 red += ((*p) >> 16)&0xFF;
1617 green += ((*p) >> 8)&0xFF;
1621 if(back == end_queue) {
1626 p = lock.
pixels() + pixel_offset +
x;
1627 for(
int y = 0;
y < rect.h; ++
y, p += surf->w) {
1629 | (std::min(red/avg,ff) << 16)
1630 | (std::min(
green/avg,ff) << 8)
1631 | std::min(
blue/avg,ff);
1634 red -= ((*front) >> 16)&0xFF;
1635 green -= ((*front) >> 8)&0xFF;
1636 blue -= *front&0xFF;
1639 if(front == end_queue) {
1644 if(
y + depth+1 < rect.h) {
1645 Uint32*
q = p + (depth+1)*surf->w;
1646 red += ((*q) >> 16)&0xFF;
1647 green += ((*q) >> 8)&0xFF;
1651 if(back == end_queue) {
1661 if(surf ==
nullptr) {
1667 if(res ==
nullptr) {
1668 std::cerr <<
"could not make neutral surface...\n";
1672 const int max_blur = 256;
1673 if(depth > max_blur) {
1677 Uint32 queue[max_blur];
1678 const Uint32* end_queue = queue + max_blur;
1680 const Uint32 ff = 0xff;
1684 for(y = 0; y < res->h; ++
y) {
1685 const Uint32* front = &queue[0];
1686 Uint32* back = &queue[0];
1688 Uint32*
p = lock.
pixels() + y*res->w;
1689 for(x = 0; x <= depth && x < res->w; ++
x, ++
p) {
1690 alpha += ((*p) >> 24)&0xFF;
1691 red += ((*p) >> 16)&0xFF;
1692 green += ((*p) >> 8)&0xFF;
1696 if(back == end_queue) {
1701 p = lock.
pixels() + y*res->w;
1702 for(x = 0; x < res->w; ++
x, ++
p) {
1703 *p = (std::min(alpha/avg,ff) << 24) | (std::min(red/avg,ff) << 16) | (std::min(
green/avg,ff) << 8) | std::min(
blue/avg,ff);
1705 alpha -= ((*front) >> 24)&0xFF;
1706 red -= ((*front) >> 16)&0xFF;
1707 green -= ((*front) >> 8)&0xFF;
1708 blue -= *front&0xFF;
1711 if(front == end_queue) {
1716 if(x + depth+1 < res->w) {
1717 Uint32*
q = p + depth+1;
1718 alpha += ((*q) >> 24)&0xFF;
1719 red += ((*q) >> 16)&0xFF;
1720 green += ((*q) >> 8)&0xFF;
1724 if(back == end_queue) {
1731 for(x = 0; x < res->w; ++
x) {
1732 const Uint32* front = &queue[0];
1733 Uint32* back = &queue[0];
1736 for(y = 0; y <= depth && y < res->h; ++
y, p += res->w) {
1737 alpha += ((*p) >> 24)&0xFF;
1738 red += ((*p) >> 16)&0xFF;
1739 green += ((*p) >> 8)&0xFF;
1743 if(back == end_queue) {
1749 for(y = 0; y < res->h; ++
y, p += res->w) {
1751 *p = (std::min(alpha/avg,ff) << 24) | (std::min(red/avg,ff) << 16) | (std::min(
green/avg,ff) << 8) | std::min(
blue/avg,ff);
1753 alpha -= ((*front) >> 24)&0xFF;
1754 red -= ((*front) >> 16)&0xFF;
1755 green -= ((*front) >> 8)&0xFF;
1756 blue -= *front&0xFF;
1759 if(front == end_queue) {
1764 if(y + depth+1 < res->h) {
1765 Uint32*
q = p + (depth+1)*res->w;
1766 alpha += ((*q) >> 24)&0xFF;
1767 red += ((*q) >> 16)&0xFF;
1768 green += ((*q) >> 8)&0xFF;
1772 if(back == end_queue) {
1789 if(res ==
nullptr) {
1790 std::cerr <<
"Could not create a new surface in cut_surface()\n";
1794 size_t sbpp = surf->format->BytesPerPixel;
1795 size_t spitch = surf->pitch;
1796 size_t rbpp = res->format->BytesPerPixel;
1797 size_t rpitch = res->pitch;
1800 SDL_Rect src_rect =
r;
1801 SDL_Rect dst_rect = { 0, 0, r.w, r.h };
1803 if (src_rect.x < 0) {
1804 if (src_rect.x + src_rect.w <= 0)
1806 dst_rect.x -= src_rect.x;
1807 dst_rect.w += src_rect.x;
1808 src_rect.w += src_rect.x;
1811 if (src_rect.y < 0) {
1812 if (src_rect.y + src_rect.h <= 0)
1814 dst_rect.y -= src_rect.y;
1815 dst_rect.h += src_rect.y;
1816 src_rect.h += src_rect.y;
1820 if(src_rect.x >= surf->w || src_rect.y >= surf->h)
1826 const Uint8* src =
reinterpret_cast<const Uint8 *
>(slock.
pixels());
1827 Uint8* dest =
reinterpret_cast<Uint8 *
>(rlock.
pixels());
1829 for(
int y = 0;
y < src_rect.h && (src_rect.y +
y) < surf->h; ++
y) {
1830 const Uint8* line_src = src + (src_rect.y +
y) * spitch + src_rect.x * sbpp;
1831 Uint8* line_dest = dest + (dst_rect.y +
y) * rpitch + dst_rect.x * rbpp;
1832 size_t size = src_rect.w + src_rect.x <= surf->w ? src_rect.w : surf->w - src_rect.x;
1834 assert(rpitch >= src_rect.w * rbpp);
1835 memcpy(line_dest, line_src, size * rbpp);
1843 ,
const Uint32
color
1844 ,
const bool optimize)
1846 if(surf==
nullptr) {
1852 if(nsurf ==
nullptr) {
1853 std::cerr <<
"could not make neutral surface...\n";
1859 Uint32* beg = lock.
pixels();
1860 Uint32*
end = beg + nsurf->w*surf->h;
1862 Uint16 ratio = amount * 256;
1863 const Uint16 red = ratio *
static_cast<Uint8
>(color >> 16);
1864 const Uint16
green = ratio *
static_cast<Uint8
>(color >> 8);
1865 const Uint16
blue = ratio *
static_cast<Uint8
>(
color);
1866 ratio = 256 - ratio;
1881 const int div = (nsurf->w * surf->h) / 8;
1882 for(
int i = 0;
i < div; ++
i, beg += 8) {
1897 vst4_u8(reinterpret_cast<Uint8*>(beg), rgba);
1901 Uint8
a =
static_cast<Uint8
>(*beg >> 24);
1902 Uint8
r = (ratio *
static_cast<Uint8
>(*beg >> 16) + red) >> 8;
1903 Uint8
g = (ratio *
static_cast<Uint8
>(*beg >> 8) + green) >> 8;
1904 Uint8
b = (ratio *
static_cast<Uint8
>(*beg) +
blue) >> 8;
1906 *beg = (a << 24) | (r << 16) | (g << 8) | b;
1922 int src_w, src_h, dst_w, dst_h;
1923 float min_x, max_x, min_y, max_y, sine, cosine;
1926 const float radians = angle * boost::math::constants::pi<float>() / 180;
1927 cosine =
static_cast<float>(cos(radians));
1928 sine =
static_cast<float>(sin(radians));
1930 src_w = surf->w * zoom;
1931 src_h = surf->h * zoom;
1933 const float point_1x = src_h * -sine;
1934 const float point_1y = src_h * cosine;
1935 const float point_2x = src_w * cosine - src_h * sine;
1936 const float point_2y = src_h * cosine + src_w * sine;
1937 const float point_3x = src_w * cosine;
1938 const float point_3y = src_w * sine;
1942 min_x = std::min(0.0F, std::min(point_1x, std::min(point_2x, point_3x)));
1943 min_y = std::min(0.0F, std::min(point_1y, std::min(point_2y, point_3y)));
1944 max_x = (angle > 90 && angle < 180) ? 0 : std::max(point_1x, std::max(point_2x, point_3x));
1945 max_y = (angle > 180 && angle < 270) ? 0 : std::max(point_1y, std::max(point_2y, point_3y));
1946 dst_w =
static_cast<int>(ceil(std::abs(max_x) - min_x)) / zoom;
1947 dst_h =
static_cast<int>(ceil(std::abs(max_y) - min_y)) / zoom;
1954 const float scale = 1.f / zoom;
1955 const int max_x = dst_w * zoom;
1956 const int max_y = dst_h * zoom;
1960 for (
int y = 0;
y < max_y;
y +=
offset) {
1962 const float source_x = (
x + min_x)*cosine + (
y + min_y)*sine;
1963 const float source_y = (
y + min_y)*cosine - (
x + min_x)*sine;
1965 if (source_x >= 0 && source_x < src_w
1966 && source_y >= 0 && source_y < src_h)
1969 get_pixel(src, src_lock, source_x, source_y));
1977 const int bpp = surf->format->BytesPerPixel;
1979 Uint8*
const dst =
reinterpret_cast<Uint8*
>(surf_lock.
pixels()) + y * surf->pitch + x * bpp;
1985 *
reinterpret_cast<Uint16*
>(
dst) = pixel;
1988 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
1989 dst[0] = (pixel >> 16) & 0xff;
1990 dst[1] = (pixel >> 8) & 0xff;
1991 dst[2] = pixel & 0xff;
1993 dst[0] = pixel & 0xff;
1994 dst[1] = (pixel >> 8) & 0xff;
1995 dst[2] = (pixel >> 16) & 0xff;
1999 *
reinterpret_cast<Uint32*
>(
dst) = pixel;
2008 const int bpp = surf->format->BytesPerPixel;
2010 const Uint8*
const src =
reinterpret_cast<const Uint8*
>(surf_lock.
pixels()) + y * surf->pitch + x * bpp;
2015 return *
reinterpret_cast<const Uint16*
>(
src);
2017 if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
2018 return src[0] << 16 | src[1] << 8 | src[2];
2020 return src[0] | src[1] << 8 | src[2] << 16;
2023 return *
reinterpret_cast<const Uint32*
>(
src);
2031 if ( surf ==
nullptr )
2037 if ( nsurf ==
nullptr ) {
2038 std::cerr <<
"could not make neutral surface...\n";
2048 for (
int y=0;
y != nsurf->h/2; ++
y) {
2049 for(
int x=0;
x != nsurf->w; ++
x) {
2050 const int index1 =
y*nsurf->w +
x;
2051 const int index2 = (nsurf->h-
y)*nsurf->w -
x - 1;
2052 std::swap(pixels[index1],pixels[index2]);
2056 if (
is_odd(nsurf->h) ) {
2058 for (
int x=0;
x != nsurf->w/2; ++
x) {
2059 const int index1 = (nsurf->h/2)*nsurf->w +
x;
2060 const int index2 = (nsurf->h/2)*nsurf->w + (nsurf->w -
x - 1);
2061 std::swap(pixels[index1],pixels[index2]);
2073 if ( surf ==
nullptr )
2080 if ( src ==
nullptr || dst ==
nullptr ) {
2081 std::cerr <<
"could not make neutral surface...\n";
2089 const Uint32*
const src_pixels = src_lock.
pixels();
2090 Uint32*
const dst_pixels = dst_lock.
pixels();
2093 for (
int y = 0;
y != src->h; ++
y ) {
2094 for (
int x = 0;
x != src->w; ++
x ) {
2095 const int src_index =
y*src->w +
x;
2096 const int dst_index = clockwise ?
2097 x*dst->w + (dst->w-1-
y) :
2098 (dst->h-1-
x)*dst->w +
y;
2099 dst_pixels[dst_index] = src_pixels[src_index];
2110 if(surf ==
nullptr) {
2116 if(nsurf ==
nullptr) {
2117 std::cerr <<
"could not make neutral surface...\n";
2125 for(
int y = 0;
y != nsurf->h; ++
y) {
2126 for(
int x = 0;
x != nsurf->w/2; ++
x) {
2127 const int index1 =
y*nsurf->w +
x;
2128 const int index2 = (
y+1)*nsurf->w -
x - 1;
2129 std::swap(pixels[index1],pixels[index2]);
2139 if(surf ==
nullptr) {
2145 if(nsurf ==
nullptr) {
2146 std::cerr <<
"could not make neutral surface...\n";
2154 for(
int x = 0;
x != nsurf->w; ++
x) {
2155 for(
int y = 0;
y != nsurf->h/2; ++
y) {
2156 const int index1 =
y*nsurf->w +
x;
2157 const int index2 = (nsurf->h-
y-1)*surf->w +
x;
2158 std::swap(pixels[index1],pixels[index2]);
2177 surface s = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, surf->format->BitsPerPixel,
2178 surf->format->Rmask, surf->format->Gmask, surf->format->Bmask, surf->format->Amask);
2179 if (surf->format->palette) {
2180 SDL_SetPaletteColors(s->format->palette, surf->format->palette->colors, 0, surf->format->palette->ncolors);
2186 const SDL_Rect* srcrect,
surface& dst,
const SDL_Rect* dstrect)
2197 dst_rect.x = dstrect->x;
2198 dst_rect.w -= dstrect->x;
2200 dst_rect.y = dstrect->y;
2201 dst_rect.h -= dstrect->y;
2206 if(srcrect && srcrect->w && srcrect->h) {
2207 src_rect.x = srcrect->x;
2208 src_rect.y = srcrect->y;
2210 src_rect.w = srcrect->w;
2211 src_rect.h = srcrect->h;
2213 if (src_rect.x < 0) {
2214 if (src_rect.x + src_rect.w <= 0 || src_rect.x + dst_rect.w <= 0 )
2216 dst_rect.x -= src_rect.x;
2217 dst_rect.w += src_rect.x;
2218 src_rect.w += src_rect.x;
2221 if (src_rect.y < 0) {
2222 if (src_rect.y + src_rect.h <= 0 || src_rect.y + dst_rect.h <= 0 )
2224 dst_rect.y -= src_rect.y;
2225 dst_rect.h += src_rect.y;
2226 src_rect.h += src_rect.y;
2229 if (src_rect.x + src_rect.w > src->w) {
2230 if (src_rect.x >= src->w)
2232 src_rect.w = src->w - src_rect.x;
2234 if (src_rect.y + src_rect.h > src->h) {
2235 if (src_rect.y >= src->h)
2237 src_rect.h = src->h - src_rect.y;
2241 assert(dst_rect.x >= 0);
2242 assert(dst_rect.y >= 0);
2245 const unsigned width = std::min(src_rect.w, dst_rect.w);
2246 const unsigned height = std::min(src_rect.h, dst_rect.h);
2253 const Uint32*
const src_pixels = src_lock.
pixels();
2254 Uint32* dst_pixels = dst_lock.
pixels();
2257 for(
unsigned x = 0;
x <
width; ++
x) {
2267 const int src_offset = (
y + src_rect.y) * src->w + (
x + src_rect.x);
2268 assert(src_offset < src->
w * src->h);
2269 const Uint32 src_pixel = src_pixels[src_offset];
2270 const Uint8 src_a = (src_pixel & 0xFF000000) >> 24;
2277 const ptrdiff_t dst_offset = (
y + dst_rect.y) * dst->w + (
x + dst_rect.x);
2278 assert(dst_offset < dst->w * dst->h);
2281 dst_pixels[dst_offset] = src_pixel;
2285 const Uint32 dst_pixel = dst_pixels[dst_offset];
2286 Uint8 dst_a = (dst_pixel & 0xFF000000) >> 24;
2290 dst_pixels[dst_offset] = src_pixel;
2294 const Uint8 src_r = (src_pixel & 0x00FF0000) >> 16;
2295 const Uint8 src_g = (src_pixel & 0x0000FF00) >> 8;
2296 const Uint8 src_b = src_pixel & 0x000000FF;
2298 Uint8 dst_r = (dst_pixel & 0x00FF0000) >> 16;
2299 Uint8 dst_g = (dst_pixel & 0x0000FF00) >> 8;
2300 Uint8 dst_b = dst_pixel & 0x000000FF;
2305 dst_r = (((src_r - dst_r) * src_a) >> 8 ) + dst_r;
2306 dst_g = (((src_g - dst_g) * src_a) >> 8 ) + dst_g;
2307 dst_b = (((src_b - dst_b) * src_a) >> 8 ) + dst_b;
2314 const unsigned tmp_a = 255 - src_a;
2316 const unsigned tmp_r = 1 + (src_r * src_a) + (dst_r * tmp_a);
2317 dst_r = (tmp_r + (tmp_r >> 8)) >> 8;
2319 const unsigned tmp_g = 1 + (src_g * src_a) + (dst_g * tmp_a);
2320 dst_g = (tmp_g + (tmp_g >> 8)) >> 8;
2322 const unsigned tmp_b = 1 + (src_b * src_a) + (dst_b * tmp_a);
2323 dst_b = (tmp_b + (tmp_b >> 8)) >> 8;
2325 dst_a += (((255 - dst_a) * src_a) >> 8);
2328 dst_pixels[dst_offset] = (dst_a << 24) | (dst_r << 16) | (dst_g << 8) | (dst_b);
2337 if (src ==
nullptr) {
2342 if(area.x >= src->w || area.y >= src->h || area.x + area.w < 0 || area.y + area.h < 0) {
2346 if(area.x + area.w > src->w) {
2347 area.w = src->w - area.x;
2349 if(area.y + area.h > src->h) {
2350 area.h = src->h - area.y;
2356 if(dst ==
nullptr) {
2357 std::cerr <<
"Could not create a new surface in get_surface_portion()\n";
2373 bool operator()(Uint32 pixel)
const {
2374 Uint8
alpha = pixel >> 24;
2375 return alpha != 0x00;
2383 SDL_Rect
res = {0,0,0,0};
2385 if(nsurf ==
nullptr) {
2386 std::cerr <<
"failed to make neutral surface\n";
2390 const not_alpha calc;
2396 for(n = 0; n != nsurf->h; ++
n) {
2397 const Uint32*
const start_row = pixels + n*nsurf->w;
2398 const Uint32*
const end_row = start_row + nsurf->w;
2400 if(std::find_if(start_row,end_row,calc) != end_row)
2406 for(n = 0; n != nsurf->h-res.y; ++
n) {
2407 const Uint32*
const start_row = pixels + (nsurf->h-n-1)*surf->w;
2408 const Uint32*
const end_row = start_row + nsurf->w;
2410 if(std::find_if(start_row,end_row,calc) != end_row)
2417 res.h = nsurf->h - res.y -
n;
2419 for(n = 0; n != nsurf->w; ++
n) {
2421 for(y = 0; y != nsurf->h; ++
y) {
2422 const Uint32 pixel = pixels[y*nsurf->w +
n];
2433 for(n = 0; n != nsurf->w-res.x; ++
n) {
2435 for(y = 0; y != nsurf->h; ++
y) {
2436 const Uint32 pixel = pixels[y*nsurf->w + surf->w - n - 1];
2445 res.w = nsurf->w - res.x -
n;
2451 return a.r == b.r && a.g == b.g && a.b == b.b;
2460 inverse.r = 255 - color.r;
2461 inverse.g = 255 - color.g;
2462 inverse.b = 255 - color.b;
2472 : target_(target), rect_(rect), surface_(nullptr)
2487 if (dst2.w == 0 || dst2.h == 0)
2489 SDL_Rect src = dst2;
2500 SDL_Rect dst =
rect_;
2522 Uint32 col = SDL_MapRGBA(target->format, color.r, color.g, color.b, color.a);
2527 if (surf !=
nullptr) {
2528 r.x = rect.x + (rect.w-surf->w)/2;
2529 r.y = rect.y + (rect.h-surf->h)/2;
2530 sdl_blit(surf,
nullptr, target, &r);
2537 s << rect.x <<
',' << rect.y <<
" x " << rect.w <<
',' << rect.h;
uint8x8_t vshrn_n_u16(uint16x8_t m, const unsigned imm)
surface rotate_any_surface(const surface &surf, float angle, int zoom, int offset, bool optimize)
Rotates a surface by any degrees.
SDL_Rect intersect_rects(SDL_Rect const &rect1, SDL_Rect const &rect2)
Calculates the intersection of two rectangles.
surface flip_surface(const surface &surf, bool optimize)
surface rotate_180_surface(const surface &surf, bool optimize)
Rotates a surface 180 degrees.
surface create_neutral_surface(int w, int h)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
SDL_Surface * get() const
GLint GLint GLsizei GLsizei GLsizei depth
void fill_rect(surface &dst, SDL_Rect *dst_rect, const Uint32 color)
Fill a rectangle on a given surface.
GLenum GLenum GLenum GLenum GLenum scale
SDL_Color create_color(const unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
surface adjust_surface_alpha_add(const surface &surf, int amount, bool optimize)
void put_pixel(const surface &surf, surface_lock &surf_lock, int x, int y, Uint32 pixel)
Helper methods for setting/getting a single pixel in an image.
surface stretch_surface_vertical(const surface &surf, const unsigned h, const bool optimize)
Stretches a surface in the vertical direction.
Helper class for ARM NEON support.
SDL_Color int_to_color(const Uint32 rgb)
surface create_optimized_surface(const surface &surf)
#define fxpdiv(x, y)
IN: unsigned and int - OUT: fixed_t.
const SDL_Rect empty_rect
const Uint32 * pixels() const
bool string2rgb(const std::string &s, std::vector< Uint32 > &result)
surface recolor_image(surface surf, const std::map< Uint32, Uint32 > &map_rgb, bool optimize)
Recolors a surface using a map with source and converted palette values.
surface rotate_90_surface(const surface &surf, bool clockwise, bool optimize)
Rotates a surface 90 degrees.
bool in_mask_surface(const surface &surf, const surface &mask)
Check if a surface fit into a mask.
surface negative_image(const surface &surf, const int thresholdR, const int thresholdG, const int thresholdB, bool optimize)
GLint GLint GLint GLint GLint GLint y
surface scale_surface(const surface &surf, int w, int h)
surface get_surface_portion(const surface &src, SDL_Rect &area)
Get a portion of the screen.
uint16x8_t vdupq_n_u16(uint16_t imm)
const_surface_lock(const surface &surf)
SDL_Rect get_non_transparent_portion(const surface &surf)
void blit_surface(const surface &surf, const SDL_Rect *srcrect, surface &dst, const SDL_Rect *dstrect)
Replacement for sdl_blit.
GLdouble GLdouble GLdouble b
surface shadow_image(const surface &surf, bool optimize)
create an heavy shadow of the image, by blurring, increasing alpha and darkening
#define fxptoi(x)
IN: fixed_t - OUT: int.
GLdouble GLdouble GLdouble GLdouble q
surface mask_surface(const surface &surf, const surface &mask, bool *empty_result, const std::string &filename)
Applies a mask on a surface.
#define fxpmult(x, y)
IN: unsigned and fixed_t - OUT: unsigned.
surface wipe_alpha(const surface &surf, bool optimize)
int floor(tfloat< T, S > lhs)
Contains code for a floating point emulation.
void scale(size_t factor, const uint32_t *src, uint32_t *trg, int srcWidth, int srcHeight, const ScalerCfg &cfg=ScalerCfg(), int yFirst=0, int yLast=std::numeric_limits< int >::max())
uint8x8_t vdup_n_u8(uint8_t imm)
void draw_centered_on_background(surface surf, const SDL_Rect &rect, const SDL_Color &color, surface target)
SDL_Color string_to_color(const std::string &color_string)
Return the color the string represents.
GLubyte GLubyte GLubyte GLubyte w
surface swap_channels_image(const surface &surf, channel r, channel g, channel b, channel a, bool optimize)
GLsizei const GLfloat * value
surface adjust_surface_alpha(const surface &surf, fixed_t amount, bool optimize)
uint8x8x4_t vld4_u8(uint8_t *base)
GLboolean GLboolean GLboolean GLboolean a
surface blend_surface(const surface &surf, const double amount, const Uint32 color, const bool optimize)
Blends a surface with a color.
GLclampf GLclampf GLclampf alpha
surface light_surface(const surface &surf, const surface &lightmap, bool optimize)
Light surf using lightmap.
Helper class for pinning SDL surfaces into memory.
surface sepia_image(const surface &surf, bool optimize)
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
surface blur_surface(const surface &surf, int depth, bool optimize)
Cross-fades a surface.
surface scale_surface_nn(const surface &surf, int w, int h)
Scale a surface using the nearest neighbor algorithm (provided by xBRZ lib)
surface flop_surface(const surface &surf, bool optimize)
std::ostream & operator<<(std::ostream &s, const SDL_Rect &rect)
const std::string ¶meters float amount
surface submerge_alpha(const surface &surf, int depth, float alpha_base, float alpha_delta, bool optimize)
Progressively reduce alpha of bottom part of the surface.
SDLKey sdl_keysym_from_name(std::string const &keyname)
surface adjust_surface_color(const surface &surf, int red, int green, int blue, bool optimize)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
void vst4_u8(uint8_t *base, uint8x8x4_t list)
Template class for the emulation.
SDL_Color inverse(const SDL_Color &color)
surface scale_surface_xbrz(const surface &surf, size_t z)
Scale a surface using xBRZ algorithm.
bool operator==(const SDL_Color &a, const SDL_Color &b)
GLfloat GLfloat GLfloat GLfloat h
surface brighten_image(const surface &surf, fixed_t amount, bool optimize)
GLint GLint GLint GLint GLint x
GLdouble GLdouble GLdouble r
static SDL_PixelFormat & get_neutral_pixel_format()
bool is_neutral(const surface &surf)
Check that the surface is neutral bpp 32.
static map_location::DIRECTION sw
floating_point_emulation::tfloat< double, 0 > tfloat
surface blur_alpha_surface(const surface &surf, int depth, bool optimize)
Cross-fades a surface with alpha channel.
GLint GLint GLint GLint GLint GLint GLsizei GLsizei height
SDL_Rect create_rect(const int x, const int y, const int w, const int h)
Creates an empty SDL_Rect.
bool operator<(const surface &a, const surface &b)
Contains the SDL_Rect helper code.
surface tile_surface(const surface &surf, int w, int h, bool optimize)
Tile a surface.
void swap(game_board &one, game_board &other)
surface make_neutral_surface(const surface &surf)
void assign(const surface &o)
surface create_compatible_surface(const surface &surf, int width, int height)
surface alpha_to_greyscale(const surface &surf, bool optimize)
surface greyscale_image(const surface &surf, bool optimize)
bool operator!=(const SDL_Color &a, const SDL_Color &b)
GLint GLint GLint GLint GLint GLint GLsizei width
surface_lock(surface &surf)
uint16x8_t vaddq_u16(uint16x8_t n, uint16x8_t m)
void sdl_copy_portion(const surface &screen, SDL_Rect *screen_rect, surface &dst, SDL_Rect *dst_rect)
void sdl_blit(const surface &src, SDL_Rect *src_rect, surface &dst, SDL_Rect *dst_rect)
int SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha)
Compatibility layer for using SDL 1.2 and 2.0.
surface scale_surface_sharp(const surface &surf, int w, int h, bool optimize)
Scale a surface using modified nearest neighbour algorithm.
void update_rect(const SDL_Rect &)
surface stretch_surface_horizontal(const surface &surf, const unsigned w, const bool optimize)
Stretches a surface in the horizontal direction.
void nearestNeighborScale(const uint32_t *src, int srcWidth, int srcHeight, uint32_t *trg, int trgWidth, int trgHeight)
GLsizei const GLcharARB ** string
Uint32 blend_rgba(const surface &surf, unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned char drop)
This method blends a RGBA color.
surface cut_surface(const surface &surf, SDL_Rect const &r)
Cuts a rectangle from a surface.
uint16x8_t vmull_u8(uint8x8_t n, uint8x8_t m)
Uint32 get_pixel(const surface &surf, const const_surface_lock &surf_lock, int x, int y)
#define ftofxp(x)
IN: float or int - OUT: fixed_t.
surface monochrome_image(const surface &surf, const int threshold, bool optimize)