1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef CINE_PAL_H
24 #define CINE_PAL_H
25 
26 #include "graphics/pixelformat.h"
27 
28 namespace Cine {
29 
30 /**
31  * Endian types. Used at least by Palette class's load and save functions.
32  * TODO: Move somewhere more general as this is definitely not Cine-engine specific
33  *
34  * NOTE: It seems LITTLE_ENDIAN and/or BIG_ENDIAN were defined already on some platforms so
35  * therefore renamed the enumerations to something not clashing by giving them "CINE_"-prefixes.
36  */
37 enum EndianType {
38 	CINE_NATIVE_ENDIAN,
39 	CINE_LITTLE_ENDIAN,
40 	CINE_BIG_ENDIAN
41 };
42 
43 struct PalEntry {
44 	char name[10];
45 	byte pal1[16];
46 	byte pal2[16];
47 };
48 
49 void loadPal(const char *fileName);
50 
51 void loadRelatedPalette(const char *fileName);
52 
53 /**
54  * A class for handling Cine-engine's palettes.
55  * TODO: Test a bit more
56  */
57 class Palette {
58 public:
59 	struct Color {
60 		uint8 r, g, b;
61 	};
62 
63 	/**
64 	 * Create an initially black palette with the given color format and number of colors.
65 	 * @param format Color format
66 	 * @param numColors Number of colors
67 	 * @note For the default constructed object (i.e. no parameters given) this will hold: empty() && !isValid()
68 	 */
69 	Palette(const Graphics::PixelFormat format = Graphics::PixelFormat(), const uint numColors = 0);
70 	Palette(const Palette& other);
71 	Palette& operator=(const Palette& other);
72 
73 	/**
74 	 * Clear the palette (Set color count to zero, release memory, overwrite color format with default value).
75 	 * @note This is very different from using fillWithBlack-function which fills the palette with black.
76 	 */
77 	Palette &clear();
78 
79 	/**
80 	 * Load palette from buffer with given color format, endianness and number of colors.
81 	 * @param buf Input buffer
82 	 * @param size Input buffer size in bytes
83 	 * @param format Input color format
84 	 * @param numColors Number of colors to load
85 	 * @param endian The endianness of the colors in the input buffer
86 	 */
87 	Palette &load(const byte *buf, const uint size, const Graphics::PixelFormat format, const uint numColors, const EndianType endian);
88 
89 	/**
90 	 * Save the whole palette to buffer in original color format using defined endianness.
91 	 * @param buf Output buffer
92 	 * @param size Output buffer size in bytes
93 	 * @param endian The endian type to use
94 	 */
95 	byte *save(byte *buf, const uint size, const EndianType endian) const;
96 
97 	/**
98 	 * Save the whole palette to buffer in given color format using defined endianness.
99 	 * @param buf Output buffer
100 	 * @param size Output buffer size in bytes
101 	 * @param format Output color format
102 	 * @param endian The endian type to use
103 	 */
104 	byte *save(byte *buf, const uint size, const Graphics::PixelFormat format, const EndianType endian) const;
105 
106 	/**
107 	 * Save (partial) palette to buffer in given color format using defined endianness.
108 	 * @param buf Output buffer
109 	 * @param size Output buffer size in bytes
110 	 * @param format Output color format
111 	 * @param numColors Number of colors to save
112 	 * @param endian The endian type to use
113 	 * @param firstIndex Starting color index (from which onwards to save the colors)
114 	 */
115 	byte *save(byte *buf, const uint size, const Graphics::PixelFormat format, const uint numColors, const EndianType endian, const byte firstIndex = 0) const;
116 
117 	/**
118 	 * Rotate the palette in color range [firstIndex, lastIndex] to the right by one.
119 	 */
120 	Palette &rotateRight(byte firstIndex, byte lastIndex);
121 	Palette &rotateLeft(byte firstIndex, byte lastIndex);
122 	Palette &saturatedAddColor(Palette &output, byte firstIndex, byte lastIndex, signed r, signed g, signed b) const;
123 
124 	/**
125 	 * Saturated add an RGB color in given color format to current palette's subset and save the modified colors in the given output palette.
126 	 * @param output The output palette (Only this palette is modified)
127 	 * @param firstIndex First color index of the palette's subset (Inclusive range)
128 	 * @param lastIndex Last color index of the palette's subset (Inclusive range)
129 	 * @param rSource The red color component in the source color format
130 	 * @param gSource The green color component in the source color format
131 	 * @param bSource The blue color component in the source color format
132 	 * @param sourceFormat The source color format (i.e. the color format of the given RGB color)
133 	 * @note This function basically converts the given color to the palette's internal color format
134 	 * and adds that using the normal saturatedAddColor-function.
135 	 */
136 	Palette &saturatedAddColor(Palette &output, byte firstIndex, byte lastIndex, signed rSource, signed gSource, signed bSource, const Graphics::PixelFormat &sourceFormat) const;
137 
138 	/**
139 	 * Saturated add a normalized gray value to current palette's subset and save the modified colors in the given output palette.
140 	 * @param output The output palette (Only this palette is modified)
141 	 * @param firstIndex First color index of the palette's subset (Inclusive range)
142 	 * @param lastIndex Last color index of the palette's subset (Inclusive range)
143 	 * @param grayDividend Dividend of the normalized gray value
144 	 * @param grayDenominator Denominator of the normalized gray value
145 	 * @note The normalized gray value (i.e. in range [-1, +1]) is given as a fractional number
146 	 * (i.e. the normalized gray value is calculated by dividing grayDividend by grayDenominator).
147 	 */
148 	Palette &saturatedAddNormalizedGray(Palette &output, byte firstIndex, byte lastIndex, signed grayDividend, signed grayDenominator) const;
149 
150 	bool empty() const;
151 	uint colorCount() const;
152 	Palette &fillWithBlack();
153 
154 	/** Is the palette valid? (Mostly just checks the color format for correctness) */
155 	bool isValid() const;
156 
157 	/** The original color format in which this palette was loaded. */
158 	const Graphics::PixelFormat &colorFormat() const;
159 
160 	/** Sets current palette to global OSystem's palette using g_system->getPaletteManager()->setPalette. */
161 	void setGlobalOSystemPalette() const;
162 
163 	/** Get the color at the given palette index. */
164 	Color getColor(byte index) const;
165 
166 	/** Get the red color component of the color at the given palette index. */
167 	uint8 getR(byte index) const;
168 
169 	/** Get the green color component of the color at the given palette index. */
170 	uint8 getG(byte index) const;
171 
172 	/** Get the blue color component of the color at the given palette index. */
173 	uint8 getB(byte index) const;
174 
175 	bool ensureContrast(byte &minBrightnessColorIndex);
176 	bool isEqual(byte index1, byte index2);
177 
178 private:
179 	int findMinBrightnessColorIndex(uint minColorIndex = 1);
180 	byte brightness(byte colorIndex);
181 	void setColorFormat(const Graphics::PixelFormat format);
182 
183 	// WORKAROUND: Using a reference to a result here instead of returning an Color object.
184 	// This is needed because when using a Color as return value, this would crash Chrilith's
185 	// compiler for PalmOS.
186 	// TODO: Add more information about the compiler.
187 	void saturatedAddColor(Color &result, const Color &baseColor, signed r, signed g, signed b) const;
188 
189 private:
190 	Graphics::PixelFormat _format; ///< The used source color format
191 	Common::Array<Color> _colors;  ///< The actual palette data
192 };
193 
194 } // End of namespace Cine
195 
196 #endif
197