/* License: This is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Use: Some usefull color code. Author: Unai Landa (unai_landa#eresmas·com) Notes: My english is really bad, I allready now that so dont tell me. The original code was nice comented in spanish, but I translated this "on the fly" so I hope you can understand :-) */ // -------------------------------------------------------------------------------------------------------------------- // Some 565 Color space defines. // -------------------------------------------------------------------------------------------------------------------- enum { COLORSPACE_565_RED_MASK = (0xF800), COLORSPACE_565_GREEN_MASK = (0x07E0), COLORSPACE_565_BLUE_MASK = (0x001F), COLORSPACE_565_SATURATE_RED_BIT = (0x10000), COLORSPACE_565_SATURATE_GREEN_BIT = (0x0800), COLORSPACE_565_SATURATE_BLUE_BIT = (0x0020), }; //---------------------------------------------------------------------------- // Some more defines //---------------------------------------------------------------------------- enum { MAXIMO_NUM_BITS_COLOR = 6 , BITS_BAJOS = 5 , MASCARA_A =(COLORSPACE_565_GREEN_MASK) , MASCARA_B =(COLORSPACE_565_RED_MASK|COLORSPACE_565_BLUE_MASK) , MASCARA_SAT_A =(COLORSPACE_565_SATURATE_GREEN_BIT ) , MASCARA_SAT_B =(COLORSPACE_565_SATURATE_RED_BIT|COLORSPACE_565_SATURATE_BLUE_BIT) , MASCARA_A_TWICE =( ((COLORSPACE_565_RED_MASK|COLORSPACE_565_BLUE_MASK)<<16)|(COLORSPACE_565_GREEN_MASK<<0 )) , MASCARA_B_TWICE =( ((COLORSPACE_565_RED_MASK|COLORSPACE_565_BLUE_MASK)<<0 )|(COLORSPACE_565_GREEN_MASK<<16)) , MASCARA_SAT_A_TWICE =( ((COLORSPACE_565_SATURATE_RED_BIT|COLORSPACE_565_SATURATE_BLUE_BIT)<<(16-BITS_BAJOS))|(COLORSPACE_565_SATURATE_GREEN_BIT>>BITS_BAJOS) ) , MASCARA_SAT_B_TWICE =((((COLORSPACE_565_SATURATE_RED_BIT|COLORSPACE_565_SATURATE_BLUE_BIT) )|(COLORSPACE_565_SATURATE_GREEN_BIT<<16))<<(MAXIMO_NUM_BITS_COLOR-BITS_BAJOS) ) }; //---------------------------------------------------------------------- // Use: Adds two 565 colours with saturation and no lose. // Returns: The added colour. // Parameters: Two colours. //---------------------------------------------------------------------- __inline unsigned GE_AddColors565( const unsigned c1, const unsigned c2) { // Separacion: // SetUp: unsigned t1_a = (c1 & MASCARA_A); // 0000__g1__ unsigned t2_a = (c2 & MASCARA_A); // 0000__g2__ unsigned t1_b = (c1 & MASCARA_B); // 0000r1__b1 unsigned t2_b = (c2 & MASCARA_B); // 0000r2__b2 // Suma_A: // Suma_B: t1_a = t2_a = t1_a + t2_a; // 00__gT__ * T means Total t1_b = t2_b = t1_b + t2_b; // 00rT__bT t2_a &= MASCARA_SAT_A; // 00_1____ *** 1 appears ONLY where saturation happened. t2_b &= MASCARA_SAT_B; // 01___1__ *** 1 appears ONLY where saturation happened. t2_a -= (t2_a>>MAXIMO_NUM_BITS_COLOR); // 00__11__ *** 1 appears ONLY where saturation happened. t2_b -= (t2_b>>BITS_BAJOS); // 0011__11 *** 1 appears ONLY where saturation happened. t1_a |= t2_a; // 00__gS__ * S means Saturated t1_b |= t2_b; // 00rS__bS // Comoposicion: return(t1_a | t1_b); } //---------------------------------------------------------------------- // Use: Adds two 565 colours TWICE with saturation and no lose. // Returns: The two added colours. // Parameters: Four 565 colours, The first parameter colurs are added to the second parameter colours.. //---------------------------------------------------------------------- __inline unsigned GE_AddColors565Twice( const unsigned c1, const unsigned c2) { // Separacion: // SetUp: unsigned t1_a = (c1 & MASCARA_A_TWICE) >> BITS_BAJOS; // __R1__B1__g1 unsigned t2_a = (c2 & MASCARA_A_TWICE) >> BITS_BAJOS; // __R2__B2__g2 unsigned t1_b = (c1 & MASCARA_B_TWICE) << (MAXIMO_NUM_BITS_COLOR-BITS_BAJOS); // __G1__r1__b1 unsigned t2_b = (c2 & MASCARA_B_TWICE) << (MAXIMO_NUM_BITS_COLOR-BITS_BAJOS); // __G2__r2__b2 // Suma_A: // Suma_B: t1_a = t2_a = t1_a + t2_a; // __RT__BT__gT * T means Total t1_b = t2_b = t1_b + t2_b; // __GT__rT__bT t2_a &= MASCARA_SAT_A_TWICE; // _1___1___1__ *** 1 appears ONLY where saturation happened. t2_b &= MASCARA_SAT_B_TWICE; // _1___1___1__ *** 1 appears ONLY where saturation happened. t2_a -= (t2_a>>MAXIMO_NUM_BITS_COLOR); // __11__11__11 *** 1 appears ONLY where saturation happened. t2_b -= (t2_b>>MAXIMO_NUM_BITS_COLOR); // __11__11__11 *** 1 appears ONLY where saturation happened. t1_a |= t2_a; // __RSxxBSxxgS * S means Saturated t1_b |= t2_b; // __GSxxrSxxbS * xx Garbage that appeared betwen the color components. t1_a = (t1_a<>MAXIMO_NUM_BITS_COLOR-BITS_BAJOS) & (MASCARA_B_TWICE); // 11xx11xx11xx * Moves all to its correct place. // __11__11__11 * Cleans the space betwen components. // Comoposicion: return(t1_a | t1_b); } //---------------------------------------------------------------------- // Use: Subs two 565 colours with saturation and no lose. // Returns: The Sub colour. // Parameters: Two colours. //---------------------------------------------------------------------- __inline unsigned GE_SubColors565( unsigned c1, const unsigned c2) { // Separacion: unsigned t1_a = (c1 & MASCARA_A) | MASCARA_SAT_A; // 0000_1g1__ // I set the bit so later I can check underflow. unsigned t2_a = (c2 & MASCARA_A); // 0000__g2__ unsigned t1_b = (c1 & MASCARA_B) | MASCARA_SAT_B; // 0001r1_1b1 // I set the bit so later I can check underflow. unsigned t2_b = (c2 & MASCARA_B); // 0000r2__b2 // Resta_A: // Resta_B: t1_a = t2_a = (t1_a - t2_a); // 00__gT__ * T means Total t1_b = t2_b = (t1_b - t2_b); // 00rT__bT t2_a &= (MASCARA_SAT_A); // 00_1____ I test sign change. t2_b &= (MASCARA_SAT_B); // 01___1__ 1 appears ONLY where no underflow happened. t2_a -= (t2_a>>MAXIMO_NUM_BITS_COLOR); // 00__11__ I create the 1filled mask on the colours the didn't underflow. t2_b -= (t2_b>>BITS_BAJOS); // 0011__11 t1_a &= t2_a; // 00__gU__ * U means UnderFlow t1_b &= t2_b; // 00rU__bU // Comoposicion: return(t1_a | t1_b); } //---------------------------------------------------------------------- // Use: Subs two 565 colours TWICE with saturation and no lose. // Returns: The two added colours. // Parameters: Four 565 colours, The second parameter colurs are sub from the first parameter colours.. //---------------------------------------------------------------------- __inline unsigned GE_SubColors565Twice( unsigned c1, const unsigned c2) { // Separacion: // SetUp: unsigned t1_a = ((c1 & MASCARA_A_TWICE) >> BITS_BAJOS) | MASCARA_SAT_A_TWICE; // _1R1_1B1_1g1 unsigned t2_a = ((c2 & MASCARA_A_TWICE) >> BITS_BAJOS); // __R2__B2__g2 unsigned t1_b = ((c1 & MASCARA_B_TWICE) << (MAXIMO_NUM_BITS_COLOR-BITS_BAJOS)) | MASCARA_SAT_B_TWICE; // _1G1_1r1_1b1 unsigned t2_b = ((c2 & MASCARA_B_TWICE) << (MAXIMO_NUM_BITS_COLOR-BITS_BAJOS)); // __G2__r2__b2 // Suma_A: // Suma_B: t1_a = t2_a = t1_a - t2_a; // __RT__BT__gT * T means Total t1_b = t2_b = t1_b - t2_b; // __GT__rT__bT t2_a &= MASCARA_SAT_A_TWICE; // _1___1___1__ *** 1 appears ONLY where no underflow happened. t2_b &= MASCARA_SAT_B_TWICE; // _1___1___1__ *** 1 appears ONLY where no underflow happened. t2_a -= (t2_a>>MAXIMO_NUM_BITS_COLOR); // __11__11__11 *** 1 appears ONLY where no underflow happened. t2_b -= (t2_b>>MAXIMO_NUM_BITS_COLOR); // __11__11__11 *** 1 appears ONLY where no underflow happened. t1_a &= t2_a; // __RUxxBUxxgU * U means Underflow t1_b &= t2_b; // __GUxxrSxxbU * xx Garbage that appeared betwen the color components. t1_a = (t1_a<>MAXIMO_NUM_BITS_COLOR-BITS_BAJOS) & (MASCARA_B_TWICE); // 11xx11xx11xx * Moves all to its correct place. // __11__11__11 * Cleans the space betwen components. // Comoposicion: return(t1_a | t1_b); } //---------------------------------------------------------------------- // Use: Make a 32 levels alfa blend betwen two 565 colours. // Returns: The blended colour. // Parameters: iAlfa=0 Only c1 is set, iAlfa=32 only c2 is set //---------------------------------------------------------------------- __inline unsigned GE_BlendColors565( const unsigned c1, const unsigned c2, int iAlfa) { unsigned ta = c1 & MASCARA_A; // 0000__g1__ unsigned tb = c2 & MASCARA_B; // 0000r2__b2 ta *= (32-iAlfa); tb *= ( iAlfa); ta += ( iAlfa) *(c2 & MASCARA_A); // 0000__g2__ tb += (32-iAlfa) *(c1 & MASCARA_B); // 0000r1__b1 ta = (ta>>BITS_BAJOS) & MASCARA_A; ta += (tb>>BITS_BAJOS) & MASCARA_B; return(ta); } //---------------------------------------------------------------------- // Use: Make a 32 levels alfa blend betwen two 565 colours TWICE // Returns: The two blended colours. // Parameters: iAlfa=0 Only c1 is set, iAlfa=32 only c2 is set // c1; two 565 Colours thar will blend with c2 that contains anothe two 565 colours. //---------------------------------------------------------------------- __inline unsigned GE_BlendColors565Twice( const unsigned c1, const unsigned c2, int iAlfa) { unsigned ta = (c1 & MASCARA_A_TWICE)>>BITS_BAJOS; // __R1__B1__g1 unsigned tb = (c1 & MASCARA_B_TWICE); // __G1__r1__b1 ta *= (32-iAlfa); tb *= (32-iAlfa); ta += iAlfa *((c2 & MASCARA_A_TWICE)>>(BITS_BAJOS)); // __R2__B2__g2 tb += iAlfa * (c2 & MASCARA_B_TWICE); // __G2__r2__b2 ta &= MASCARA_A_TWICE; // R2__B2__g2__ ta += (tb>>BITS_BAJOS) & MASCARA_B_TWICE; // __G2__r2__b2 return(ta); }