]> git.localhorst.tv Git - l2e.git/blobdiff - src/sdl/Desaturate.cpp
added basic defeat state
[l2e.git] / src / sdl / Desaturate.cpp
diff --git a/src/sdl/Desaturate.cpp b/src/sdl/Desaturate.cpp
new file mode 100644 (file)
index 0000000..175e1b9
--- /dev/null
@@ -0,0 +1,127 @@
+#include "Desaturate.h"
+
+#include <stdexcept>
+
+using std::runtime_error;
+
+
+namespace sdl {
+
+template<typename SrcType, typename DestType>
+void DesaturatePixel(
+               SrcType *src, SDL_PixelFormat *srcFmt,
+               DestType *dest, SDL_PixelFormat *destFmt,
+               Uint8 amount) {
+
+       Uint8 srcRed = (((*src) & srcFmt->Rmask)
+                       >> srcFmt->Rshift) << srcFmt->Rloss;
+       Uint8 srcGreen = (((*src) & srcFmt->Gmask)
+                       >> srcFmt->Gshift) << srcFmt->Gloss;
+       Uint8 srcBlue = (((*src) & srcFmt->Bmask)
+                       >> srcFmt->Bshift) << srcFmt->Bloss;
+
+       Uint8 srcGrey = (srcRed * 76 + srcGreen * 150 + srcBlue * 29) / 255;
+
+       Uint8 destRed = (srcRed * amount + srcGrey * (255 - amount)) / 255;
+       Uint8 destGreen = (srcGreen * amount + srcGrey * (255 - amount)) / 255;
+       Uint8 destBlue = (srcBlue * amount + srcGrey * (255 - amount)) / 255;
+
+       *dest
+               = ((destRed >> destFmt->Rloss) << destFmt->Rshift)
+               | ((destGreen >> destFmt->Gloss) << destFmt->Gshift)
+               | ((destBlue >> destFmt->Bloss) << destFmt->Bshift)
+               | (*dest & destFmt->Amask);
+}
+
+void Desaturate(
+               SDL_Surface *src,
+               SDL_Surface *dest,
+               Uint8 amount) {
+       Uint32 size = src->w * src->h;
+       SDL_LockSurface(src);
+       SDL_LockSurface(dest);
+       SDL_PixelFormat *srcFmt = src->format;
+       SDL_PixelFormat *destFmt = dest->format;
+       Uint8 srcBPP = srcFmt->BytesPerPixel;
+       Uint8 destBPP = destFmt->BytesPerPixel;
+       switch (srcBPP) {
+       default:
+               SDL_UnlockSurface(dest);
+               SDL_UnlockSurface(src);
+               throw runtime_error("unable to read src format");
+       case 2: {
+               Uint16 *srcIter = reinterpret_cast<Uint16 *>(
+                               src->pixels);
+               Uint16 *srcEnd = srcIter + size;
+               switch (destBPP) {
+               default:
+                       SDL_UnlockSurface(dest);
+                       SDL_UnlockSurface(src);
+                       throw runtime_error("unable to read src format");
+               case 2: {
+                       Uint16 *destIter = reinterpret_cast<Uint16 *>(
+                                       dest->pixels);
+                       Uint16 *destEnd = destIter + size;
+                       for (;srcIter < srcEnd && destIter < destEnd;
+                                       ++srcIter, ++destIter) {
+                               DesaturatePixel(
+                                               srcIter, srcFmt,
+                                               destIter, destFmt,
+                                               amount);
+                       }
+                       break; }
+               case 4: {
+                       Uint32 *destIter = reinterpret_cast<Uint32 *>(
+                                       dest->pixels);
+                       Uint32 *destEnd = destIter + size;
+                       for (;srcIter < srcEnd && destIter < destEnd;
+                                       ++srcIter, ++destIter) {
+                               DesaturatePixel(
+                                               srcIter, srcFmt,
+                                               destIter, destFmt,
+                                               amount);
+                       }
+                       break; }
+               }
+               break; }
+       case 4: {
+               Uint32 *srcIter = reinterpret_cast<Uint32 *>(
+                               src->pixels);
+               Uint32 *srcEnd = srcIter + size;
+               switch (destBPP) {
+               default:
+                       SDL_UnlockSurface(dest);
+                       SDL_UnlockSurface(src);
+                       throw runtime_error("unable to read src format");
+               case 2: {
+                       Uint16 *destIter = reinterpret_cast<Uint16 *>(
+                                       dest->pixels);
+                       Uint16 *destEnd = destIter + size;
+                       for (;srcIter < srcEnd && destIter < destEnd;
+                                       ++srcIter, ++destIter) {
+                               DesaturatePixel(
+                                               srcIter, srcFmt,
+                                               destIter, destFmt,
+                                               amount);
+                       }
+                       break; }
+               case 4: {
+                       Uint32 *destIter = reinterpret_cast<Uint32 *>(
+                                       dest->pixels);
+                       Uint32 *destEnd = destIter + size;
+                       for (;srcIter < srcEnd && destIter < destEnd;
+                                       ++srcIter, ++destIter) {
+                               DesaturatePixel(
+                                               srcIter, srcFmt,
+                                               destIter, destFmt,
+                                               amount);
+                       }
+                       break; }
+               }
+               break; }
+       }
+       SDL_UnlockSurface(dest);
+       SDL_UnlockSurface(src);
+}
+
+}