Allow WinBoard to use bitmaps with alpha channel
[xboard.git] / winboard / winboard.c
index 96bebcb..293b643 100644 (file)
  *------------------------------------------------------------------------\r
  ** See the file ChangeLog for a revision history.  */\r
 \r
+#ifndef WINVER\r
+#define WINVER 0x0500\r
+#endif\r
+\r
 #include "config.h"\r
 \r
 #include <windows.h>\r
@@ -2193,7 +2197,7 @@ void CreatePiecesFromFont()
 HBITMAP\r
 DoLoadBitmap(HINSTANCE hinst, char *piece, int squareSize, char *suffix)\r
 {\r
-  char name[128], buf[MSG_SIZ];\r
+  char name[128], buf[MSG_SIZ], *ids = "pnbrqfeicwmohajgdvlsukaacvdklnwpwnwlwswolfgnuzebracameltowersword", *p;\r
 \r
     snprintf(name, sizeof(name)/sizeof(name[0]), "%s%d%s", piece, squareSize, suffix);\r
   if(appData.pieceDirectory[0]) {\r
@@ -2201,6 +2205,30 @@ DoLoadBitmap(HINSTANCE hinst, char *piece, int squareSize, char *suffix)
     snprintf(buf, MSG_SIZ, "%s\\%s.bmp", appData.pieceDirectory, name);\r
     res = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
     if(res) return res;\r
+    p = strstr(ids, piece);\r
+    if(p) { // if we could reconstruct canonical piece number, try the pieceNNN_ format before falling back on built-ins\r
+      int n = p - ids;\r
+      switch(n) {\r
+       case 21: n = WhiteKing; break;\r
+       case 22: n = WhiteAngel; break;\r
+       case 24: n = WhiteSilver; break;\r
+       case 26: n = WhiteDragon; break;\r
+       case 28: n = WhiteLion; break;\r
+       case 30: n = WhiteTokin; break;\r
+       case 32: n = WhitePKnight; break;\r
+       case 34: n = WhitePLance; break;\r
+       case 36: n = WhitePSilver; break;\r
+       case 38: n = WhiteWolf; break;\r
+       case 42: n = WhiteGnu; break;\r
+       case 45: n = WhiteZebra; break;\r
+       case 50: n = WhiteCamel; break;\r
+       case 55: n = WhiteTower; break;\r
+       case 60: n = WhiteSword; break;\r
+      }\r
+      snprintf(buf, MSG_SIZ, "%s\\piece%d_%d%s.bmp", appData.pieceDirectory, n, squareSize, suffix);\r
+      res = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+      if(res) return res;\r
+    }\r
   }\r
   if (gameInfo.event &&\r
       strcmp(gameInfo.event, "Easter Egg Hunt") == 0 &&\r
@@ -2992,7 +3020,7 @@ VOID
 DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, HDC tmphdc)\r
 {\r
   HBITMAP oldBitmap;\r
-  HBRUSH oldBrush;\r
+  HBRUSH oldBrush = NULL;\r
   int tmpSize;\r
 \r
   if (appData.blindfold) return;\r
@@ -3051,6 +3079,20 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y,
       y += squareSize - minorSize - 2;\r
       tmpSize = minorSize;\r
     }\r
+#if WINVER >= 0x0500\r
+    HBITMAP pbm = PieceBitmap(piece, color ? OUTLINE_PIECE : SOLID_PIECE);\r
+    BITMAP b;\r
+    GetObject(pbm, sizeof(BITMAP), &b);\r
+    if(b.bmBitsPixel == 32) { // for now this is a kludge to indicate bitmaps with alpha channel\r
+       BLENDFUNCTION bf;\r
+       bf.BlendOp = AC_SRC_OVER;\r
+       bf.BlendFlags = 0;\r
+       bf.SourceConstantAlpha = 0xFF;\r
+       bf.AlphaFormat = AC_SRC_ALPHA;\r
+       oldBitmap = SelectObject(tmphdc, pbm);\r
+       AlphaBlend(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, bf);\r
+    } else\r
+#endif\r
     if (color || appData.allWhite ) {\r
       oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, WHITE_PIECE));\r
       if( color )\r
@@ -3087,7 +3129,7 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y,
       else\r
         BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A);\r
     }\r
-    SelectObject(hdc, oldBrush);\r
+    if(oldBrush) SelectObject(hdc, oldBrush);\r
     SelectObject(tmphdc, oldBitmap);\r
   }\r
 }\r