imported catch-22 sol clone with authors permission
[reactos.git] / rosapps / games / solitaire / cardlib / cardcolor.cpp
diff --git a/rosapps/games/solitaire/cardlib/cardcolor.cpp b/rosapps/games/solitaire/cardlib/cardcolor.cpp
new file mode 100644 (file)
index 0000000..f82c9fa
--- /dev/null
@@ -0,0 +1,353 @@
+//\r
+//     Colour support\r
+//\r
+#include <windows.h>\r
+\r
+#define MakeRGB RGB\r
+\r
+#define MIN3(a,b,c) ( (a)<=(b) ? (a)<=(c)?(a):(c) : (b)<=(c)?(b):(c) )\r
+#define MAX3(a,b,c) ( (a)>=(b) ? (a)>=(c)?(a):(c) : (b)>=(c)?(b):(c) )\r
+\r
+inline double fMax(double a, double b)\r
+{\r
+       return a < b ? b : a;\r
+}\r
+\r
+inline double fMin(double a, double b)\r
+{\r
+       return a < b ? a : b;\r
+}\r
+/******************************************************************************\r
+  FUNCTION: RGBtoHLS\r
+  PURPOSE:     Convert from RGB to HLS\r
+  IN: RGB color (0xBBGGRR)\r
+  OUT: Hue, Saturation, Luminance from 0 to 1\r
+  COPYRIGHT:1995-1997 Robert Mashlan\r
+            Modified for LabWindows/CVI, 1999 Guillaume Dargaud\r
+******************************************************************************/\r
+void RGBtoHLS(const COLORREF rgb, double *H, double *L, double *S ) \r
+{\r
+       double delta;\r
+       double r = (double)((rgb    )&0xFF)/255;\r
+       double g = (double)((rgb>> 8)&0xFF)/255;\r
+       double b = (double)((rgb>>16)&0xFF)/255;\r
+       double cmax = MAX3(r,g,b);\r
+       double cmin = MIN3(r,g,b);\r
+       *L=(cmax+cmin)/2.0;\r
+       \r
+       if(cmax == cmin) \r
+       {\r
+               *S = *H = 0; // it's really undefined\r
+       }\r
+       else \r
+       {\r
+               if(*L < 0.5)    *S = (cmax-cmin)/(cmax+cmin);\r
+               else                    *S = (cmax-cmin)/(2.0-cmax-cmin);\r
+               \r
+               delta = cmax - cmin;\r
+               \r
+               if(r == cmax) \r
+               {\r
+                       *H = (g - b) / delta;\r
+               }\r
+               else\r
+               {\r
+                       if(g == cmax) *H = 2.0 + (b-r) / delta;\r
+                       else          *H = 4.0 + (r-g) / delta;\r
+               }\r
+               *H /= 6.0;\r
+               if (*H < 0.0) *H += 1;\r
+       }\r
+}\r
+\r
+/******************************************************************************\r
+  FUNCTION: HueToRGB\r
+  PURPOSE:     Convert a hue (color) to RGB\r
+  COPYRIGHT:1995-1997 Robert Mashlan\r
+            Modified for LabWindows/CVI, 1999 Guillaume Dargaud\r
+******************************************************************************/\r
+double HueToRGB(const double m1, const double m2, double h ) \r
+{\r
+       if (h<0) h+=1.0;\r
+       if (h>1) h-=1.0;\r
+       if (6.0*h < 1  ) return (m1+(m2-m1)*h*6.0);\r
+       if (2.0*h < 1  ) return m2;\r
+       if (3.0*h < 2.0) return (m1+(m2-m1)*((2.0/3.0)-h)*6.0);\r
+       return m1;\r
+}\r
+\r
+\r
+/******************************************************************************\r
+  FUNCTION: HLStoRGB\r
+  PURPOSE:     Convert from HSL to RGB\r
+  IN:          Hue, Saturation, Luminance from 0 to 1\r
+  RETURN:      RGB color (0xBBGGRR)\r
+  COPYRIGHT:1995-1997 Robert Mashlan\r
+            Modified for LabWindows/CVI, 1999 Guillaume Dargaud\r
+******************************************************************************/\r
+\r
+COLORREF HLStoRGB(const double H, const double L, const double S ) \r
+{\r
+       double r,g,b;\r
+       double m1, m2;\r
+\r
+       if(S == 0) \r
+       {\r
+               r = g = b = L;\r
+       }\r
+       else \r
+       {\r
+               if (L <= 0.5) \r
+                       m2 = L * (1.0 + S);\r
+               else         \r
+                       m2 = L + S - L * S;\r
+\r
+               m1 = 2.0 * L - m2;\r
+\r
+               r = HueToRGB(m1,m2,H+1.0/3.0);\r
+               g = HueToRGB(m1,m2,H);\r
+               b = HueToRGB(m1,m2,H-1.0/3.0);\r
+       }\r
+  \r
+       return RGB(r*255, g*255, b*255);\r
+}\r
+\r
+\r
+\r
+/******************************************************************************\r
+  FUNCTION: ColorScaleHSL\r
+  PURPOSE:     Returns the HSL linear interpolated color between 2 colors\r
+                       (more natural looking than RGB interpolation)\r
+               For instance if the luminance is the same in Col1 and Col2, \r
+                       then the luminance of the result will be the same\r
+               If Ratio=0, you get Col1,\r
+                       If Ratio=1, you get Col2\r
+  IN: Col1: low color in hex 0xBBGGRR format\r
+         Col2: high color in hex 0xBBGGRR format\r
+         Ratio: 0 for low color, 1 for high color, or in between\r
+  EXAMPLE: Col1=0, Col2=0xFF00FF, Ratio=0.5 returns 0x1F5F3F\r
+******************************************************************************/\r
+COLORREF ColorScaleHSL(        const COLORREF Col1, const COLORREF Col2, const double Ratio) \r
+{\r
+       static double H1, H2, S1, S2, L1, L2;\r
+       \r
+       if (Ratio<=0) return Col1;      // Ratio parameter must be between 0 and 1\r
+       else if (Ratio>=1) return Col2;\r
+\r
+       RGBtoHLS( Col1, &H1, &L1, &S1);\r
+       RGBtoHLS( Col2, &H2, &L2, &S2);\r
+       return HLStoRGB( H1+(H2-H1)*Ratio, L1+(L2-L1)*Ratio, S1+(S2-S1)*Ratio );\r
+}\r
+\r
+\r
+/******************************************************************************\r
+  FUNCTION: ColorScaleRGB\r
+  PURPOSE:     Returns the RGB linear interpolated color between 2 colors\r
+               If Ratio=0, you get Col1,\r
+                       If Ratio=1, you get Col2\r
+  IN: Col1: low color in hex 0xBBGGRR format\r
+         Col2: high color in hex 0xBBGGRR format\r
+         Ratio: 0 for low color, 1 for high color, or in between\r
+  EXAMPLE: Col1=0, Col2=0xFF00FF, Ratio=0.5 returns 0x800080\r
+******************************************************************************/\r
+COLORREF ColorScaleRGB(        const COLORREF Col1, \r
+                                               const COLORREF Col2, \r
+                                               const double Ratio) {\r
+       int R1=(Col1)&0xFF, G1=(Col1>>8)&0xFF, B1=(Col1>>16)&0xFF;\r
+       int R2=(Col2)&0xFF, G2=(Col2>>8)&0xFF, B2=(Col2>>16)&0xFF;\r
+\r
+       if (Ratio<=0) return Col1;      // Ratio parameter must be between 0 and 1\r
+       else if (Ratio>=1) return Col2;\r
+\r
+/*     return RGB(\r
+                      (R1 + (R2 - R1) * (Ratio + 0.02) + 0.5),         // rounding\r
+                          (G1 + (G2 - G1) * (Ratio - 0.00) + 0.5),\r
+                          (B1 + (B2 - B1) * (Ratio + 0.05) + 0.5)\r
+                          );*/\r
+\r
+       /*double r = Ratio;\r
+       if(Col2 == 0)\r
+               r = 1-Ratio;\r
+       else\r
+               r = 1+Ratio;\r
+       R1 = (int)(double(R1) * r + 0.5);\r
+       G1 = (int)(double(G1) * r + 0.5);\r
+       B1 = (int)(double(B1) * r + 0.5);\r
+       return RGB(R1,G1,B1);*/\r
+\r
+       return RGB(\r
+                          (R1 + (R2 - R1) * (Ratio + 0.02) + 0.5),             // rounding\r
+                          (G1 + (G2 - G1) * (Ratio - 0.00) + 0.5),\r
+                          (B1 + (B2 - B1) * (Ratio + 0.05) + 0.5)\r
+                          );\r
+}\r
+\r
+\r
+\r
+COLORREF ColorDarker(COLORREF col, double ratio)\r
+{\r
+       static double Hue, Lum, Sat;\r
+\r
+       //RGBtoHLS(col, &Hue, &Lum, &Sat);\r
+\r
+       //col = HLStoRGB(Hue, fMax(0.0,Lum-ratio), Sat);\r
+\r
+       return ColorScaleHSL(col, RGB(0,0,0), ratio);\r
+\r
+       //return col;\r
+}\r
+\r
+COLORREF ColorLighter(COLORREF col, double ratio)\r
+{\r
+       static double Hue, Lum, Sat;\r
+\r
+       //RGBtoHLS(col, &Hue, &Lum, &Sat);\r
+\r
+       //col = HLStoRGB(Hue, fMin(1.0,Lum+ratio), Sat);\r
+\r
+       return ColorScaleHSL(col, RGB(255,255,255), ratio);\r
+\r
+       //return col;\r
+}\r
+\r
+//\r
+//     Experimental!!!\r
+//\r
+#if 0\r
+\r
+typedef enum { Red, Green, Blue };\r
+\r
+void RGBtoHLS(COLORREF rgb, double *Hue, double *Lum, double *Sat)\r
+{\r
+       double mn, mx;\r
+       int major;\r
+\r
+       BYTE red, green, blue;\r
+\r
+       red    = GetRValue(rgb);\r
+       green  = GetGValue(rgb);\r
+       blue   = GetBValue(rgb);\r
+\r
+       if(red < green)\r
+       {\r
+               mn = red; mx = green; major = Green;\r
+       }\r
+       else\r
+       {\r
+               mn = green; mx = red; major = Red;\r
+       }\r
+\r
+       if(blue < mn)\r
+       {\r
+               mn = blue;\r
+       }\r
+       else if(blue > mx)\r
+       {\r
+               mx = blue; major = Blue;\r
+       }\r
+\r
+       if(mn == mx)\r
+       {\r
+               *Lum = mn / 255;\r
+               *Sat = 0;\r
+               *Hue = 0;\r
+       }\r
+       else\r
+       {\r
+               *Lum = (mx + mn) / 510;\r
+\r
+               if(*Lum <= 0.5)\r
+                       *Sat = (mx-mn) / (mn+mx);\r
+               else\r
+                       *Sat = (mx-mn) / (510-mn-mx);\r
+\r
+               switch(major)\r
+               {\r
+               case Red:   *Hue = (green-blue) * 60.0 / (mx-mn) + 360.0;\r
+                                   break;\r
+\r
+               case Green: *Hue = (blue-red) * 60.0 / (mx-mn) + 120.0;\r
+                               break;\r
+\r
+               case Blue:  *Hue = (red-green) * 60.0 / (mx-mn) + 240.0;\r
+                               break;\r
+\r
+               }\r
+\r
+               if(*Hue > 360.0)\r
+                       *Hue -= 360.0;\r
+       }\r
+}\r
+\r
+static BYTE Value(double m1, double m2, double hue)\r
+{\r
+\r
+       if(hue > 360)           hue -= 360;\r
+       else if(hue < 0)        hue += 360;\r
+\r
+       if(hue < 60)\r
+               m1 = m1 + (m2 - m1) * hue / 60;\r
+       else if(hue < 180)\r
+               m1 = m2;\r
+       else if(hue < 240)\r
+               m1 = m1 + (m2 - m1) * (240 - hue) / 60;\r
+\r
+       return (BYTE)(m1 * 255);\r
+}\r
+\r
+COLORREF HLStoRGB(const double Hue, const double Lum, const double Sat)\r
+{\r
+       BYTE red, green, blue;\r
+\r
+       if(Sat == 0)\r
+       {\r
+               red = green = blue = (BYTE)(Lum * 255);         \r
+       }\r
+       else\r
+       {\r
+               double m1, m2;\r
+\r
+               if(Lum <= 0.5)\r
+                       m2 = Lum + Lum * Sat;\r
+               else\r
+                       m2 = Lum + Sat - Lum * Sat;\r
+\r
+               m1 = 2 * Lum - m2;\r
+\r
+               red   = Value(m1, m2, Hue + 120);\r
+               green = Value(m1, m2, Hue);\r
+               blue  = Value(m1, m2, Hue - 120);\r
+       }\r
+\r
+       return RGB(red, green, blue);\r
+}\r
+\r
+COLORREF ScaleLumRGB(COLORREF col1, double ratio)\r
+{\r
+       double H1, L1, S1;\r
+\r
+       RGBtoHLS(col1, &H1, &L1, &S1);\r
+\r
+       L1 += L1 * ratio;\r
+\r
+       return HLStoRGB(H1, L1, S1);\r
+}\r
+\r
+COLORREF ColorScaleHSL(const COLORREF Col1, const COLORREF Col2, const double Ratio) \r
+{\r
+       static double H1, H2, S1, S2, L1, L2;\r
+       \r
+       if(Ratio <= 0)          return Col1;    // Ratio parameter must be between 0 and 1\r
+       else if(Ratio >= 1)     return Col2;\r
+\r
+       RGBtoHLS( Col1, &H1, &L1, &S1);\r
+       RGBtoHLS( Col2, &H2, &L2, &S2);\r
+\r
+       return HLStoRGB( H1 /*+ (H2 - H1 ) * Ratio*/, L1 + (L2 - L1) * Ratio, S1 + (S2 - S1) * Ratio * 2);\r
+}\r
+\r
+COLORREF ColorScaleRGB(const COLORREF Col1, const COLORREF Col2, const double Ratio)\r
+{\r
+       return ColorScaleHSL(Col1, Col2, Ratio);\r
+}\r
+#endif\r