ManaPlus
sdlpixel.h
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2011-2019 The ManaPlus Developers
4  * Copyright (C) 2019-2021 Andrei Karas
5  *
6  * This file is part of The ManaPlus Client.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 /* _______ __ __ __ ______ __ __ _______ __ __
23  * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
24  * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
25  * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
26  * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
27  * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
28  * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
29  *
30  * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
31  *
32  *
33  * Per Larsson a.k.a finalman
34  * Olof Naessén a.k.a jansem/yakslem
35  *
36  * Visit: http://guichan.sourceforge.net
37  *
38  * License: (BSD)
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions
41  * are met:
42  * 1. Redistributions of source code must retain the above copyright
43  * notice, this list of conditions and the following disclaimer.
44  * 2. Redistributions in binary form must reproduce the above copyright
45  * notice, this list of conditions and the following disclaimer in
46  * the documentation and/or other materials provided with the
47  * distribution.
48  * 3. Neither the name of Guichan nor the names of its contributors may
49  * be used to endorse or promote products derived from this software
50  * without specific prior written permission.
51  *
52  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
53  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
54  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
55  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
56  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
57  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
58  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
59  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
60  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
61  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63  */
64 
65 #ifndef UTILS_SDLPIXEL_H
66 #define UTILS_SDLPIXEL_H
67 
68 #include "gui/color.h"
69 
70 PRAGMA48(GCC diagnostic push)
71 PRAGMA48(GCC diagnostic ignored "-Wshadow")
72 #include <SDL.h>
73 PRAGMA48(GCC diagnostic pop)
74 
75 #ifndef SDL_BYTEORDER
76 #error missing SDL_endian.h
77 #endif // SDL_BYTEORDER
78 
86 inline void SDLputPixel(SDL_Surface* surface, int x, int y,
87  const Color& color)
88 {
89  if (surface == nullptr)
90  return;
91 
92  const int bpp = surface->format->BytesPerPixel;
93 
94  SDL_LockSurface(surface);
95 
96  Uint8 *const p = static_cast<uint8_t*>(surface->pixels)
97  + CAST_SIZE(y * surface->pitch + x * bpp);
98 
99  const Uint32 pixel = SDL_MapRGB(surface->format,
100  CAST_U8(color.r), CAST_U8(color.g),
101  CAST_U8(color.b));
102 
103  switch (bpp)
104  {
105  case 1:
106  *p = CAST_U8(pixel);
107  break;
108 
109  case 2:
110  *reinterpret_cast<uint16_t*>(p) = CAST_U16(pixel);
111  break;
112 
113  case 3:
114 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
115  p[0] = CAST_U8((pixel >> 16) & 0xff);
116  p[1] = CAST_U8((pixel >> 8) & 0xff);
117  p[2] = CAST_U8((pixel) & 0xff);
118 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
119 
120  p[0] = CAST_U8((pixel) & 0xff);
121  p[1] = CAST_U8((pixel >> 8) & 0xff);
122  p[2] = CAST_U8((pixel >> 16) & 0xff);
123 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
124 
125  break;
126 
127  case 4:
128  *reinterpret_cast<Uint32*>(p) = pixel;
129  break;
130 
131  default:
132  break;
133  }
134 
135  SDL_UnlockSurface(surface);
136 }
137 
145 inline unsigned int SDLAlpha32(const unsigned int src,
146  const unsigned int dst,
147  const unsigned char a)
148 {
149  const unsigned int b = ((src & 0xff) * a + (dst & 0xff) * (255 - a)) >> 8;
150  const unsigned int g = ((src & 0xff00) * a + (dst & 0xff00)
151  * (255 - a)) >> 8;
152  const unsigned int r = ((src & 0xff0000) * a + (dst & 0xff0000)
153  * (255 - a)) >> 8;
154 
155  return (b & 0xff) | (g & 0xff00) | (r & 0xff0000);
156 }
157 
158 inline unsigned short SDLAlpha16(const unsigned short src,
159  const unsigned short dst,
160  const unsigned char a,
161  const SDL_PixelFormat *const f) A_NONNULL(4);
162 
170 inline unsigned short SDLAlpha16(const unsigned short src,
171  const unsigned short dst,
172  const unsigned char a,
173  const SDL_PixelFormat *const f)
174 {
175  unsigned int b = ((src & f->Rmask) * a + (dst & f->Rmask)
176  * (255 - a)) >> 8;
177  unsigned int g = ((src & f->Gmask) * a + (dst & f->Gmask)
178  * (255 - a)) >> 8;
179  unsigned int r = ((src & f->Bmask) * a + (dst & f->Bmask)
180  * (255 - a)) >> 8;
181 
182  return static_cast<unsigned short>((b & f->Rmask)
183  | (g & f->Gmask) | (r & f->Bmask));
184 }
185 
193 inline void SDLputPixelAlpha(SDL_Surface* surface, int x, int y,
194  const Color& color)
195 {
196  if (surface == nullptr)
197  return;
198  const int bpp = surface->format->BytesPerPixel;
199 
200  SDL_LockSurface(surface);
201 
202  Uint8 *const p = static_cast<uint8_t*>(surface->pixels)
203  + CAST_SIZE(y * surface->pitch + x * bpp);
204 
205  const Uint32 pixel = SDL_MapRGB(surface->format,
206  CAST_U8(color.r),
207  CAST_U8(color.g),
208  CAST_U8(color.b));
209 
210  switch (bpp)
211  {
212  case 1:
213  *p = CAST_U8(pixel);
214  break;
215 
216  case 2:
217  *reinterpret_cast<Uint16*>(p) = SDLAlpha16(
218  static_cast<unsigned short>(pixel),
219  *reinterpret_cast<unsigned short*>(p),
220  CAST_U8(color.a), surface->format);
221  break;
222 
223  case 3:
224 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
225  p[2] = CAST_U8((p[2] * (255 - color.a)
226  + color.b * color.a) >> 8);
227  p[1] = CAST_U8((p[1] * (255 - color.a)
228  + color.g * color.a) >> 8);
229  p[0] = CAST_U8((p[0] * (255 - color.a)
230  + color.r * color.a) >> 8);
231 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
232 
233  p[0] = CAST_U8((p[0] * (255 - color.a)
234  + color.b * color.a) >> 8);
235  p[1] = CAST_U8((p[1] * (255 - color.a)
236  + color.g * color.a) >> 8);
237  p[2] = CAST_U8((p[2] * (255 - color.a)
238  + color.r * color.a) >> 8);
239 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
240 
241  break;
242 
243  case 4:
244  *reinterpret_cast<Uint32*>(p) = SDLAlpha32(pixel,
245  *reinterpret_cast<Uint32*>(p),
246  CAST_U8(color.a));
247  break;
248  default:
249  break;
250  }
251 
252  SDL_UnlockSurface(surface);
253 }
254 
255 #endif // UTILS_SDLPIXEL_H
#define CAST_U16
Definition: cast.h:29
#define CAST_SIZE
Definition: cast.h:34
#define CAST_U8
Definition: cast.h:27
Definition: color.h:76
unsigned int a
Definition: color.h:251
unsigned int b
Definition: color.h:245
unsigned int r
Definition: color.h:235
unsigned int g
Definition: color.h:240
#define A_NONNULL(...)
Definition: localconsts.h:168
#define PRAGMA48(str)
Definition: localconsts.h:199
void SDLputPixelAlpha(SDL_Surface *surface, int x, int y, const Color &color)
Definition: sdlpixel.h:193
void SDLputPixel(SDL_Surface *surface, int x, int y, const Color &color)
Definition: sdlpixel.h:86
unsigned int SDLAlpha32(const unsigned int src, const unsigned int dst, const unsigned char a)
Definition: sdlpixel.h:145
unsigned short SDLAlpha16(const unsigned short src, const unsigned short dst, const unsigned char a, const SDL_PixelFormat *const f)
Definition: sdlpixel.h:170