1 /* 2 * This file is part of Dune Legacy. 3 * 4 * Dune Legacy is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * Dune Legacy is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with Dune Legacy. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef PALETTE_H 19 #define PALETTE_H 20 21 #include <misc/exceptions.h> 22 23 #include <SDL.h> 24 #include <string.h> 25 26 class Palette 27 { 28 public: Palette()29 Palette() : pSDLPalette(nullptr) { 30 31 } 32 Palette(int numPaletteEntries)33 explicit Palette(int numPaletteEntries) : pSDLPalette(nullptr) { 34 pSDLPalette = SDL_AllocPalette(numPaletteEntries); 35 if (!pSDLPalette) { 36 throw; 37 } 38 } 39 Palette(const SDL_Palette * pSDLPalette)40 explicit Palette(const SDL_Palette* pSDLPalette) : pSDLPalette(nullptr) { 41 setSDLPalette(pSDLPalette); 42 } 43 Palette(const Palette & palette)44 Palette(const Palette& palette) : pSDLPalette(nullptr) { 45 *this = palette; 46 } 47 ~Palette()48 virtual ~Palette() { 49 deleteSDLPalette(); 50 } 51 52 Palette& operator=(const Palette& palette) { 53 if(this == &palette) { 54 return *this; 55 } 56 57 this->setSDLPalette(palette.pSDLPalette); 58 59 return *this; 60 } 61 62 inline SDL_Color& operator[](const int i) { 63 if(pSDLPalette == nullptr || i < 0 || i >= pSDLPalette->ncolors) { 64 THROW(std::runtime_error, "Palette::operator[]: Invalid index!"); 65 } 66 67 return pSDLPalette->colors[i]; 68 } 69 70 inline const SDL_Color& operator[](const int i) const { 71 if(pSDLPalette == nullptr || i < 0 || i >= pSDLPalette->ncolors) { 72 THROW(std::runtime_error, "Palette::operator[]: Invalid index!"); 73 } 74 75 return pSDLPalette->colors[i]; 76 } 77 getSDLPalette()78 inline SDL_Palette* getSDLPalette() const { 79 return pSDLPalette; 80 } 81 setSDLPalette(const SDL_Palette * pSDLPalette)82 void setSDLPalette(const SDL_Palette* pSDLPalette) { 83 if(!pSDLPalette) { 84 this->pSDLPalette = nullptr; 85 return; 86 } 87 SDL_Palette* pNewSDLPalette = SDL_AllocPalette(pSDLPalette->ncolors); 88 if(!pNewSDLPalette) { 89 throw; 90 } 91 memcpy(pNewSDLPalette->colors, pSDLPalette->colors, pSDLPalette->ncolors * sizeof(SDL_Color)); 92 93 deleteSDLPalette(); 94 this->pSDLPalette = pNewSDLPalette; 95 } 96 getNumColors()97 inline int getNumColors() const { 98 if(pSDLPalette == nullptr) { 99 return 0; 100 } 101 102 return pSDLPalette->ncolors; 103 } 104 105 void applyToSurface(SDL_Surface* pSurface, int firstColor = 0, int endColor = -1) const { 106 Uint32 colorKey = 0; 107 bool hasColorKey = (SDL_GetColorKey(pSurface, &colorKey) == 0); 108 109 if(pSDLPalette == nullptr) { 110 THROW(std::runtime_error, "Palette::applyToSurface(): Palette not initialized yet!"); 111 } 112 113 if(pSurface == nullptr) { 114 THROW(std::runtime_error, "Palette::applyToSurface(): pSurface == nullptr!"); 115 } 116 117 if(pSurface->format->palette == nullptr) { 118 THROW(std::runtime_error, "Palette::applyToSurface(): Cannot apply palette to surface without a palette!"); 119 } 120 121 int nColors = (endColor != -1) ? (endColor - firstColor + 1) : (pSDLPalette->ncolors - firstColor); 122 SDL_SetPaletteColors(pSurface->format->palette, pSDLPalette->colors + firstColor, firstColor, nColors); 123 124 if(hasColorKey) { 125 SDL_SetColorKey(pSurface, SDL_TRUE, colorKey); 126 } 127 } 128 129 private: 130 deleteSDLPalette()131 void deleteSDLPalette() { 132 if (pSDLPalette != nullptr) { 133 SDL_FreePalette(pSDLPalette); 134 } 135 pSDLPalette = nullptr; 136 } 137 138 SDL_Palette* pSDLPalette; 139 }; 140 141 #endif // PALETTE_H 142