#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; }