aboutsummaryrefslogtreecommitdiff
path: root/engines/cine/pal.h
blob: 8b73771df6afc1e03ad0f134f56f04a2dc141666 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * $URL$
 * $Id$
 *
 */

#ifndef CINE_PAL_H
#define CINE_PAL_H

#include "graphics/pixelformat.h"

namespace Cine {

/*! \brief Low resolution (9-bit) color format used in Cine's 16-color modes. */
static const Graphics::PixelFormat kLowPalFormat  = {2, 5, 5, 5, 8, 8, 4,  0, 0};

/*! \brief High resolution (24-bit) color format used in Cine's 256-color modes. */
static const Graphics::PixelFormat kHighPalFormat = {3, 0, 0, 0, 8, 0, 8, 16, 0};

/*! \brief The color format used by OSystem's setPalette-function. */
static const Graphics::PixelFormat kSystemPalFormat = {4, 0, 0, 0, 8, 0, 8, 16, 0};

/*! \brief Endian types. Used at least by Palette class's load and save functions.
 * TODO: Move somewhere more general as this is definitely not Cine-engine specific
 *
 * NOTE: It seems LITTLE_ENDIAN and/or BIG_ENDIAN were defined already on some platforms so
 * therefore renamed the enumerations to something not clashing by giving them "CINE_"-prefixes.
 */
enum EndianType {
	CINE_NATIVE_ENDIAN,
	CINE_LITTLE_ENDIAN,
	CINE_BIG_ENDIAN
};

struct PalEntry {
	char name[10];
	byte pal1[16];
	byte pal2[16];
};

extern Common::Array<PalEntry> palArray;

void loadPal(const char *fileName);

void loadRelatedPalette(const char *fileName);

void palRotate(uint16 *pal, byte a, byte b, byte c);
void palRotate(byte *pal, byte a, byte b, byte c);
uint16 transformColor(uint16 baseColor, int r, int g, int b);
void transformPaletteRange(uint16 *srcPal, uint16 *dstPal, int startColor, int stopColor, int r, int g, int b);
void transformPaletteRange(byte *srcPal, byte *dstPal, int startColor, int stopColor, int r, int g, int b);

// This class might be used for handling Cine-engine's palettes in the future. WIP!
// TODO: Document
// TODO: Make use of
// TODO: Test
class Palette {
private:
	struct Color {
		uint8 r, g, b;
	};

public:
	/*! \brief Load palette from buffer with given color format, endianness and number of colors.
	 * \param buf Input buffer
	 * \param size Input buffer size in bytes
	 * \param format Input color format
	 * \param numColors Number of colors to load
	 * \param endian The endianness of the colors in the input buffer
	 */
	Palette &load(const byte *buf, const uint size, const Graphics::PixelFormat format, const uint numColors, const EndianType endian);

	/*! \brief Save the whole palette to buffer in original color format using defined endianness.
	 * \param buf Output buffer
	 * \param size Output buffer size in bytes
	 * \param endian The endian type to use
	 */
	byte *save(byte *buf, const uint size, const EndianType endian) const;

	/*! \brief Save the whole palette to buffer in given color format using defined endianness.
	 * \param buf Output buffer
	 * \param size Output buffer size in bytes
	 * \param format Output color format
	 * \param endian The endian type to use
	 */
	byte *save(byte *buf, const uint size, const Graphics::PixelFormat format, const EndianType endian) const;

	/*! \brief Save (partial) palette to buffer in given color format using defined endianness.
	 * \param buf Output buffer
	 * \param size Output buffer size in bytes
	 * \param format Output color format
	 * \param numColors Number of colors to save
	 * \param endian The endian type to use
	 * \param firstIndex Starting color index (from which onwards to save the colors)
	 */
	byte *save(byte *buf, const uint size, const Graphics::PixelFormat format, const uint numColors, const EndianType endian, const byte firstIndex = 0) const;

	Palette &rotateRight(byte firstIndex, byte lastIndex);
	Palette &saturatedAddColor(Palette& output, byte firstIndex, byte lastIndex, signed r, signed g, signed b);

	/*! \brief Saturated add a normalized gray value to current palette's subset and save the modified colors in the given output palette.
	 * \param output The output palette (Only this palette is modified)
	 * \param firstIndex First color index of the palette's subset (Inclusive range)
	 * \param lastIndex Last color index of the palette's subset (Inclusive range)
	 * \param grayDividend Dividend of the normalized gray value
	 * \param grayDenominator Denominator of the normalized gray value
	 * \note The normalized gray value (i.e. in range [-1, +1]) is given as a fractional number
	 * (i.e. the normalized gray value is calculated by dividing grayDividend by grayDenominator).
	 */
	Palette &saturatedAddNormalizedGray(Palette& output, byte firstIndex, byte lastIndex, signed grayDividend, signed grayDenominator);

	uint colorCount() const;

	Palette &fillWithBlack();

	/*! \brief The original endian type in which this palette was loaded.
	 * \note This will always return either CINE_BIG_ENDIAN or CINE_LITTLE_ENDIAN (So no CINE_NATIVE_ENDIAN).
	 */
	EndianType endianType() const;

	/*! \brief The original color format in which this palette was loaded. */
	Graphics::PixelFormat colorFormat() const;

	/*! \brief Sets current palette to global OSystem's palette using g_system->setPalette. */
	void setGlobalOSystemPalette() const;

private:
	void setColorFormat(const Graphics::PixelFormat format);
	void setEndianType(const EndianType endian);
	Cine::Palette::Color saturatedAddColor(Cine::Palette::Color baseColor, signed r, signed g, signed b) const;

private:
	// The used source format, its endianness etc.
	Graphics::PixelFormat _format;
	uint _rBits, _gBits, _bBits;
	uint _rMax, _gMax, _bMax;
	bool _bigEndian;

	Common::Array<Color> _colors;
};

} // End of namespace Cine

#endif