]> git.localhorst.tv Git - l2e.git/blob - src/sdl/Desaturate.cpp
added basic defeat state
[l2e.git] / src / sdl / Desaturate.cpp
1 #include "Desaturate.h"
2
3 #include <stdexcept>
4
5 using std::runtime_error;
6
7
8 namespace sdl {
9
10 template<typename SrcType, typename DestType>
11 void DesaturatePixel(
12                 SrcType *src, SDL_PixelFormat *srcFmt,
13                 DestType *dest, SDL_PixelFormat *destFmt,
14                 Uint8 amount) {
15
16         Uint8 srcRed = (((*src) & srcFmt->Rmask)
17                         >> srcFmt->Rshift) << srcFmt->Rloss;
18         Uint8 srcGreen = (((*src) & srcFmt->Gmask)
19                         >> srcFmt->Gshift) << srcFmt->Gloss;
20         Uint8 srcBlue = (((*src) & srcFmt->Bmask)
21                         >> srcFmt->Bshift) << srcFmt->Bloss;
22
23         Uint8 srcGrey = (srcRed * 76 + srcGreen * 150 + srcBlue * 29) / 255;
24
25         Uint8 destRed = (srcRed * amount + srcGrey * (255 - amount)) / 255;
26         Uint8 destGreen = (srcGreen * amount + srcGrey * (255 - amount)) / 255;
27         Uint8 destBlue = (srcBlue * amount + srcGrey * (255 - amount)) / 255;
28
29         *dest
30                 = ((destRed >> destFmt->Rloss) << destFmt->Rshift)
31                 | ((destGreen >> destFmt->Gloss) << destFmt->Gshift)
32                 | ((destBlue >> destFmt->Bloss) << destFmt->Bshift)
33                 | (*dest & destFmt->Amask);
34 }
35
36 void Desaturate(
37                 SDL_Surface *src,
38                 SDL_Surface *dest,
39                 Uint8 amount) {
40         Uint32 size = src->w * src->h;
41         SDL_LockSurface(src);
42         SDL_LockSurface(dest);
43         SDL_PixelFormat *srcFmt = src->format;
44         SDL_PixelFormat *destFmt = dest->format;
45         Uint8 srcBPP = srcFmt->BytesPerPixel;
46         Uint8 destBPP = destFmt->BytesPerPixel;
47         switch (srcBPP) {
48         default:
49                 SDL_UnlockSurface(dest);
50                 SDL_UnlockSurface(src);
51                 throw runtime_error("unable to read src format");
52         case 2: {
53                 Uint16 *srcIter = reinterpret_cast<Uint16 *>(
54                                 src->pixels);
55                 Uint16 *srcEnd = srcIter + size;
56                 switch (destBPP) {
57                 default:
58                         SDL_UnlockSurface(dest);
59                         SDL_UnlockSurface(src);
60                         throw runtime_error("unable to read src format");
61                 case 2: {
62                         Uint16 *destIter = reinterpret_cast<Uint16 *>(
63                                         dest->pixels);
64                         Uint16 *destEnd = destIter + size;
65                         for (;srcIter < srcEnd && destIter < destEnd;
66                                         ++srcIter, ++destIter) {
67                                 DesaturatePixel(
68                                                 srcIter, srcFmt,
69                                                 destIter, destFmt,
70                                                 amount);
71                         }
72                         break; }
73                 case 4: {
74                         Uint32 *destIter = reinterpret_cast<Uint32 *>(
75                                         dest->pixels);
76                         Uint32 *destEnd = destIter + size;
77                         for (;srcIter < srcEnd && destIter < destEnd;
78                                         ++srcIter, ++destIter) {
79                                 DesaturatePixel(
80                                                 srcIter, srcFmt,
81                                                 destIter, destFmt,
82                                                 amount);
83                         }
84                         break; }
85                 }
86                 break; }
87         case 4: {
88                 Uint32 *srcIter = reinterpret_cast<Uint32 *>(
89                                 src->pixels);
90                 Uint32 *srcEnd = srcIter + size;
91                 switch (destBPP) {
92                 default:
93                         SDL_UnlockSurface(dest);
94                         SDL_UnlockSurface(src);
95                         throw runtime_error("unable to read src format");
96                 case 2: {
97                         Uint16 *destIter = reinterpret_cast<Uint16 *>(
98                                         dest->pixels);
99                         Uint16 *destEnd = destIter + size;
100                         for (;srcIter < srcEnd && destIter < destEnd;
101                                         ++srcIter, ++destIter) {
102                                 DesaturatePixel(
103                                                 srcIter, srcFmt,
104                                                 destIter, destFmt,
105                                                 amount);
106                         }
107                         break; }
108                 case 4: {
109                         Uint32 *destIter = reinterpret_cast<Uint32 *>(
110                                         dest->pixels);
111                         Uint32 *destEnd = destIter + size;
112                         for (;srcIter < srcEnd && destIter < destEnd;
113                                         ++srcIter, ++destIter) {
114                                 DesaturatePixel(
115                                                 srcIter, srcFmt,
116                                                 destIter, destFmt,
117                                                 amount);
118                         }
119                         break; }
120                 }
121                 break; }
122         }
123         SDL_UnlockSurface(dest);
124         SDL_UnlockSurface(src);
125 }
126
127 }