fixed the last commit to set and check the target more often, thanks fuzzie
[gemrb.git] / gemrb / core / Palette.cpp
blob11690f11980e50b57a97c1e6a4385cc681ab44e6
1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2006 The GemRB Project
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program 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.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "Palette.h"
23 #include "Interface.h"
25 #define MINCOL 2
26 #define MUL 2
28 void Palette::CreateShadedAlphaChannel()
30 for (int i = 0; i < 256; ++i) {
31 unsigned int r = col[i].r;
32 unsigned int g = col[i].g;
33 unsigned int b = col[i].b;
34 unsigned int m = (r + g + b) / 3;
35 if (m > MINCOL) {
36 if (( r == 0 ) && ( g == 0xff ) && ( b == 0 )) {
37 col[i].a = 0xff;
38 } else {
39 int tmp = m * MUL;
40 col[i].a = ( tmp > 0xff ) ? 0xff : (unsigned char) tmp;
43 else {
44 col[i].a = 0;
47 alpha = true;
50 Palette* Palette::Copy()
52 Palette* pal = new Palette(col, alpha);
53 Release();
54 return pal;
57 void Palette::SetupPaperdollColours(const ieDword* Colors, unsigned int type)
59 unsigned int s = 8*type;
60 //metal
61 core->GetPalette( (Colors[0]>>s)&0xFF, 12, &col[0x04]);
62 //minor
63 core->GetPalette( (Colors[1]>>s)&0xFF, 12, &col[0x10]);
64 //major
65 core->GetPalette( (Colors[2]>>s)&0xFF, 12, &col[0x1c]);
66 //skin
67 core->GetPalette( (Colors[3]>>s)&0xFF, 12, &col[0x28]);
68 //leather
69 core->GetPalette( (Colors[4]>>s)&0xFF, 12, &col[0x34]);
70 //armor
71 core->GetPalette( (Colors[5]>>s)&0xFF, 12, &col[0x40]);
72 //hair
73 core->GetPalette( (Colors[6]>>s)&0xFF, 12, &col[0x4c]);
75 //minor
76 memcpy( &col[0x58], &col[0x11], 8 * sizeof( Color ) );
77 //major
78 memcpy( &col[0x60], &col[0x1d], 8 * sizeof( Color ) );
79 //minor
80 memcpy( &col[0x68], &col[0x11], 8 * sizeof( Color ) );
81 //metal
82 memcpy( &col[0x70], &col[0x05], 8 * sizeof( Color ) );
83 //leather
84 memcpy( &col[0x78], &col[0x35], 8 * sizeof( Color ) );
85 //leather
86 memcpy( &col[0x80], &col[0x35], 8 * sizeof( Color ) );
87 //minor
88 memcpy( &col[0x88], &col[0x11], 8 * sizeof( Color ) );
90 int i;
91 for (i = 0x90; i < 0xA8; i += 0x08)
92 //leather
93 memcpy( &col[i], &col[0x35], 8 * sizeof( Color ) );
95 //skin
96 memcpy( &col[0xB0], &col[0x29], 8 * sizeof( Color ) );
98 for (i = 0xB8; i < 0xFF; i += 0x08)
99 //leather
100 memcpy( &col[i], &col[0x35], 8 * sizeof( Color ) );
104 static inline void applyMod(const Color& src, Color& dest,
105 const RGBModifier& mod) {
106 if (mod.speed == -1) {
107 if (mod.type == RGBModifier::TINT) {
108 dest.r = ((unsigned int)src.r * mod.rgb.r)>>8;
109 dest.g = ((unsigned int)src.g * mod.rgb.g)>>8;
110 dest.b = ((unsigned int)src.b * mod.rgb.b)>>8;
111 } else if (mod.type == RGBModifier::BRIGHTEN) {
112 unsigned int r = (unsigned int)src.r * mod.rgb.r;
113 if (r & (~0x7FF)) r = 0x7FF;
114 dest.r = r >> 3;
116 unsigned int g = (unsigned int)src.g * mod.rgb.g;
117 if (g & (~0x7FF)) g = 0x7FF;
118 dest.g = g >> 3;
120 unsigned int b = (unsigned int)src.b * mod.rgb.b;
121 if (b & (~0x7FF)) b = 0x7FF;
122 dest.b = b >> 3;
123 } else if (mod.type == RGBModifier::ADD) {
124 unsigned int r = (unsigned int)src.r + mod.rgb.r;
125 if (r & (~0xFF)) r = 0xFF;
126 dest.r = r;
128 unsigned int g = (unsigned int)src.g + mod.rgb.g;
129 if (g & (~0xFF)) g = 0xFF;
130 dest.g = g;
132 unsigned int b = (unsigned int)src.b + mod.rgb.b;
133 if (b & (~0xFF)) b = 0xFF;
134 dest.b = b;
135 } else {
136 dest = src;
138 } else if (mod.speed > 0) {
140 // TODO: a sinewave will probably look better
141 int phase = (mod.phase % (2*mod.speed));
142 if (phase > mod.speed) {
143 phase = 512 - (256*phase)/mod.speed;
144 } else {
145 phase = (256*phase)/mod.speed;
148 if (mod.type == RGBModifier::TINT) {
149 dest.r = ((unsigned int)src.r * (256*256 + phase*mod.rgb.r - 256*phase))>>16;
150 dest.g = ((unsigned int)src.g * (256*256 + phase*mod.rgb.g - 256*phase))>>16;
151 dest.b = ((unsigned int)src.b * (256*256 + phase*mod.rgb.b - 256*phase))>>16;
152 } else if (mod.type == RGBModifier::BRIGHTEN) {
153 unsigned int r = src.r + (256*256 + phase*mod.rgb.r - 256*phase);
154 if (r & (~0x7FFFF)) r = 0x7FFFF;
155 dest.r = r >> 11;
157 unsigned int g = src.g * (256*256 + phase*mod.rgb.g - 256*phase);
158 if (g & (~0x7FFFF)) g = 0x7FFFF;
159 dest.g = g >> 11;
161 unsigned int b = src.b * (256*256 + phase*mod.rgb.b - 256*phase);
162 if (b & (~0x7FFFF)) b = 0x7FFFF;
163 dest.b = b >> 11;
164 } else if (mod.type == RGBModifier::ADD) {
165 unsigned int r = src.r + ((phase*mod.rgb.r)>>8);
166 if (r & (~0xFF)) r = 0xFF;
167 dest.r = r;
169 unsigned int g = src.g + ((phase*mod.rgb.g)>>8);
170 if (g & (~0xFF)) g = 0xFF;
171 dest.g = g;
173 unsigned int b = src.b + ((phase*mod.rgb.b)>>8);
174 if (b & (~0xFF)) b = 0xFF;
175 dest.b = b;
176 } else {
177 dest = src;
179 } else {
180 dest = src;
184 void Palette::SetupRGBModification(const Palette* src, const RGBModifier* mods,
185 unsigned int type)
187 const RGBModifier* tmods = mods+(8*type);
188 int i;
190 for (i = 0; i < 4; ++i)
191 col[i] = src->col[i];
193 for (i = 0; i < 12; ++i)
194 applyMod(src->col[0x04+i],col[0x04+i],tmods[0]);
195 for (i = 0; i < 12; ++i)
196 applyMod(src->col[0x10+i],col[0x10+i],tmods[1]);
197 for (i = 0; i < 12; ++i)
198 applyMod(src->col[0x1c+i],col[0x1c+i],tmods[2]);
199 for (i = 0; i < 12; ++i)
200 applyMod(src->col[0x28+i],col[0x28+i],tmods[3]);
201 for (i = 0; i < 12; ++i)
202 applyMod(src->col[0x34+i],col[0x34+i],tmods[4]);
203 for (i = 0; i < 12; ++i)
204 applyMod(src->col[0x40+i],col[0x40+i],tmods[5]);
205 for (i = 0; i < 12; ++i)
206 applyMod(src->col[0x4c+i],col[0x4c+i],tmods[6]);
207 for (i = 0; i < 8; ++i)
208 applyMod(src->col[0x58+i],col[0x58+i],tmods[1]);
209 for (i = 0; i < 8; ++i)
210 applyMod(src->col[0x60+i],col[0x60+i],tmods[2]);
211 for (i = 0; i < 8; ++i)
212 applyMod(src->col[0x68+i],col[0x68+i],tmods[1]);
213 for (i = 0; i < 8; ++i)
214 applyMod(src->col[0x70+i],col[0x70+i],tmods[0]);
215 for (i = 0; i < 8; ++i)
216 applyMod(src->col[0x78+i],col[0x78+i],tmods[4]);
217 for (i = 0; i < 8; ++i)
218 applyMod(src->col[0x80+i],col[0x80+i],tmods[4]);
219 for (i = 0; i < 8; ++i)
220 applyMod(src->col[0x88+i],col[0x88+i],tmods[1]);
221 for (i = 0; i < 24; ++i)
222 applyMod(src->col[0x90+i],col[0x90+i],tmods[4]);
224 for (i = 0; i < 8; ++i)
225 col[0xA8+i] = src->col[0xA8+i];
227 for (i = 0; i < 8; ++i)
228 applyMod(src->col[0xB0+i],col[0xB0+i],tmods[3]);
229 for (i = 0; i < 72; ++i)
230 applyMod(src->col[0xB8+i],col[0xB8+i],tmods[4]);
233 void Palette::SetupGlobalRGBModification(const Palette* src,
234 const RGBModifier& mod)
236 int i;
237 // don't modify the transparency and shadow colour
238 for (i = 0; i < 2; ++i)
239 col[i] = src->col[i];
241 for (i = 2; i < 256; ++i)
242 applyMod(src->col[i],col[i],mod);