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
|
#include "PackedCol.h"
#include "String.h"
#include "ExtMath.h"
PackedCol PackedCol_Scale(PackedCol a, float t) {
cc_uint8 R = (cc_uint8)(PackedCol_R(a) * t);
cc_uint8 G = (cc_uint8)(PackedCol_G(a) * t);
cc_uint8 B = (cc_uint8)(PackedCol_B(a) * t);
return (a & PACKEDCOL_A_MASK) | PackedCol_R_Bits(R) | PackedCol_G_Bits(G) | PackedCol_B_Bits(B);
}
PackedCol PackedCol_Lerp(PackedCol a, PackedCol b, float t) {
cc_uint8 R = (cc_uint8)Math_Lerp(PackedCol_R(a), PackedCol_R(b), t);
cc_uint8 G = (cc_uint8)Math_Lerp(PackedCol_G(a), PackedCol_G(b), t);
cc_uint8 B = (cc_uint8)Math_Lerp(PackedCol_B(a), PackedCol_B(b), t);
return (a & PACKEDCOL_A_MASK) | PackedCol_R_Bits(R) | PackedCol_G_Bits(G) | PackedCol_B_Bits(B);
}
PackedCol PackedCol_Tint(PackedCol a, PackedCol b) {
cc_uint32 R = PackedCol_R(a) * PackedCol_R(b) / 255;
cc_uint32 G = PackedCol_G(a) * PackedCol_G(b) / 255;
cc_uint32 B = PackedCol_B(a) * PackedCol_B(b) / 255;
/* TODO: don't shift when multiplying */
return (a & PACKEDCOL_A_MASK) | (R << PACKEDCOL_R_SHIFT) | (G << PACKEDCOL_G_SHIFT) | (B << PACKEDCOL_B_SHIFT);
}
PackedCol PackedCol_ScreenBlend(PackedCol a, PackedCol b) {
PackedCol finalColor, aInverted, bInverted;
cc_uint8 R, G, B;
/* With Screen blend mode, the values of the pixels in the two layers are inverted, multiplied, and then inverted again. */
R = 255 - PackedCol_R(a);
G = 255 - PackedCol_G(a);
B = 255 - PackedCol_B(a);
aInverted = PackedCol_Make(R, G, B, 255);
R = 255 - PackedCol_R(b);
G = 255 - PackedCol_G(b);
B = 255 - PackedCol_B(b);
bInverted = PackedCol_Make(R, G, B, 255);
finalColor = PackedCol_Tint(aInverted, bInverted);
R = 255 - PackedCol_R(finalColor);
G = 255 - PackedCol_G(finalColor);
B = 255 - PackedCol_B(finalColor);
return PackedCol_Make(R, G, B, 255);
}
void PackedCol_GetShaded(PackedCol normal, PackedCol* xSide, PackedCol* zSide, PackedCol* yMin) {
*xSide = PackedCol_Scale(normal, PACKEDCOL_SHADE_X);
*zSide = PackedCol_Scale(normal, PACKEDCOL_SHADE_Z);
*yMin = PackedCol_Scale(normal, PACKEDCOL_SHADE_YMIN);
}
int PackedCol_DeHex(char hex) {
if (hex >= '0' && hex <= '9') {
return (hex - '0');
} else if (hex >= 'a' && hex <= 'f') {
return (hex - 'a') + 10;
} else if (hex >= 'A' && hex <= 'F') {
return (hex - 'A') + 10;
}
return -1;
}
cc_bool PackedCol_Unhex(const char* src, int* dst, int count) {
int i;
for (i = 0; i < count; i++) {
dst[i] = PackedCol_DeHex(src[i]);
if (dst[i] == -1) return false;
}
return true;
}
void PackedCol_ToHex(cc_string* str, PackedCol value) {
String_AppendHex(str, PackedCol_R(value));
String_AppendHex(str, PackedCol_G(value));
String_AppendHex(str, PackedCol_B(value));
}
cc_bool PackedCol_TryParseHex(const cc_string* str, cc_uint8* rgb) {
int bits[6];
char* buffer = str->buffer;
/* accept XXYYZZ or #XXYYZZ forms */
if (str->length < 6) return false;
if (str->length > 6 && (str->buffer[0] != '#' || str->length > 7)) return false;
if (buffer[0] == '#') buffer++;
if (!PackedCol_Unhex(buffer, bits, 6)) return false;
rgb[0] = (cc_uint8)((bits[0] << 4) | bits[1]);
rgb[1] = (cc_uint8)((bits[2] << 4) | bits[3]);
rgb[2] = (cc_uint8)((bits[4] << 4) | bits[5]);
return true;
}
|