text: #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);
  }
  
  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);
  }
  
  static 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;
  }
  