update SVN properties
authorMartin Fuchs <fuchs.martin@gmail.com>
Sun, 7 Aug 2005 07:33:14 +0000 (07:33 +0000)
committerMartin Fuchs <fuchs.martin@gmail.com>
Sun, 7 Aug 2005 07:33:14 +0000 (07:33 +0000)
svn path=/trunk/; revision=17143

69 files changed:
rosapps/games/solitaire/cardlib/card.h
rosapps/games/solitaire/cardlib/cardbitmaps.cpp
rosapps/games/solitaire/cardlib/cardbutton.cpp
rosapps/games/solitaire/cardlib/cardbutton.h
rosapps/games/solitaire/cardlib/cardcolor.cpp
rosapps/games/solitaire/cardlib/cardcolor.h
rosapps/games/solitaire/cardlib/cardcount.cpp
rosapps/games/solitaire/cardlib/cardcount.h
rosapps/games/solitaire/cardlib/cardlib.cpp
rosapps/games/solitaire/cardlib/cardlib.h
rosapps/games/solitaire/cardlib/cardregion.cpp
rosapps/games/solitaire/cardlib/cardregion.h
rosapps/games/solitaire/cardlib/cardrgndraw.cpp
rosapps/games/solitaire/cardlib/cardrgnmouse.cpp
rosapps/games/solitaire/cardlib/cardstack.cpp
rosapps/games/solitaire/cardlib/cardstack.h
rosapps/games/solitaire/cardlib/cardwindow.cpp
rosapps/games/solitaire/cardlib/cardwindow.h
rosapps/games/solitaire/cardlib/dropzone.cpp
rosapps/games/solitaire/cardlib/dropzone.h
rosapps/games/solitaire/cardlib/globals.h
rosapps/games/solitaire/solcreate.cpp
rosapps/games/solitaire/solgame.cpp
rosapps/games/solitaire/solitaire.cpp
rosapps/packmgr/cmd-line/main.c
rosapps/packmgr/cmd-line/main.h
rosapps/packmgr/gui/main.c
rosapps/packmgr/gui/main.h
rosapps/packmgr/gui/resource.h
rosapps/packmgr/lib/download.cpp
rosapps/packmgr/lib/error.h
rosapps/packmgr/lib/expat.h
rosapps/packmgr/lib/functions.cpp
rosapps/packmgr/lib/log.cpp
rosapps/packmgr/lib/log.h
rosapps/packmgr/lib/main.cpp
rosapps/packmgr/lib/options.cpp
rosapps/packmgr/lib/package.cpp
rosapps/packmgr/lib/package.h
rosapps/packmgr/lib/package.hpp
rosapps/packmgr/lib/script.cpp
rosapps/packmgr/lib/script.h
rosapps/packmgr/lib/tree.cpp
rosapps/sysutils/ctm/resource.h
rosapps/sysutils/dosfsck/boot.c
rosapps/sysutils/dosfsck/boot.h
rosapps/sysutils/dosfsck/byteorder.h
rosapps/sysutils/dosfsck/byteswap.h
rosapps/sysutils/dosfsck/byteswap1.h
rosapps/sysutils/dosfsck/check.c
rosapps/sysutils/dosfsck/check.h
rosapps/sysutils/dosfsck/common.c
rosapps/sysutils/dosfsck/common.h
rosapps/sysutils/dosfsck/compiler.h
rosapps/sysutils/dosfsck/dosfsck.c
rosapps/sysutils/dosfsck/dosfsck.h
rosapps/sysutils/dosfsck/fat.c
rosapps/sysutils/dosfsck/fat.h
rosapps/sysutils/dosfsck/file.c
rosapps/sysutils/dosfsck/file.h
rosapps/sysutils/dosfsck/io.c
rosapps/sysutils/dosfsck/io.h
rosapps/sysutils/dosfsck/lfn.c
rosapps/sysutils/dosfsck/lfn.h
rosapps/sysutils/dosfsck/msdos_fs.h
rosapps/sysutils/dosfsck/swab.h
rosapps/sysutils/dosfsck/version.h
rosapps/sysutils/dosfsck/vfat.h
rosapps/sysutils/mkdosfs/mkdosfs.c

index 13dc190..dc85896 100644 (file)
-//\r
-//     CardLib - Card class\r
-//\r
-//     Freeware\r
-//     Copyright J Brown 2001\r
-//\r
-\r
-#ifndef _CARD_INCLUDED\r
-#define _CARD_INCLUDED\r
-\r
-enum eSuit  { Clubs = 0, Diamonds = 1, Hearts = 2, Spades = 3 };\r
-enum eValue { Ace = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, \r
-              Eight = 8, Nine = 9, Ten = 10, Jack = 11, Queen = 12, King = 13 };\r
-\r
-inline int MAKE_CARD(int Value, int Suit)\r
-{\r
-       if(Value < 1)   Value = 1;\r
-       if(Value == 14) Value = 1;\r
-       if(Value >  13) Value = 13;\r
-\r
-       if(Suit < 0)    Suit = 0;\r
-       if(Suit > 3)    Suit = 3;\r
-\r
-       return ((Value - 1) * 4 + Suit);\r
-}\r
-\r
-class Card\r
-{\r
-       friend class CardStack;\r
-\r
-public:\r
-\r
-       Card() \r
-       { \r
-               nValue = 0;             //ace of spades by default\r
-               fFaceUp = true; \r
-       }\r
-       \r
-       Card(int value, int suit)       //specify a face value [1-13] and suit [0-3]\r
-       { \r
-               nValue = MAKE_CARD(value, suit);\r
-               fFaceUp = true; \r
-       }\r
-       \r
-       Card(int index)                         //specify a 0-51 index\r
-       { \r
-               if(index < 0)  index = 0;\r
-               if(index > 51) index = 51;\r
-\r
-               nValue = index; \r
-               fFaceUp = true;\r
-       }\r
-       \r
-       int Suit() const\r
-       { \r
-               return (nValue % 4); \r
-       }\r
-\r
-       int LoVal() const\r
-       { \r
-               return (nValue / 4) + 1; \r
-       }\r
-\r
-       int HiVal() const\r
-       { \r
-               return ((nValue < 4) ? 14 : (nValue / 4) + 1); \r
-       }\r
-\r
-       int Idx() const //unique value (0-51 etc)\r
-       {\r
-               return nValue;\r
-       }\r
-\r
-       bool FaceUp() const\r
-       {\r
-               return fFaceUp;\r
-       }\r
-       \r
-       bool FaceDown() const\r
-       {\r
-               return !fFaceUp;\r
-       }\r
-\r
-       void SetFaceUp(bool fTrue)\r
-       {\r
-               fFaceUp = fTrue;\r
-       }\r
-\r
-       bool IsBlack() const\r
-       {\r
-               return Suit() == 0 || Suit() == 3;\r
-       }\r
-\r
-       bool IsRed() const\r
-       {\r
-               return !IsBlack();\r
-       }\r
-\r
-private:\r
-\r
-       int  nValue;\r
-       bool fFaceUp;\r
-};\r
-\r
-#endif\r
+//
+//     CardLib - Card class
+//
+//     Freeware
+//     Copyright J Brown 2001
+//
+
+#ifndef _CARD_INCLUDED
+#define _CARD_INCLUDED
+
+enum eSuit  { Clubs = 0, Diamonds = 1, Hearts = 2, Spades = 3 };
+enum eValue { Ace = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, 
+              Eight = 8, Nine = 9, Ten = 10, Jack = 11, Queen = 12, King = 13 };
+
+inline int MAKE_CARD(int Value, int Suit)
+{
+       if(Value < 1)   Value = 1;
+       if(Value == 14) Value = 1;
+       if(Value >  13) Value = 13;
+
+       if(Suit < 0)    Suit = 0;
+       if(Suit > 3)    Suit = 3;
+
+       return ((Value - 1) * 4 + Suit);
+}
+
+class Card
+{
+       friend class CardStack;
+
+public:
+
+       Card() 
+       { 
+               nValue = 0;             //ace of spades by default
+               fFaceUp = true; 
+       }
+       
+       Card(int value, int suit)       //specify a face value [1-13] and suit [0-3]
+       { 
+               nValue = MAKE_CARD(value, suit);
+               fFaceUp = true; 
+       }
+       
+       Card(int index)                         //specify a 0-51 index
+       { 
+               if(index < 0)  index = 0;
+               if(index > 51) index = 51;
+
+               nValue = index; 
+               fFaceUp = true;
+       }
+       
+       int Suit() const
+       { 
+               return (nValue % 4); 
+       }
+
+       int LoVal() const
+       { 
+               return (nValue / 4) + 1; 
+       }
+
+       int HiVal() const
+       { 
+               return ((nValue < 4) ? 14 : (nValue / 4) + 1); 
+       }
+
+       int Idx() const //unique value (0-51 etc)
+       {
+               return nValue;
+       }
+
+       bool FaceUp() const
+       {
+               return fFaceUp;
+       }
+       
+       bool FaceDown() const
+       {
+               return !fFaceUp;
+       }
+
+       void SetFaceUp(bool fTrue)
+       {
+               fFaceUp = fTrue;
+       }
+
+       bool IsBlack() const
+       {
+               return Suit() == 0 || Suit() == 3;
+       }
+
+       bool IsRed() const
+       {
+               return !IsBlack();
+       }
+
+private:
+
+       int  nValue;
+       bool fFaceUp;
+};
+
+#endif
index 2611fa0..5b32ae4 100644 (file)
-//\r
-//    CardLib - Card bitmap support\r
-//\r
-//    Freeware\r
-//    Copyright J Brown 2001\r
-//\r
-#include <windows.h>\r
-#include "globals.h"\r
-#include "cardcolor.h"\r
-\r
-#ifndef __REACTOS__\r
-#pragma comment( lib, "..\\CardLib\\cards16.lib" )\r
-\r
-extern "C" HINSTANCE WINAPI LoadLibrary16( PSTR );\r
-extern "C" void         WINAPI FreeLibrary16( HINSTANCE );\r
-#endif\r
-\r
-#define NUMCARDBITMAPS (52+16)\r
-\r
-void PaintRect(HDC hdc, RECT *rect, COLORREF col);\r
-\r
-void LoadCardBitmapsFromLibrary(HINSTANCE hCardDll, int *pwidth, int *pheight)\r
-{\r
-    HBITMAP   hBitmap;\r
-    HDC          hdcCard = NULL;\r
-    HANDLE      hOld;\r
-    int        i, xpos;\r
-    int        width, height;\r
-    BITMAP bmp;\r
-\r
-    for(i = 0; i < NUMCARDBITMAPS; i++)\r
-    {\r
-        //convert into the range used by the cdt_xxx functions\r
-        int val;\r
-        \r
-        if(i < 52) val = (i % 4) * 13 + (i/4);\r
-        else       val = i;\r
-        \r
-        hBitmap = LoadBitmap(hCardDll, MAKEINTRESOURCE(val + 1));\r
-        GetObject(hBitmap, sizeof(bmp), &bmp);\r
-        \r
-        width  = bmp.bmWidth;\r
-        height = bmp.bmHeight;\r
-\r
-        if(i == 0)    //if first time through, create BIG bitmap..\r
-        {\r
-            HDC hdc = GetDC(0);\r
-            __hdcCardBitmaps = CreateCompatibleDC(hdc);\r
-            __hbmCardBitmaps = CreateCompatibleBitmap(hdc, width * NUMCARDBITMAPS, height);\r
-            SelectObject(__hdcCardBitmaps, __hbmCardBitmaps);\r
-\r
-            hdcCard = CreateCompatibleDC(0);\r
-\r
-            ReleaseDC(0, hdc);\r
-        }\r
-        \r
-        hOld = SelectObject(hdcCard, hBitmap);\r
-        BitBlt(__hdcCardBitmaps, i*width, 0, width, height, hdcCard, 0, 0, SRCCOPY);\r
-        SelectObject(hdcCard, hOld);\r
-        \r
-        //Now draw a black border around each card...\r
-        xpos = i*width;\r
-        MoveToEx(__hdcCardBitmaps, xpos+2, 0, 0);\r
-        LineTo(__hdcCardBitmaps, xpos+width - 3, 0);\r
-        LineTo(__hdcCardBitmaps, xpos+width - 1, 2);\r
-        LineTo(__hdcCardBitmaps, xpos+width - 1, height - 3);    //vertical\r
-        LineTo(__hdcCardBitmaps, xpos+width - 3, height - 1);\r
-        LineTo(__hdcCardBitmaps, xpos+2, height - 1);\r
-        LineTo(__hdcCardBitmaps, xpos+0, height - 3);\r
-        LineTo(__hdcCardBitmaps, xpos+0, 2);\r
-        LineTo(__hdcCardBitmaps, xpos+2, 0);\r
-        \r
-        DeleteObject(hBitmap);\r
-    }\r
-    \r
-    DeleteDC(hdcCard);\r
-\r
-    *pwidth = width;\r
-    *pheight = height;\r
-                \r
-}\r
-\r
-void LoadCardBitmaps(void)\r
-{\r
-    HINSTANCE hCardDll;\r
-    \r
-\r
-    //If Windows NT/2000/XP\r
-    if(GetVersion() < 0x80000000)\r
-    {\r
-        hCardDll = LoadLibrary("cards.dll");\r
-\r
-        if(hCardDll == 0)\r
-        {\r
-            MessageBox(0, "Error loading cards.dll (32bit)", "Shed", MB_OK | MB_ICONEXCLAMATION);\r
-            PostQuitMessage(0);\r
-            return;\r
-        }\r
-        \r
-        LoadCardBitmapsFromLibrary(hCardDll, &__cardwidth, &__cardheight);\r
-        \r
-        FreeLibrary(hCardDll);\r
-    }\r
-#ifndef __REACTOS__\r
-    //Else, Win9X\r
-    else\r
-    {\r
-        hCardDll = LoadLibrary16("cards.dll");\r
-\r
-        if(hCardDll == 0)\r
-        {\r
-            MessageBox(0, "Error loading cards.dll (16bit)", "Shed", MB_OK | MB_ICONEXCLAMATION);\r
-            PostQuitMessage(0);\r
-            return;\r
-        }\r
-\r
-        LoadCardBitmapsFromLibrary(hCardDll, &__cardwidth, &__cardheight);\r
-\r
-        FreeLibrary16(hCardDll);\r
-    }\r
-#endif\r
-}\r
-\r
-void FreeCardBitmaps()\r
-{\r
-    DeleteObject (__hbmCardBitmaps);\r
-    DeleteDC     (__hdcCardBitmaps);\r
-}\r
-//\r
-//    Paint a checkered rectangle, with each alternate\r
-//    pixel being assigned a different colour\r
-//\r
-static void DrawCheckedRect(HDC hdc, RECT *rect, COLORREF fg, COLORREF bg)\r
-{\r
-    static WORD wCheckPat[8] = \r
-    { \r
-        0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555 \r
-    };\r
-\r
-    HBITMAP hbmp;\r
-    HBRUSH  hbr, hbrold;\r
-    COLORREF fgold, bgold;\r
-\r
-    hbmp = CreateBitmap(8, 8, 1, 1, wCheckPat);\r
-    hbr  = CreatePatternBrush(hbmp);\r
-\r
-    //UnrealizeObject(hbr);\r
-\r
-    SetBrushOrgEx(hdc, rect->left, rect->top, 0);\r
-\r
-    hbrold = (HBRUSH)SelectObject(hdc, hbr);\r
-\r
-    fgold = SetTextColor(hdc, fg);\r
-    bgold = SetBkColor(hdc, bg);\r
-    \r
-    PatBlt(hdc, rect->left, rect->top, \r
-                rect->right - rect->left, \r
-                rect->bottom - rect->top, \r
-                PATCOPY);\r
-    \r
-    SetBkColor(hdc, bgold);\r
-    SetTextColor(hdc, fgold);\r
-    \r
-    SelectObject(hdc, hbrold);\r
-    DeleteObject(hbr);\r
-    DeleteObject(hbmp);\r
-}\r
-\r
-void GetSinkCols(COLORREF crBase, COLORREF *fg, COLORREF *bg, COLORREF *sh1, COLORREF *sh2)\r
-{\r
-    if(bg) *bg     = crBase;\r
-    if(fg) *fg   = ColorScaleRGB(crBase, RGB(255,255,255), 0.2);//RGB(49, 99, 140);\r
-    if(sh1) *sh1 = ColorScaleRGB(crBase, RGB(0,0,0), 0.4);\r
-    if(sh2) *sh2 = ColorScaleRGB(crBase, RGB(0,0,0), 0.2);\r
-}\r
-\r
-HBITMAP CreateSinkBmp(HDC hdcCompat, HDC hdc, COLORREF col, int width, int height)\r
-{\r
-    HANDLE hold, hpold;\r
-    HBITMAP hbm = CreateCompatibleBitmap(hdcCompat, width, height);\r
-\r
-    HPEN hpfg, hpbg, hpsh, hpsh2;\r
-\r
-    RECT rect;\r
-    COLORREF fg, bg, shadow, shadow2;\r
-\r
-    GetSinkCols(col, &fg, &bg, &shadow, &shadow2);\r
-\r
-    hold = SelectObject(hdc, hbm);\r
-\r
-    //fill with a solid base colour\r
-    SetRect(&rect, 0,0,width,height);\r
-    PaintRect(hdc, &rect, MAKE_PALETTERGB(bg));\r
-\r
-    //draw the outline\r
-    hpfg = CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(fg));\r
-    hpbg = CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(bg));\r
-    hpsh = CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(shadow));\r
-    hpsh2= CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(shadow2));    \r
-\r
-    hpold = SelectObject(hdc, hpsh);\r
-    MoveToEx(hdc, 2, 0, NULL);\r
-    LineTo  (hdc, width-3,0);\r
-    LineTo  (hdc, width-1, 2);\r
-    \r
-    SelectObject(hdc, hpold);\r
-    hpold = SelectObject(hdc, hpsh2);\r
-    LineTo  (hdc, width-1, height-3);    //vertical\r
-    LineTo  (hdc, width-3, height-1);\r
-    LineTo  (hdc, 2, height-1);\r
-    LineTo  (hdc, 0, height-3);\r
-    SelectObject(hdc, hpold);\r
-    hpold = SelectObject(hdc, hpsh);\r
-\r
-    //MoveToEx( hdc, 0, height-3,0);\r
-    LineTo  (hdc, 0, 2);\r
-    LineTo  (hdc, 2, 0);\r
-\r
-    SelectObject(hdc, hpold);\r
-\r
-    //draw the highlight (vertical)\r
-    hpold = SelectObject(hdc, hpfg);\r
-    MoveToEx(hdc, width - 2, 3, NULL);\r
-    LineTo  (hdc, width - 2, height - 2);\r
-    \r
-    //(horz)\r
-    MoveToEx(hdc, width - 3, height-2, NULL);\r
-    LineTo  (hdc, 3, height-2);\r
-    SelectObject(hdc, hpold);\r
-    \r
-    //draw the background\r
-    InflateRect(&rect, -2, -2);\r
-    DrawCheckedRect(hdc, &rect, MAKE_PALETTERGB(bg), MAKE_PALETTERGB(fg));\r
-\r
-    //overwrite the top-left background pixel\r
-    SetPixel(hdc, 2, 2, MAKE_PALETTERGB(bg));\r
-\r
-    DeleteObject(hpsh);\r
-    DeleteObject(hpsh2);\r
-    DeleteObject(hpfg);\r
-    DeleteObject(hpbg);\r
-\r
-    \r
-    return hbm;\r
-}\r
-\r
-\r
-\r
-void CopyColor(PALETTEENTRY *pe, COLORREF col)\r
-{\r
-    pe->peBlue  = GetBValue(col);\r
-    pe->peGreen = GetGValue(col);\r
-    pe->peRed   = GetRValue(col);\r
-    pe->peFlags = 0;\r
-}\r
-\r
-HPALETTE MakePaletteFromCols(COLORREF cols[], int nNumColours)\r
-{\r
-    LOGPALETTE    *lp;\r
-    HPALETTE    hPalette;\r
-\r
-    //    Allocate memory for the logical palette\r
-    lp = (LOGPALETTE *)HeapAlloc(\r
-        GetProcessHeap(), 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * nNumColours);\r
-\r
-    lp->palNumEntries = nNumColours;\r
-    lp->palVersion    = 0x300;\r
-\r
-    //copy the colours into the logical palette format\r
-    for(int i = 0; i < nNumColours; i++)\r
-    {\r
-        CopyColor(&lp->palPalEntry[i], cols[i]);\r
-    }\r
-\r
-    // create palette!\r
-    hPalette = CreatePalette(lp);\r
-\r
-    HeapFree(GetProcessHeap(), 0, lp);\r
-\r
-    return hPalette;\r
-}\r
+//
+//    CardLib - Card bitmap support
+//
+//    Freeware
+//    Copyright J Brown 2001
+//
+#include <windows.h>
+#include "globals.h"
+#include "cardcolor.h"
+
+#ifndef __REACTOS__
+#pragma comment( lib, "..\\CardLib\\cards16.lib" )
+
+extern "C" HINSTANCE WINAPI LoadLibrary16( PSTR );
+extern "C" void         WINAPI FreeLibrary16( HINSTANCE );
+#endif
+
+#define NUMCARDBITMAPS (52+16)
+
+void PaintRect(HDC hdc, RECT *rect, COLORREF col);
+
+void LoadCardBitmapsFromLibrary(HINSTANCE hCardDll, int *pwidth, int *pheight)
+{
+    HBITMAP   hBitmap;
+    HDC          hdcCard = NULL;
+    HANDLE      hOld;
+    int        i, xpos;
+    int        width, height;
+    BITMAP bmp;
+
+    for(i = 0; i < NUMCARDBITMAPS; i++)
+    {
+        //convert into the range used by the cdt_xxx functions
+        int val;
+        
+        if(i < 52) val = (i % 4) * 13 + (i/4);
+        else       val = i;
+        
+        hBitmap = LoadBitmap(hCardDll, MAKEINTRESOURCE(val + 1));
+        GetObject(hBitmap, sizeof(bmp), &bmp);
+        
+        width  = bmp.bmWidth;
+        height = bmp.bmHeight;
+
+        if(i == 0)    //if first time through, create BIG bitmap..
+        {
+            HDC hdc = GetDC(0);
+            __hdcCardBitmaps = CreateCompatibleDC(hdc);
+            __hbmCardBitmaps = CreateCompatibleBitmap(hdc, width * NUMCARDBITMAPS, height);
+            SelectObject(__hdcCardBitmaps, __hbmCardBitmaps);
+
+            hdcCard = CreateCompatibleDC(0);
+
+            ReleaseDC(0, hdc);
+        }
+        
+        hOld = SelectObject(hdcCard, hBitmap);
+        BitBlt(__hdcCardBitmaps, i*width, 0, width, height, hdcCard, 0, 0, SRCCOPY);
+        SelectObject(hdcCard, hOld);
+        
+        //Now draw a black border around each card...
+        xpos = i*width;
+        MoveToEx(__hdcCardBitmaps, xpos+2, 0, 0);
+        LineTo(__hdcCardBitmaps, xpos+width - 3, 0);
+        LineTo(__hdcCardBitmaps, xpos+width - 1, 2);
+        LineTo(__hdcCardBitmaps, xpos+width - 1, height - 3);    //vertical
+        LineTo(__hdcCardBitmaps, xpos+width - 3, height - 1);
+        LineTo(__hdcCardBitmaps, xpos+2, height - 1);
+        LineTo(__hdcCardBitmaps, xpos+0, height - 3);
+        LineTo(__hdcCardBitmaps, xpos+0, 2);
+        LineTo(__hdcCardBitmaps, xpos+2, 0);
+        
+        DeleteObject(hBitmap);
+    }
+    
+    DeleteDC(hdcCard);
+
+    *pwidth = width;
+    *pheight = height;
+                
+}
+
+void LoadCardBitmaps(void)
+{
+    HINSTANCE hCardDll;
+    
+
+    //If Windows NT/2000/XP
+    if(GetVersion() < 0x80000000)
+    {
+        hCardDll = LoadLibrary("cards.dll");
+
+        if(hCardDll == 0)
+        {
+            MessageBox(0, "Error loading cards.dll (32bit)", "Shed", MB_OK | MB_ICONEXCLAMATION);
+            PostQuitMessage(0);
+            return;
+        }
+        
+        LoadCardBitmapsFromLibrary(hCardDll, &__cardwidth, &__cardheight);
+        
+        FreeLibrary(hCardDll);
+    }
+#ifndef __REACTOS__
+    //Else, Win9X
+    else
+    {
+        hCardDll = LoadLibrary16("cards.dll");
+
+        if(hCardDll == 0)
+        {
+            MessageBox(0, "Error loading cards.dll (16bit)", "Shed", MB_OK | MB_ICONEXCLAMATION);
+            PostQuitMessage(0);
+            return;
+        }
+
+        LoadCardBitmapsFromLibrary(hCardDll, &__cardwidth, &__cardheight);
+
+        FreeLibrary16(hCardDll);
+    }
+#endif
+}
+
+void FreeCardBitmaps()
+{
+    DeleteObject (__hbmCardBitmaps);
+    DeleteDC     (__hdcCardBitmaps);
+}
+//
+//    Paint a checkered rectangle, with each alternate
+//    pixel being assigned a different colour
+//
+static void DrawCheckedRect(HDC hdc, RECT *rect, COLORREF fg, COLORREF bg)
+{
+    static WORD wCheckPat[8] = 
+    { 
+        0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555 
+    };
+
+    HBITMAP hbmp;
+    HBRUSH  hbr, hbrold;
+    COLORREF fgold, bgold;
+
+    hbmp = CreateBitmap(8, 8, 1, 1, wCheckPat);
+    hbr  = CreatePatternBrush(hbmp);
+
+    //UnrealizeObject(hbr);
+
+    SetBrushOrgEx(hdc, rect->left, rect->top, 0);
+
+    hbrold = (HBRUSH)SelectObject(hdc, hbr);
+
+    fgold = SetTextColor(hdc, fg);
+    bgold = SetBkColor(hdc, bg);
+    
+    PatBlt(hdc, rect->left, rect->top, 
+                rect->right - rect->left, 
+                rect->bottom - rect->top, 
+                PATCOPY);
+    
+    SetBkColor(hdc, bgold);
+    SetTextColor(hdc, fgold);
+    
+    SelectObject(hdc, hbrold);
+    DeleteObject(hbr);
+    DeleteObject(hbmp);
+}
+
+void GetSinkCols(COLORREF crBase, COLORREF *fg, COLORREF *bg, COLORREF *sh1, COLORREF *sh2)
+{
+    if(bg) *bg     = crBase;
+    if(fg) *fg   = ColorScaleRGB(crBase, RGB(255,255,255), 0.2);//RGB(49, 99, 140);
+    if(sh1) *sh1 = ColorScaleRGB(crBase, RGB(0,0,0), 0.4);
+    if(sh2) *sh2 = ColorScaleRGB(crBase, RGB(0,0,0), 0.2);
+}
+
+HBITMAP CreateSinkBmp(HDC hdcCompat, HDC hdc, COLORREF col, int width, int height)
+{
+    HANDLE hold, hpold;
+    HBITMAP hbm = CreateCompatibleBitmap(hdcCompat, width, height);
+
+    HPEN hpfg, hpbg, hpsh, hpsh2;
+
+    RECT rect;
+    COLORREF fg, bg, shadow, shadow2;
+
+    GetSinkCols(col, &fg, &bg, &shadow, &shadow2);
+
+    hold = SelectObject(hdc, hbm);
+
+    //fill with a solid base colour
+    SetRect(&rect, 0,0,width,height);
+    PaintRect(hdc, &rect, MAKE_PALETTERGB(bg));
+
+    //draw the outline
+    hpfg = CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(fg));
+    hpbg = CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(bg));
+    hpsh = CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(shadow));
+    hpsh2= CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(shadow2));    
+
+    hpold = SelectObject(hdc, hpsh);
+    MoveToEx(hdc, 2, 0, NULL);
+    LineTo  (hdc, width-3,0);
+    LineTo  (hdc, width-1, 2);
+    
+    SelectObject(hdc, hpold);
+    hpold = SelectObject(hdc, hpsh2);
+    LineTo  (hdc, width-1, height-3);    //vertical
+    LineTo  (hdc, width-3, height-1);
+    LineTo  (hdc, 2, height-1);
+    LineTo  (hdc, 0, height-3);
+    SelectObject(hdc, hpold);
+    hpold = SelectObject(hdc, hpsh);
+
+    //MoveToEx( hdc, 0, height-3,0);
+    LineTo  (hdc, 0, 2);
+    LineTo  (hdc, 2, 0);
+
+    SelectObject(hdc, hpold);
+
+    //draw the highlight (vertical)
+    hpold = SelectObject(hdc, hpfg);
+    MoveToEx(hdc, width - 2, 3, NULL);
+    LineTo  (hdc, width - 2, height - 2);
+    
+    //(horz)
+    MoveToEx(hdc, width - 3, height-2, NULL);
+    LineTo  (hdc, 3, height-2);
+    SelectObject(hdc, hpold);
+    
+    //draw the background
+    InflateRect(&rect, -2, -2);
+    DrawCheckedRect(hdc, &rect, MAKE_PALETTERGB(bg), MAKE_PALETTERGB(fg));
+
+    //overwrite the top-left background pixel
+    SetPixel(hdc, 2, 2, MAKE_PALETTERGB(bg));
+
+    DeleteObject(hpsh);
+    DeleteObject(hpsh2);
+    DeleteObject(hpfg);
+    DeleteObject(hpbg);
+
+    
+    return hbm;
+}
+
+
+
+void CopyColor(PALETTEENTRY *pe, COLORREF col)
+{
+    pe->peBlue  = GetBValue(col);
+    pe->peGreen = GetGValue(col);
+    pe->peRed   = GetRValue(col);
+    pe->peFlags = 0;
+}
+
+HPALETTE MakePaletteFromCols(COLORREF cols[], int nNumColours)
+{
+    LOGPALETTE    *lp;
+    HPALETTE    hPalette;
+
+    //    Allocate memory for the logical palette
+    lp = (LOGPALETTE *)HeapAlloc(
+        GetProcessHeap(), 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * nNumColours);
+
+    lp->palNumEntries = nNumColours;
+    lp->palVersion    = 0x300;
+
+    //copy the colours into the logical palette format
+    for(int i = 0; i < nNumColours; i++)
+    {
+        CopyColor(&lp->palPalEntry[i], cols[i]);
+    }
+
+    // create palette!
+    hPalette = CreatePalette(lp);
+
+    HeapFree(GetProcessHeap(), 0, lp);
+
+    return hPalette;
+}
index bfdfcf9..a66c3f2 100644 (file)
-//\r
-//    CardLib - CardButton class\r
-//\r
-//    Freeware\r
-//    Copyright J Brown 2001\r
-//\r
-#include <windows.h>\r
-#include <tchar.h>\r
-\r
-#include "cardlib.h"\r
-#include "cardwindow.h"\r
-#include "cardbutton.h"\r
-#include "cardcolor.h"\r
-\r
-HPALETTE UseNicePalette(HDC, HPALETTE);\r
-void     RestorePalette(HDC, HPALETTE);\r
-\r
-void PaintRect(HDC hdc, RECT *rect, COLORREF colour);\r
-\r
-CardButton::CardButton(CardWindow &parent, int Id, TCHAR *szText, UINT Style, bool visible,\r
-                        int x, int y, int width, int height)\r
-\r
- : parentWnd(parent), id(Id), uStyle(Style), fVisible(visible), ButtonCallback(0)\r
-{\r
-    crText = RGB(255,255,255);\r
-    crBack = RGB(0, 128, 0);\r
-    \r
-    xadjust = 0;\r
-    yadjust = 0;\r
-    xjustify = 0;\r
-    yjustify = 0;\r
-\r
-    fMouseDown = false;\r
-    fButtonDown = false;\r
-\r
-    hIcon = 0;\r
-\r
-    SetText(szText);\r
-    Move(x, y, width, height);\r
-\r
-    mxlock = CreateMutex(0, FALSE, 0);\r
-\r
-    hFont = 0;\r
-}\r
-\r
-CardButton::~CardButton()\r
-{\r
-    CloseHandle(mxlock);\r
-}\r
-\r
-void CardButton::DrawRect(HDC hdc, RECT *rect, bool fNormal)\r
-{\r
-    RECT fill;\r
-\r
-    HANDLE hOld;\r
-\r
-    HPEN hhi = CreatePen(0, 0, MAKE_PALETTERGB(crHighlight));\r
-    HPEN hsh = CreatePen(0, 0, MAKE_PALETTERGB(crShadow));\r
-    HPEN hbl = (HPEN)GetStockObject(BLACK_PEN);\r
-    \r
-    int x        = rect->left;\r
-    int y        = rect->top;\r
-    int width    = rect->right-rect->left - 1;\r
-    int height    = rect->bottom-rect->top - 1;\r
-    \r
-    SetRect(&fill, x+1, y+1, x+width-1, y+height-1);\r
-\r
-    int one = 1;\r
-    \r
-    if(!fNormal)\r
-    {\r
-        x += width;\r
-        y += height;\r
-        width = -width;\r
-        height = -height;\r
-        one = -1;\r
-        OffsetRect(&fill, 1, 1);\r
-    }\r
-    \r
-    if(fNormal)\r
-        hOld = SelectObject(hdc, hhi);\r
-    else\r
-        hOld = SelectObject(hdc, hhi);\r
-\r
-    MoveToEx(hdc, x, y+height, 0);\r
-    LineTo(hdc, x, y);\r
-    LineTo(hdc, x+width, y);\r
-    SelectObject(hdc, hOld);\r
-\r
-    hOld = SelectObject(hdc, hbl);\r
-    LineTo(hdc, x+width, y+height);\r
-    LineTo(hdc, x-one, y+height);\r
-    SelectObject(hdc, hOld);\r
-\r
-    hOld = SelectObject(hdc, hsh);\r
-    MoveToEx(hdc, x+one, y+height-one, 0);\r
-    LineTo(hdc, x+width-one, y+height-one);\r
-    LineTo(hdc, x+width-one, y);\r
-    SelectObject(hdc, hOld);\r
-\r
-    PaintRect(hdc, &fill, MAKE_PALETTERGB(crBack));\r
-\r
-    DeleteObject(hhi);\r
-    DeleteObject(hsh);\r
-}\r
-\r
-void CardButton::Clip(HDC hdc)\r
-{\r
-    if(fVisible == false) return;\r
-    \r
-    ExcludeClipRect(hdc, rect.left,  rect.top, rect.right, rect.bottom);\r
-}\r
-\r
-void CardButton::Draw(HDC hdc, bool fNormal)\r
-{\r
-    SIZE textsize;\r
-    int x, y;        //text x, y\r
-    int ix, iy;        //icon x, y\r
-    int iconwidth = 0;\r
-\r
-    RECT cliprect;\r
-\r
-    if(fVisible == 0) return;\r
-\r
-    if(hFont == 0)\r
-        SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));    \r
-    else\r
-        SelectObject(hdc, hFont);    \r
-    \r
-    GetTextExtentPoint32(hdc, szText, lstrlen(szText), &textsize);\r
-    \r
-    if(hIcon)\r
-    {\r
-        x = rect.left + 32 + 8;\r
-    }\r
-    else\r
-    {\r
-        if(uStyle & CB_ALIGN_LEFT)\r
-        {\r
-            x = rect.left + iconwidth;\r
-        }\r
-        else if(uStyle & CB_ALIGN_RIGHT)\r
-        {\r
-            x = rect.left + (rect.right-rect.left-iconwidth-textsize.cx);\r
-        }\r
-        else    //centered\r
-        {\r
-            x = rect.right - rect.left - iconwidth;\r
-            x = (x - textsize.cx) / 2;\r
-            x += rect.left + iconwidth;\r
-        }\r
-    }\r
-    \r
-    y = rect.bottom - rect.top;\r
-    y = (y - textsize.cy) / 2;\r
-    y += rect.top;\r
-    \r
-    //calc icon position..\r
-    ix = rect.left + 4;\r
-    iy = rect.top + (rect.bottom-rect.top-32) / 2;\r
-\r
-    //if button is pressed, then shift text\r
-    if(fNormal == false && (uStyle & CB_PUSHBUTTON))\r
-    {\r
-        x += 1;\r
-        y += 1;\r
-        ix += 1;\r
-        iy += 1;\r
-    }\r
-\r
-    SetRect(&cliprect, x, y, x+textsize.cx, y+textsize.cy);\r
-    ExcludeClipRect(hdc, x, y, x+textsize.cx, y+textsize.cy);\r
-\r
-    //\r
-    //    Calc icon pos\r
-    //\r
-    \r
-    if(hIcon)\r
-    {\r
-        ExcludeClipRect(hdc, ix, iy, ix + 32, iy + 32);\r
-    }\r
-    \r
-    if(uStyle & CB_PUSHBUTTON)\r
-    {\r
-        DrawRect(hdc, &rect, fNormal);\r
-\r
-        SetBkColor(hdc,   MAKE_PALETTERGB(crBack));\r
-        SetTextColor(hdc, crText);//MAKE_PALETTERGB(crText));\r
-        \r
-        SelectClipRgn(hdc, 0);        \r
-\r
-        ExtTextOut(hdc, x, y, ETO_OPAQUE, &cliprect, szText, lstrlen(szText), 0);\r
-    }\r
-    else\r
-    {\r
-        SetBkColor(hdc,      MAKE_PALETTERGB(crBack));\r
-        SetTextColor(hdc, crText);//MAKE_PALETTERGB(crText));\r
-\r
-        SelectClipRgn(hdc, 0);\r
-\r
-        ExtTextOut(hdc, x, y, ETO_OPAQUE, &rect, szText, lstrlen(szText), 0);\r
-    }\r
-\r
-    if(hIcon)\r
-    {\r
-        HBRUSH hbr = CreateSolidBrush(MAKE_PALETTERGB(crBack));\r
-        DrawIconEx(hdc, ix, iy, hIcon, 32, 32, 0, hbr, 0);\r
-        DeleteObject(hbr);\r
-    }\r
-\r
-}\r
-\r
-void CardButton::AdjustPosition(int winwidth, int winheight)\r
-{\r
-    int width = rect.right-rect.left;\r
-    int height = rect.bottom-rect.top;\r
-\r
-    width = width & ~0x1;\r
-\r
-    switch(xjustify)\r
-    {\r
-    case CS_XJUST_NONE:\r
-        break;\r
-\r
-    case CS_XJUST_CENTER:        //centered\r
-        rect.left = (winwidth - (width)) / 2;\r
-        rect.left += xadjust;\r
-        rect.right = rect.left+width;\r
-        break;\r
-\r
-    case CS_XJUST_RIGHT:        //right-aligned\r
-        rect.left = winwidth - width;\r
-        rect.left += xadjust;\r
-        rect.right = rect.left+width;\r
-        break;\r
-    }\r
-\r
-    switch(yjustify)\r
-    {\r
-    case CS_YJUST_NONE:\r
-        break;\r
-\r
-    case CS_YJUST_CENTER:        //centered\r
-        rect.top = (winheight - (height)) / 2;\r
-        rect.top += yadjust;\r
-        rect.bottom = rect.top+height;\r
-        break;\r
-\r
-    case CS_YJUST_BOTTOM:        //right-aligned\r
-        rect.top = winheight - height;\r
-        rect.top += yadjust;\r
-        rect.bottom = rect.top+height;\r
-        break;\r
-    }\r
-\r
-}\r
-\r
-int CardButton::OnLButtonDown(HWND hwnd, int x, int y)\r
-{\r
-    if((uStyle & CB_PUSHBUTTON) == 0) \r
-        return 0;\r
-\r
-    //make sure that the user is allowed to do something\r
-    if(WaitForSingleObject(mxlock, 0) != WAIT_OBJECT_0)\r
-    {\r
-        return 0;\r
-    }\r
-    else\r
-    {\r
-        ReleaseMutex(mxlock);\r
-    }\r
-    \r
-    fMouseDown = true;\r
-    fButtonDown = true;\r
-\r
-    Redraw();\r
-\r
-    SetCapture(hwnd);\r
-\r
-    return 1;\r
-}\r
-\r
-int CardButton::OnMouseMove(HWND hwnd, int x, int y)\r
-{\r
-    if(fMouseDown)\r
-    {\r
-        bool fOldButtonDown = fButtonDown;\r
-\r
-        POINT pt;\r
-        \r
-        pt.x = x;\r
-        pt.y = y;\r
-        \r
-        if(PtInRect(&rect, pt))\r
-            fButtonDown = true;\r
-        else\r
-            fButtonDown = false;\r
-        \r
-        if(fButtonDown != fOldButtonDown)\r
-            Redraw();\r
-    }\r
-    \r
-    return 0;\r
-}\r
-\r
-int CardButton::OnLButtonUp(HWND hwnd, int x, int y)\r
-{\r
-    if(fMouseDown)\r
-    {\r
-        fMouseDown = false;\r
-        fButtonDown = false;\r
-        \r
-        if(uStyle & CB_PUSHBUTTON)\r
-        {\r
-            Redraw();\r
-            ReleaseCapture();\r
-        }\r
-        \r
-        //if have clicked the button\r
-        if(parentWnd.CardButtonFromPoint(x, y) == this)\r
-        {\r
-            if(ButtonCallback)\r
-            {\r
-                ButtonCallback(*this);    \r
-            }\r
-            else\r
-            {\r
-                HWND hwnd = (HWND)parentWnd;\r
-                SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(id, BN_CLICKED), (LONG)hwnd);\r
-            }\r
-        }\r
-    }\r
-\r
-    return 0;\r
-}\r
-\r
-#define _countof(array) (sizeof(array)/sizeof(array[0]))\r
-\r
-CardButton *CardWindow::CreateButton(int id, TCHAR *szText, UINT uStyle, bool fVisible, int x, int y, int width, int height)\r
-{\r
-    CardButton *cb;\r
-\r
-    if(nNumButtons == MAXBUTTONS) \r
-        return 0;\r
-\r
-    cb = new CardButton(*this, id, szText, uStyle, fVisible, x, y, width, height);\r
-    Buttons[nNumButtons++] = cb;\r
-\r
-    if(uStyle & CB_PUSHBUTTON)\r
-    {\r
-        cb->SetBackColor(CardButton::GetFace(crBackgnd));\r
-        //cb->SetBackColor(ScaleLumRGB(crBackgnd, 0.1));\r
-        cb->SetForeColor(RGB(255,255,255));\r
-    }\r
-    else\r
-    {\r
-        cb->SetBackColor(crBackgnd);\r
-        cb->SetForeColor(RGB(255,255,255));\r
-    }\r
-    \r
-    return cb;\r
-}\r
-\r
-void CardButton::SetText(TCHAR *lpszFormat, ...)\r
-{\r
-    int count;\r
-\r
-    va_list args;\r
-    va_start(args, lpszFormat);\r
-\r
-    count = wvsprintf(szText, lpszFormat, args);\r
-    va_end(args);\r
-}\r
-\r
-int CardButton::Id()\r
-{\r
-    return id;\r
-}\r
-\r
-void CardButton::Show(bool fShow)\r
-{\r
-    fVisible = fShow;\r
-}\r
-\r
-void CardButton::Move(int x, int y, int width, int height)\r
-{\r
-    SetRect(&rect, x, y, x+width, y+height);\r
-}\r
-\r
-void CardButton::Redraw()\r
-{\r
-    HDC hdc = GetDC((HWND)parentWnd);\r
-\r
-    HPALETTE hOldPal = UseNicePalette(hdc, __hPalette);\r
-\r
-    Draw(hdc, !fButtonDown);\r
-    \r
-    RestorePalette(hdc, hOldPal);\r
-    \r
-    ReleaseDC((HWND)parentWnd, hdc);\r
-}\r
-\r
-void CardButton::SetForeColor(COLORREF cr)\r
-{\r
-    crText = cr;\r
-}\r
-\r
-void CardButton::SetBackColor(COLORREF cr)\r
-{\r
-    crBack = cr;\r
-\r
-    crHighlight = GetHighlight(cr);\r
-    crShadow    = GetShadow(cr);\r
-    \r
-    //crHighlight = ScaleLumRGB(cr, +0.25);\r
-    //crShadow    = ScaleLumRGB(cr, -0.25);\r
-}\r
-\r
-//    Static member\r
-COLORREF CardButton::GetHighlight(COLORREF crBase)\r
-{\r
-    return ColorScaleRGB(crBase, RGB(255,255,255), 0.25);\r
-}\r
-\r
-//    Static member\r
-COLORREF CardButton::GetShadow(COLORREF crBase)\r
-{\r
-    return ColorScaleRGB(crBase, RGB(0,  0,  0),   0.25);\r
-}\r
-\r
-COLORREF CardButton::GetFace(COLORREF crBase)\r
-{\r
-    return ColorScaleRGB(crBase, RGB(255,255,255), 0.1);\r
-}\r
-\r
-void CardButton::SetPlacement(UINT xJustify, UINT yJustify, int xAdjust, int yAdjust)\r
-{\r
-    xadjust = xAdjust;\r
-    yadjust = yAdjust;\r
-    xjustify = xJustify;\r
-    yjustify = yJustify;\r
-}\r
-\r
-void CardButton::SetIcon(HICON hicon, bool fRedraw)\r
-{\r
-    hIcon = hicon;\r
-    \r
-    if(fRedraw)\r
-        Redraw();\r
-}\r
-\r
-void CardButton::SetFont(HFONT font)\r
-{\r
-    //don't delete the existing font..\r
-    hFont = font;\r
-}\r
-\r
-void CardButton::SetButtonProc(pButtonProc proc)\r
-{\r
-    ButtonCallback    = proc;\r
-}\r
-\r
-bool CardButton::Lock()\r
-{\r
-    DWORD dw = WaitForSingleObject(mxlock, 0);\r
-\r
-    if(dw == WAIT_OBJECT_0)\r
-        return true; \r
-    else\r
-        return false;\r
-}\r
-\r
-bool CardButton::UnLock()\r
-{\r
-    if(ReleaseMutex(mxlock))\r
-        return true;\r
-    else\r
-        return false;\r
-}\r
-\r
-void CardButton::SetStyle(UINT style)\r
-{\r
-    uStyle = style;\r
-}\r
-\r
-UINT CardButton::GetStyle()\r
-{\r
-    return uStyle;\r
-}\r
+//
+//    CardLib - CardButton class
+//
+//    Freeware
+//    Copyright J Brown 2001
+//
+#include <windows.h>
+#include <tchar.h>
+
+#include "cardlib.h"
+#include "cardwindow.h"
+#include "cardbutton.h"
+#include "cardcolor.h"
+
+HPALETTE UseNicePalette(HDC, HPALETTE);
+void     RestorePalette(HDC, HPALETTE);
+
+void PaintRect(HDC hdc, RECT *rect, COLORREF colour);
+
+CardButton::CardButton(CardWindow &parent, int Id, TCHAR *szText, UINT Style, bool visible,
+                        int x, int y, int width, int height)
+
+ : parentWnd(parent), id(Id), uStyle(Style), fVisible(visible), ButtonCallback(0)
+{
+    crText = RGB(255,255,255);
+    crBack = RGB(0, 128, 0);
+    
+    xadjust = 0;
+    yadjust = 0;
+    xjustify = 0;
+    yjustify = 0;
+
+    fMouseDown = false;
+    fButtonDown = false;
+
+    hIcon = 0;
+
+    SetText(szText);
+    Move(x, y, width, height);
+
+    mxlock = CreateMutex(0, FALSE, 0);
+
+    hFont = 0;
+}
+
+CardButton::~CardButton()
+{
+    CloseHandle(mxlock);
+}
+
+void CardButton::DrawRect(HDC hdc, RECT *rect, bool fNormal)
+{
+    RECT fill;
+
+    HANDLE hOld;
+
+    HPEN hhi = CreatePen(0, 0, MAKE_PALETTERGB(crHighlight));
+    HPEN hsh = CreatePen(0, 0, MAKE_PALETTERGB(crShadow));
+    HPEN hbl = (HPEN)GetStockObject(BLACK_PEN);
+    
+    int x        = rect->left;
+    int y        = rect->top;
+    int width    = rect->right-rect->left - 1;
+    int height    = rect->bottom-rect->top - 1;
+    
+    SetRect(&fill, x+1, y+1, x+width-1, y+height-1);
+
+    int one = 1;
+    
+    if(!fNormal)
+    {
+        x += width;
+        y += height;
+        width = -width;
+        height = -height;
+        one = -1;
+        OffsetRect(&fill, 1, 1);
+    }
+    
+    if(fNormal)
+        hOld = SelectObject(hdc, hhi);
+    else
+        hOld = SelectObject(hdc, hhi);
+
+    MoveToEx(hdc, x, y+height, 0);
+    LineTo(hdc, x, y);
+    LineTo(hdc, x+width, y);
+    SelectObject(hdc, hOld);
+
+    hOld = SelectObject(hdc, hbl);
+    LineTo(hdc, x+width, y+height);
+    LineTo(hdc, x-one, y+height);
+    SelectObject(hdc, hOld);
+
+    hOld = SelectObject(hdc, hsh);
+    MoveToEx(hdc, x+one, y+height-one, 0);
+    LineTo(hdc, x+width-one, y+height-one);
+    LineTo(hdc, x+width-one, y);
+    SelectObject(hdc, hOld);
+
+    PaintRect(hdc, &fill, MAKE_PALETTERGB(crBack));
+
+    DeleteObject(hhi);
+    DeleteObject(hsh);
+}
+
+void CardButton::Clip(HDC hdc)
+{
+    if(fVisible == false) return;
+    
+    ExcludeClipRect(hdc, rect.left,  rect.top, rect.right, rect.bottom);
+}
+
+void CardButton::Draw(HDC hdc, bool fNormal)
+{
+    SIZE textsize;
+    int x, y;        //text x, y
+    int ix, iy;        //icon x, y
+    int iconwidth = 0;
+
+    RECT cliprect;
+
+    if(fVisible == 0) return;
+
+    if(hFont == 0)
+        SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));    
+    else
+        SelectObject(hdc, hFont);    
+    
+    GetTextExtentPoint32(hdc, szText, lstrlen(szText), &textsize);
+    
+    if(hIcon)
+    {
+        x = rect.left + 32 + 8;
+    }
+    else
+    {
+        if(uStyle & CB_ALIGN_LEFT)
+        {
+            x = rect.left + iconwidth;
+        }
+        else if(uStyle & CB_ALIGN_RIGHT)
+        {
+            x = rect.left + (rect.right-rect.left-iconwidth-textsize.cx);
+        }
+        else    //centered
+        {
+            x = rect.right - rect.left - iconwidth;
+            x = (x - textsize.cx) / 2;
+            x += rect.left + iconwidth;
+        }
+    }
+    
+    y = rect.bottom - rect.top;
+    y = (y - textsize.cy) / 2;
+    y += rect.top;
+    
+    //calc icon position..
+    ix = rect.left + 4;
+    iy = rect.top + (rect.bottom-rect.top-32) / 2;
+
+    //if button is pressed, then shift text
+    if(fNormal == false && (uStyle & CB_PUSHBUTTON))
+    {
+        x += 1;
+        y += 1;
+        ix += 1;
+        iy += 1;
+    }
+
+    SetRect(&cliprect, x, y, x+textsize.cx, y+textsize.cy);
+    ExcludeClipRect(hdc, x, y, x+textsize.cx, y+textsize.cy);
+
+    //
+    //    Calc icon pos
+    //
+    
+    if(hIcon)
+    {
+        ExcludeClipRect(hdc, ix, iy, ix + 32, iy + 32);
+    }
+    
+    if(uStyle & CB_PUSHBUTTON)
+    {
+        DrawRect(hdc, &rect, fNormal);
+
+        SetBkColor(hdc,   MAKE_PALETTERGB(crBack));
+        SetTextColor(hdc, crText);//MAKE_PALETTERGB(crText));
+        
+        SelectClipRgn(hdc, 0);        
+
+        ExtTextOut(hdc, x, y, ETO_OPAQUE, &cliprect, szText, lstrlen(szText), 0);
+    }
+    else
+    {
+        SetBkColor(hdc,      MAKE_PALETTERGB(crBack));
+        SetTextColor(hdc, crText);//MAKE_PALETTERGB(crText));
+
+        SelectClipRgn(hdc, 0);
+
+        ExtTextOut(hdc, x, y, ETO_OPAQUE, &rect, szText, lstrlen(szText), 0);
+    }
+
+    if(hIcon)
+    {
+        HBRUSH hbr = CreateSolidBrush(MAKE_PALETTERGB(crBack));
+        DrawIconEx(hdc, ix, iy, hIcon, 32, 32, 0, hbr, 0);
+        DeleteObject(hbr);
+    }
+
+}
+
+void CardButton::AdjustPosition(int winwidth, int winheight)
+{
+    int width = rect.right-rect.left;
+    int height = rect.bottom-rect.top;
+
+    width = width & ~0x1;
+
+    switch(xjustify)
+    {
+    case CS_XJUST_NONE:
+        break;
+
+    case CS_XJUST_CENTER:        //centered
+        rect.left = (winwidth - (width)) / 2;
+        rect.left += xadjust;
+        rect.right = rect.left+width;
+        break;
+
+    case CS_XJUST_RIGHT:        //right-aligned
+        rect.left = winwidth - width;
+        rect.left += xadjust;
+        rect.right = rect.left+width;
+        break;
+    }
+
+    switch(yjustify)
+    {
+    case CS_YJUST_NONE:
+        break;
+
+    case CS_YJUST_CENTER:        //centered
+        rect.top = (winheight - (height)) / 2;
+        rect.top += yadjust;
+        rect.bottom = rect.top+height;
+        break;
+
+    case CS_YJUST_BOTTOM:        //right-aligned
+        rect.top = winheight - height;
+        rect.top += yadjust;
+        rect.bottom = rect.top+height;
+        break;
+    }
+
+}
+
+int CardButton::OnLButtonDown(HWND hwnd, int x, int y)
+{
+    if((uStyle & CB_PUSHBUTTON) == 0) 
+        return 0;
+
+    //make sure that the user is allowed to do something
+    if(WaitForSingleObject(mxlock, 0) != WAIT_OBJECT_0)
+    {
+        return 0;
+    }
+    else
+    {
+        ReleaseMutex(mxlock);
+    }
+    
+    fMouseDown = true;
+    fButtonDown = true;
+
+    Redraw();
+
+    SetCapture(hwnd);
+
+    return 1;
+}
+
+int CardButton::OnMouseMove(HWND hwnd, int x, int y)
+{
+    if(fMouseDown)
+    {
+        bool fOldButtonDown = fButtonDown;
+
+        POINT pt;
+        
+        pt.x = x;
+        pt.y = y;
+        
+        if(PtInRect(&rect, pt))
+            fButtonDown = true;
+        else
+            fButtonDown = false;
+        
+        if(fButtonDown != fOldButtonDown)
+            Redraw();
+    }
+    
+    return 0;
+}
+
+int CardButton::OnLButtonUp(HWND hwnd, int x, int y)
+{
+    if(fMouseDown)
+    {
+        fMouseDown = false;
+        fButtonDown = false;
+        
+        if(uStyle & CB_PUSHBUTTON)
+        {
+            Redraw();
+            ReleaseCapture();
+        }
+        
+        //if have clicked the button
+        if(parentWnd.CardButtonFromPoint(x, y) == this)
+        {
+            if(ButtonCallback)
+            {
+                ButtonCallback(*this);    
+            }
+            else
+            {
+                HWND hwnd = (HWND)parentWnd;
+                SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(id, BN_CLICKED), (LONG)hwnd);
+            }
+        }
+    }
+
+    return 0;
+}
+
+#define _countof(array) (sizeof(array)/sizeof(array[0]))
+
+CardButton *CardWindow::CreateButton(int id, TCHAR *szText, UINT uStyle, bool fVisible, int x, int y, int width, int height)
+{
+    CardButton *cb;
+
+    if(nNumButtons == MAXBUTTONS) 
+        return 0;
+
+    cb = new CardButton(*this, id, szText, uStyle, fVisible, x, y, width, height);
+    Buttons[nNumButtons++] = cb;
+
+    if(uStyle & CB_PUSHBUTTON)
+    {
+        cb->SetBackColor(CardButton::GetFace(crBackgnd));
+        //cb->SetBackColor(ScaleLumRGB(crBackgnd, 0.1));
+        cb->SetForeColor(RGB(255,255,255));
+    }
+    else
+    {
+        cb->SetBackColor(crBackgnd);
+        cb->SetForeColor(RGB(255,255,255));
+    }
+    
+    return cb;
+}
+
+void CardButton::SetText(TCHAR *lpszFormat, ...)
+{
+    int count;
+
+    va_list args;
+    va_start(args, lpszFormat);
+
+    count = wvsprintf(szText, lpszFormat, args);
+    va_end(args);
+}
+
+int CardButton::Id()
+{
+    return id;
+}
+
+void CardButton::Show(bool fShow)
+{
+    fVisible = fShow;
+}
+
+void CardButton::Move(int x, int y, int width, int height)
+{
+    SetRect(&rect, x, y, x+width, y+height);
+}
+
+void CardButton::Redraw()
+{
+    HDC hdc = GetDC((HWND)parentWnd);
+
+    HPALETTE hOldPal = UseNicePalette(hdc, __hPalette);
+
+    Draw(hdc, !fButtonDown);
+    
+    RestorePalette(hdc, hOldPal);
+    
+    ReleaseDC((HWND)parentWnd, hdc);
+}
+
+void CardButton::SetForeColor(COLORREF cr)
+{
+    crText = cr;
+}
+
+void CardButton::SetBackColor(COLORREF cr)
+{
+    crBack = cr;
+
+    crHighlight = GetHighlight(cr);
+    crShadow    = GetShadow(cr);
+    
+    //crHighlight = ScaleLumRGB(cr, +0.25);
+    //crShadow    = ScaleLumRGB(cr, -0.25);
+}
+
+//    Static member
+COLORREF CardButton::GetHighlight(COLORREF crBase)
+{
+    return ColorScaleRGB(crBase, RGB(255,255,255), 0.25);
+}
+
+//    Static member
+COLORREF CardButton::GetShadow(COLORREF crBase)
+{
+    return ColorScaleRGB(crBase, RGB(0,  0,  0),   0.25);
+}
+
+COLORREF CardButton::GetFace(COLORREF crBase)
+{
+    return ColorScaleRGB(crBase, RGB(255,255,255), 0.1);
+}
+
+void CardButton::SetPlacement(UINT xJustify, UINT yJustify, int xAdjust, int yAdjust)
+{
+    xadjust = xAdjust;
+    yadjust = yAdjust;
+    xjustify = xJustify;
+    yjustify = yJustify;
+}
+
+void CardButton::SetIcon(HICON hicon, bool fRedraw)
+{
+    hIcon = hicon;
+    
+    if(fRedraw)
+        Redraw();
+}
+
+void CardButton::SetFont(HFONT font)
+{
+    //don't delete the existing font..
+    hFont = font;
+}
+
+void CardButton::SetButtonProc(pButtonProc proc)
+{
+    ButtonCallback    = proc;
+}
+
+bool CardButton::Lock()
+{
+    DWORD dw = WaitForSingleObject(mxlock, 0);
+
+    if(dw == WAIT_OBJECT_0)
+        return true; 
+    else
+        return false;
+}
+
+bool CardButton::UnLock()
+{
+    if(ReleaseMutex(mxlock))
+        return true;
+    else
+        return false;
+}
+
+void CardButton::SetStyle(UINT style)
+{
+    uStyle = style;
+}
+
+UINT CardButton::GetStyle()
+{
+    return uStyle;
+}
index 9ca402e..12515c4 100644 (file)
-#ifndef CARDBUTTON_INCLUDED\r
-#define CARDBUTTON_INCLUDED\r
-\r
-#define MAXBUTTONTEXT 64\r
-\r
-#include "cardlib.h"\r
-\r
-class CardButton\r
-{\r
-       friend class CardWindow;\r
-\r
-       //\r
-       //      Constructor is PRIVATE - only a\r
-       //  CardWindow can create buttons!\r
-       //\r
-       CardButton(CardWindow &parent, int id, TCHAR *szText, UINT style, bool visible,\r
-               int x, int y, int width, int height);\r
-\r
-       ~CardButton();\r
-\r
-public:\r
-\r
-       void SetStyle(UINT uStyle);\r
-       UINT GetStyle();\r
-\r
-       void SetText(TCHAR *fmt, ...);\r
-       void SetFont(HFONT font);\r
-\r
-       void SetPlacement(UINT xJustify, UINT yJustify, int xAdjust, int yAdjust);\r
-\r
-       void SetForeColor(COLORREF cr);\r
-       void SetBackColor(COLORREF cr);\r
-\r
-       void Move(int x, int y, int width, int height);\r
-       void Show(bool fShow);\r
-       void Redraw();\r
-       int  Id();\r
-\r
-       void SetIcon(HICON hicon, bool fRedraw);\r
-\r
-       void SetButtonProc(pButtonProc proc);\r
-\r
-       CardWindow &GetCardWindow() { return parentWnd; }\r
-\r
-       bool Lock();\r
-       bool UnLock();\r
-\r
-       static COLORREF GetHighlight(COLORREF crBase);\r
-       static COLORREF GetShadow(COLORREF crBase);\r
-       static COLORREF GetFace(COLORREF crBase);\r
-\r
-private:\r
-\r
-       //\r
-       //      Private member functions\r
-       //\r
-       void AdjustPosition(int winwidth, int winheight);\r
-\r
-       void DrawRect(HDC hdc, RECT *rect, bool fNormal);\r
-       void Draw(HDC hdc, bool fNormal);\r
-       void Clip(HDC hdc);\r
-\r
-       int  OnLButtonDown(HWND hwnd, int x, int y);\r
-       int  OnMouseMove(HWND hwnd, int x, int y);\r
-       int  OnLButtonUp(HWND hwnd, int x, int y);\r
-\r
-       //\r
-       //      Private members\r
-       //\r
-       CardWindow &parentWnd;\r
-\r
-       RECT    rect;\r
-       int             id;\r
-       UINT    uStyle;\r
-       bool    fVisible;\r
-\r
-       int             xadjust;\r
-       int             xjustify;\r
-       int             yadjust;\r
-       int             yjustify;\r
-\r
-       HICON   hIcon;\r
-       HFONT   hFont;\r
-\r
-       TCHAR   szText[MAXBUTTONTEXT];\r
-\r
-       COLORREF crBack;\r
-       COLORREF crText;\r
-       COLORREF crHighlight;\r
-       COLORREF crShadow;\r
-       COLORREF crShadow2;\r
-\r
-       bool    fMouseDown;\r
-       bool    fButtonDown;\r
-\r
-       HANDLE  mxlock;\r
-\r
-       pButtonProc     ButtonCallback;\r
-};\r
-\r
-#endif\r
+#ifndef CARDBUTTON_INCLUDED
+#define CARDBUTTON_INCLUDED
+
+#define MAXBUTTONTEXT 64
+
+#include "cardlib.h"
+
+class CardButton
+{
+       friend class CardWindow;
+
+       //
+       //      Constructor is PRIVATE - only a
+       //  CardWindow can create buttons!
+       //
+       CardButton(CardWindow &parent, int id, TCHAR *szText, UINT style, bool visible,
+               int x, int y, int width, int height);
+
+       ~CardButton();
+
+public:
+
+       void SetStyle(UINT uStyle);
+       UINT GetStyle();
+
+       void SetText(TCHAR *fmt, ...);
+       void SetFont(HFONT font);
+
+       void SetPlacement(UINT xJustify, UINT yJustify, int xAdjust, int yAdjust);
+
+       void SetForeColor(COLORREF cr);
+       void SetBackColor(COLORREF cr);
+
+       void Move(int x, int y, int width, int height);
+       void Show(bool fShow);
+       void Redraw();
+       int  Id();
+
+       void SetIcon(HICON hicon, bool fRedraw);
+
+       void SetButtonProc(pButtonProc proc);
+
+       CardWindow &GetCardWindow() { return parentWnd; }
+
+       bool Lock();
+       bool UnLock();
+
+       static COLORREF GetHighlight(COLORREF crBase);
+       static COLORREF GetShadow(COLORREF crBase);
+       static COLORREF GetFace(COLORREF crBase);
+
+private:
+
+       //
+       //      Private member functions
+       //
+       void AdjustPosition(int winwidth, int winheight);
+
+       void DrawRect(HDC hdc, RECT *rect, bool fNormal);
+       void Draw(HDC hdc, bool fNormal);
+       void Clip(HDC hdc);
+
+       int  OnLButtonDown(HWND hwnd, int x, int y);
+       int  OnMouseMove(HWND hwnd, int x, int y);
+       int  OnLButtonUp(HWND hwnd, int x, int y);
+
+       //
+       //      Private members
+       //
+       CardWindow &parentWnd;
+
+       RECT    rect;
+       int             id;
+       UINT    uStyle;
+       bool    fVisible;
+
+       int             xadjust;
+       int             xjustify;
+       int             yadjust;
+       int             yjustify;
+
+       HICON   hIcon;
+       HFONT   hFont;
+
+       TCHAR   szText[MAXBUTTONTEXT];
+
+       COLORREF crBack;
+       COLORREF crText;
+       COLORREF crHighlight;
+       COLORREF crShadow;
+       COLORREF crShadow2;
+
+       bool    fMouseDown;
+       bool    fButtonDown;
+
+       HANDLE  mxlock;
+
+       pButtonProc     ButtonCallback;
+};
+
+#endif
index 1d3348a..64e7960 100644 (file)
-//\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
-    return ColorScaleHSL(col, RGB(0,0,0), ratio);\r
-}\r
-\r
-COLORREF ColorLighter(COLORREF col, double ratio)\r
-{\r
-    return ColorScaleHSL(col, RGB(255,255,255), ratio);\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
+//
+//    Colour support
+//
+#include <windows.h>
+
+#define MakeRGB RGB
+
+#define MIN3(a,b,c) ( (a)<=(b) ? (a)<=(c)?(a):(c) : (b)<=(c)?(b):(c) )
+#define MAX3(a,b,c) ( (a)>=(b) ? (a)>=(c)?(a):(c) : (b)>=(c)?(b):(c) )
+
+inline double fMax(double a, double b)
+{
+    return a < b ? b : a;
+}
+
+inline double fMin(double a, double b)
+{
+    return a < b ? a : b;
+}
+/******************************************************************************
+  FUNCTION: RGBtoHLS
+  PURPOSE:     Convert from RGB to HLS
+  IN: RGB color (0xBBGGRR)
+  OUT: Hue, Saturation, Luminance from 0 to 1
+  COPYRIGHT:1995-1997 Robert Mashlan
+            Modified for LabWindows/CVI, 1999 Guillaume Dargaud
+******************************************************************************/
+void RGBtoHLS(const COLORREF rgb, double *H, double *L, double *S ) 
+{
+    double delta;
+    double r = (double)((rgb    )&0xFF)/255;
+    double g = (double)((rgb>> 8)&0xFF)/255;
+    double b = (double)((rgb>>16)&0xFF)/255;
+    double cmax = MAX3(r,g,b);
+    double cmin = MIN3(r,g,b);
+    *L=(cmax+cmin)/2.0;
+    
+    if(cmax == cmin) 
+    {
+        *S = *H = 0; // it's really undefined
+    }
+    else 
+    {
+        if(*L < 0.5)    *S = (cmax-cmin)/(cmax+cmin);
+        else            *S = (cmax-cmin)/(2.0-cmax-cmin);
+        
+        delta = cmax - cmin;
+        
+        if(r == cmax) 
+        {
+            *H = (g - b) / delta;
+        }
+        else
+        {
+            if(g == cmax) *H = 2.0 + (b-r) / delta;
+              else          *H = 4.0 + (r-g) / delta;
+        }
+          *H /= 6.0;
+          if (*H < 0.0) *H += 1;
+    }
+}
+
+/******************************************************************************
+  FUNCTION: HueToRGB
+  PURPOSE:     Convert a hue (color) to RGB
+  COPYRIGHT:1995-1997 Robert Mashlan
+            Modified for LabWindows/CVI, 1999 Guillaume Dargaud
+******************************************************************************/
+double HueToRGB(const double m1, const double m2, double h ) 
+{
+    if (h<0) h+=1.0;
+    if (h>1) h-=1.0;
+    if (6.0*h < 1  ) return (m1+(m2-m1)*h*6.0);
+    if (2.0*h < 1  ) return m2;
+    if (3.0*h < 2.0) return (m1+(m2-m1)*((2.0/3.0)-h)*6.0);
+    return m1;
+}
+
+
+/******************************************************************************
+  FUNCTION: HLStoRGB
+  PURPOSE:     Convert from HSL to RGB
+  IN:         Hue, Saturation, Luminance from 0 to 1
+  RETURN:     RGB color (0xBBGGRR)
+  COPYRIGHT:1995-1997 Robert Mashlan
+            Modified for LabWindows/CVI, 1999 Guillaume Dargaud
+******************************************************************************/
+
+COLORREF HLStoRGB(const double H, const double L, const double S ) 
+{
+    double r,g,b;
+    double m1, m2;
+
+    if(S == 0) 
+    {
+        r = g = b = L;
+    }
+    else 
+    {
+        if (L <= 0.5) 
+            m2 = L * (1.0 + S);
+        else         
+            m2 = L + S - L * S;
+
+        m1 = 2.0 * L - m2;
+
+        r = HueToRGB(m1,m2,H+1.0/3.0);
+        g = HueToRGB(m1,m2,H);
+        b = HueToRGB(m1,m2,H-1.0/3.0);
+    }
+  
+    return RGB(r*255, g*255, b*255);
+}
+
+
+
+/******************************************************************************
+  FUNCTION: ColorScaleHSL
+  PURPOSE:     Returns the HSL linear interpolated color between 2 colors
+            (more natural looking than RGB interpolation)
+               For instance if the luminance is the same in Col1 and Col2, 
+                   then the luminance of the result will be the same
+               If Ratio=0, you get Col1,
+             If Ratio=1, you get Col2
+  IN: Col1: low color in hex 0xBBGGRR format
+        Col2: high color in hex 0xBBGGRR format
+        Ratio: 0 for low color, 1 for high color, or in between
+  EXAMPLE: Col1=0, Col2=0xFF00FF, Ratio=0.5 returns 0x1F5F3F
+******************************************************************************/
+COLORREF ColorScaleHSL(    const COLORREF Col1, const COLORREF Col2, const double Ratio) 
+{
+    static double H1, H2, S1, S2, L1, L2;
+    
+    if (Ratio<=0) return Col1;    // Ratio parameter must be between 0 and 1
+    else if (Ratio>=1) return Col2;
+
+    RGBtoHLS( Col1, &H1, &L1, &S1);
+    RGBtoHLS( Col2, &H2, &L2, &S2);
+    return HLStoRGB( H1+(H2-H1)*Ratio, L1+(L2-L1)*Ratio, S1+(S2-S1)*Ratio );
+}
+
+
+/******************************************************************************
+  FUNCTION: ColorScaleRGB
+  PURPOSE:     Returns the RGB linear interpolated color between 2 colors
+               If Ratio=0, you get Col1,
+             If Ratio=1, you get Col2
+  IN: Col1: low color in hex 0xBBGGRR format
+        Col2: high color in hex 0xBBGGRR format
+        Ratio: 0 for low color, 1 for high color, or in between
+  EXAMPLE: Col1=0, Col2=0xFF00FF, Ratio=0.5 returns 0x800080
+******************************************************************************/
+COLORREF ColorScaleRGB(    const COLORREF Col1, 
+                        const COLORREF Col2, 
+                        const double Ratio) {
+    int R1=(Col1)&0xFF, G1=(Col1>>8)&0xFF, B1=(Col1>>16)&0xFF;
+    int R2=(Col2)&0xFF, G2=(Col2>>8)&0xFF, B2=(Col2>>16)&0xFF;
+
+    if (Ratio<=0) return Col1;    // Ratio parameter must be between 0 and 1
+    else if (Ratio>=1) return Col2;
+
+/*    return RGB(
+               (R1 + (R2 - R1) * (Ratio + 0.02) + 0.5),        // rounding
+               (G1 + (G2 - G1) * (Ratio - 0.00) + 0.5),
+               (B1 + (B2 - B1) * (Ratio + 0.05) + 0.5)
+               );*/
+
+    /*double r = Ratio;
+    if(Col2 == 0)
+        r = 1-Ratio;
+    else
+        r = 1+Ratio;
+    R1 = (int)(double(R1) * r + 0.5);
+    G1 = (int)(double(G1) * r + 0.5);
+    B1 = (int)(double(B1) * r + 0.5);
+    return RGB(R1,G1,B1);*/
+
+    return RGB(
+               (R1 + (R2 - R1) * (Ratio + 0.02) + 0.5),        // rounding
+               (G1 + (G2 - G1) * (Ratio - 0.00) + 0.5),
+               (B1 + (B2 - B1) * (Ratio + 0.05) + 0.5)
+               );
+}
+
+
+
+COLORREF ColorDarker(COLORREF col, double ratio)
+{
+    return ColorScaleHSL(col, RGB(0,0,0), ratio);
+}
+
+COLORREF ColorLighter(COLORREF col, double ratio)
+{
+    return ColorScaleHSL(col, RGB(255,255,255), ratio);
+}
+
+//
+//    Experimental!!!
+//
+#if 0
+
+typedef enum { Red, Green, Blue };
+
+void RGBtoHLS(COLORREF rgb, double *Hue, double *Lum, double *Sat)
+{
+    double mn, mx;
+    int major;
+
+    BYTE red, green, blue;
+
+    red    = GetRValue(rgb);
+    green  = GetGValue(rgb);
+    blue   = GetBValue(rgb);
+
+    if(red < green)
+    {
+        mn = red; mx = green; major = Green;
+    }
+    else
+    {
+        mn = green; mx = red; major = Red;
+    }
+
+    if(blue < mn)
+    {
+        mn = blue;
+    }
+    else if(blue > mx)
+    {
+        mx = blue; major = Blue;
+    }
+
+    if(mn == mx)
+    {
+        *Lum = mn / 255;
+        *Sat = 0;
+        *Hue = 0;
+    }
+    else
+    {
+        *Lum = (mx + mn) / 510;
+
+        if(*Lum <= 0.5)
+            *Sat = (mx-mn) / (mn+mx);
+        else
+            *Sat = (mx-mn) / (510-mn-mx);
+
+        switch(major)
+        {
+        case Red:   *Hue = (green-blue) * 60.0 / (mx-mn) + 360.0;
+                    break;
+
+        case Green: *Hue = (blue-red) * 60.0 / (mx-mn) + 120.0;
+                    break;
+
+        case Blue:  *Hue = (red-green) * 60.0 / (mx-mn) + 240.0;
+                    break;
+
+        }
+
+        if(*Hue > 360.0)
+            *Hue -= 360.0;
+    }
+}
+
+static BYTE Value(double m1, double m2, double hue)
+{
+
+    if(hue > 360)        hue -= 360;
+    else if(hue < 0)    hue += 360;
+
+    if(hue < 60)
+        m1 = m1 + (m2 - m1) * hue / 60;
+    else if(hue < 180)
+        m1 = m2;
+    else if(hue < 240)
+        m1 = m1 + (m2 - m1) * (240 - hue) / 60;
+
+    return (BYTE)(m1 * 255);
+}
+
+COLORREF HLStoRGB(const double Hue, const double Lum, const double Sat)
+{
+    BYTE red, green, blue;
+
+    if(Sat == 0)
+    {
+        red = green = blue = (BYTE)(Lum * 255);        
+    }
+    else
+    {
+        double m1, m2;
+
+        if(Lum <= 0.5)
+            m2 = Lum + Lum * Sat;
+        else
+            m2 = Lum + Sat - Lum * Sat;
+
+        m1 = 2 * Lum - m2;
+
+        red   = Value(m1, m2, Hue + 120);
+        green = Value(m1, m2, Hue);
+        blue  = Value(m1, m2, Hue - 120);
+    }
+
+    return RGB(red, green, blue);
+}
+
+COLORREF ScaleLumRGB(COLORREF col1, double ratio)
+{
+    double H1, L1, S1;
+
+    RGBtoHLS(col1, &H1, &L1, &S1);
+
+    L1 += L1 * ratio;
+
+    return HLStoRGB(H1, L1, S1);
+}
+
+COLORREF ColorScaleHSL(const COLORREF Col1, const COLORREF Col2, const double Ratio) 
+{
+    static double H1, H2, S1, S2, L1, L2;
+    
+    if(Ratio <= 0)        return Col1;    // Ratio parameter must be between 0 and 1
+    else if(Ratio >= 1)    return Col2;
+
+    RGBtoHLS( Col1, &H1, &L1, &S1);
+    RGBtoHLS( Col2, &H2, &L2, &S2);
+
+    return HLStoRGB( H1 /*+ (H2 - H1 ) * Ratio*/, L1 + (L2 - L1) * Ratio, S1 + (S2 - S1) * Ratio * 2);
+}
+
+COLORREF ColorScaleRGB(const COLORREF Col1, const COLORREF Col2, const double Ratio)
+{
+    return ColorScaleHSL(Col1, Col2, Ratio);
+}
+#endif
index d97adce..e8a9ff2 100644 (file)
@@ -1,16 +1,16 @@
-\r
-COLORREF ColorScaleRGB(        const COLORREF Col1, \r
-                                               const COLORREF Col2, \r
-                                               const double Ratio);\r
-\r
-COLORREF ColorScaleHSL(        const COLORREF Col1, \r
-                                               const COLORREF Col2, \r
-                                               const double Ratio);\r
-\r
-\r
-COLORREF ColorDarker(COLORREF col, double ratio);\r
-COLORREF ColorLighter(COLORREF col, double ratio);\r
-\r
-COLORREF ScaleLumRGB(COLORREF col1, double ratio);\r
-\r
-#define MAKE_PALETTERGB(colref) (0x02000000 | colref)\r
+
+COLORREF ColorScaleRGB(        const COLORREF Col1, 
+                                               const COLORREF Col2, 
+                                               const double Ratio);
+
+COLORREF ColorScaleHSL(        const COLORREF Col1, 
+                                               const COLORREF Col2, 
+                                               const double Ratio);
+
+
+COLORREF ColorDarker(COLORREF col, double ratio);
+COLORREF ColorLighter(COLORREF col, double ratio);
+
+COLORREF ScaleLumRGB(COLORREF col1, double ratio);
+
+#define MAKE_PALETTERGB(colref) (0x02000000 | colref)
index 7321858..5cafdd2 100644 (file)
@@ -1,90 +1,90 @@
-//\r
-//    CardCount is a helper library for CardStacks.\r
-//    \r
-//    When you initialize a CardCount object with a \r
-//  cardstack, it keeps track of the number of cards\r
-//    the stack contains.\r
-//\r
-//    e.g. CardCount count(cardstack);\r
-//\r
-//    Then you can do:\r
-//    \r
-//        int num_fives = count[5]\r
-//        \r
-//        count.Add(cardstack2);        - combine with another stack\r
-//\r
-//        int num_aces = count[1]        - aces low\r
-//        int num_aces = count[14]    - aces high\r
-//\r
-//        count.Clear();\r
-//\r
-#include "cardcount.h"\r
-\r
-CardCount::CardCount()\r
-{\r
-    Clear();\r
-}\r
-\r
-CardCount::CardCount(const CardStack &cs)\r
-{\r
-    Init(cs);\r
-}\r
-\r
-void CardCount::Clear()\r
-{\r
-    for(int i = 0; i < 13; i++)\r
-        count[i] = 0;\r
-}\r
-\r
-void CardCount::Add(const CardStack &cs)\r
-{\r
-    for(int i = 0; i < cs.NumCards(); i++)\r
-    {\r
-        Card card = cs[i];\r
-\r
-        int val = card.LoVal();\r
-        count[val - 1]++;\r
-    }\r
-}\r
-\r
-void CardCount::Sub(const CardStack &cs)\r
-{\r
-    for(int i = 0; i < cs.NumCards(); i++)\r
-    {\r
-        Card card = cs[i];\r
-        int val = card.LoVal();\r
-        \r
-        if(count[val - 1] > 0)\r
-            count[val - 1]--;\r
-    }\r
-}\r
-\r
-void CardCount::Init(const CardStack &cs)\r
-{\r
-    Clear();\r
-    Add(cs);\r
-}\r
-\r
-int CardCount::operator [] (size_t index) const\r
-{\r
-    if(index < 1) return 0;\r
-    else if(index > 14)  return 0;    //if out of range\r
-    else if(index == 14) index = 1;    //if a "ace-high"\r
-\r
-    return count[index - 1];\r
-}\r
-\r
-//\r
-//    Decrement specified item by one\r
-//\r
-void CardCount::Dec(size_t index)\r
-{\r
-    if(index < 1) return;\r
-    else if(index > 14)  return;    //if out of range\r
-    else if(index == 14) index = 1;    //if a "ace-high"\r
-\r
-    index -= 1;\r
-\r
-    if(count[index] > 0) \r
-        count[index]--;\r
-}\r
+//
+//    CardCount is a helper library for CardStacks.
+//    
+//    When you initialize a CardCount object with a 
+//  cardstack, it keeps track of the number of cards
+//    the stack contains.
+//
+//    e.g. CardCount count(cardstack);
+//
+//    Then you can do:
+//    
+//        int num_fives = count[5]
+//        
+//        count.Add(cardstack2);        - combine with another stack
+//
+//        int num_aces = count[1]        - aces low
+//        int num_aces = count[14]    - aces high
+//
+//        count.Clear();
+//
+#include "cardcount.h"
+
+CardCount::CardCount()
+{
+    Clear();
+}
+
+CardCount::CardCount(const CardStack &cs)
+{
+    Init(cs);
+}
+
+void CardCount::Clear()
+{
+    for(int i = 0; i < 13; i++)
+        count[i] = 0;
+}
+
+void CardCount::Add(const CardStack &cs)
+{
+    for(int i = 0; i < cs.NumCards(); i++)
+    {
+        Card card = cs[i];
+
+        int val = card.LoVal();
+        count[val - 1]++;
+    }
+}
+
+void CardCount::Sub(const CardStack &cs)
+{
+    for(int i = 0; i < cs.NumCards(); i++)
+    {
+        Card card = cs[i];
+        int val = card.LoVal();
+        
+        if(count[val - 1] > 0)
+            count[val - 1]--;
+    }
+}
+
+void CardCount::Init(const CardStack &cs)
+{
+    Clear();
+    Add(cs);
+}
+
+int CardCount::operator [] (size_t index) const
+{
+    if(index < 1) return 0;
+    else if(index > 14)  return 0;    //if out of range
+    else if(index == 14) index = 1;    //if a "ace-high"
+
+    return count[index - 1];
+}
+
+//
+//    Decrement specified item by one
+//
+void CardCount::Dec(size_t index)
+{
+    if(index < 1) return;
+    else if(index > 14)  return;    //if out of range
+    else if(index == 14) index = 1;    //if a "ace-high"
+
+    index -= 1;
+
+    if(count[index] > 0) 
+        count[index]--;
+}
index f97ba15..6e0a632 100644 (file)
@@ -1,31 +1,31 @@
-#ifndef _CARDCOUNT_INCLUDED\r
-#define _CARDCOUNT_INCLUDED\r
-\r
-#include <windows.h>\r
-\r
-#include "cardstack.h"\r
-\r
-class CardCount\r
-{\r
-public:\r
-       CardCount();\r
-       CardCount(const CardStack &cs);\r
-\r
-       void Init(const CardStack &cs);\r
-       void Clear();\r
-       void Add(const CardStack &cs);\r
-       void Sub(const CardStack &cs);\r
-\r
-       void Dec(size_t index);\r
-\r
-       int operator[] (size_t index) const;\r
-\r
-       CardCount &operator =  (const CardStack &cs);\r
-       CardCount &operator += (const CardStack &cs);\r
-\r
-private:\r
-       int count[13];  //13 different card values \r
-                                       //(ace,2,3,4,5,6,7,8,9,10,J,Q,K)\r
-};\r
-\r
-#endif\r
+#ifndef _CARDCOUNT_INCLUDED
+#define _CARDCOUNT_INCLUDED
+
+#include <windows.h>
+
+#include "cardstack.h"
+
+class CardCount
+{
+public:
+       CardCount();
+       CardCount(const CardStack &cs);
+
+       void Init(const CardStack &cs);
+       void Clear();
+       void Add(const CardStack &cs);
+       void Sub(const CardStack &cs);
+
+       void Dec(size_t index);
+
+       int operator[] (size_t index) const;
+
+       CardCount &operator =  (const CardStack &cs);
+       CardCount &operator += (const CardStack &cs);
+
+private:
+       int count[13];  //13 different card values 
+                                       //(ace,2,3,4,5,6,7,8,9,10,J,Q,K)
+};
+
+#endif
index acd37c0..dcbe424 100644 (file)
-//\r
-//    CardLib - not much of interest in here\r
-//\r
-//    Freeware\r
-//    Copyright J Brown 2001\r
-//\r
-#include <windows.h>\r
-#include "cardlib.h"\r
-#include "globals.h"\r
-\r
-void LoadCardBitmaps(void);\r
-\r
-//static bool __CARDLIB_ACES_HIGH = false;\r
-extern double __CARDZOOMSPEED;\r
-\r
-//\r
-//    Global variables!\r
-//\r
-HDC     __hdcCardBitmaps;\r
-HBITMAP __hbmCardBitmaps;\r
-\r
-HDC        __hdcPlaceHolder;\r
-HBITMAP    __hbmPlaceHolder;\r
-HPALETTE __holdplacepal;\r
-\r
-int        __cardwidth;\r
-int        __cardheight;\r
-\r
-HPALETTE __hPalette;\r
-\r
-\r
-//\r
-//    Cardlib global functions!\r
-//\r
-void CardLib_SetZoomSpeed(int speed)\r
-{\r
-    __CARDZOOMSPEED = (double)speed;\r
-}\r
-\r
-/*\r
-\r
-  It's dangerous to use these operators, because of all\r
-  the implicit conversions that could take place, which\r
-  would have unpredicted side-effects.\r
-\r
-  e.g. Card card(Hearts, 4);\r
-       if(card == 4)    - how does 4 get converted??\r
-                          It uses the Card(int uval) constructor,\r
-                          which results in a 2 of clubs...\r
-                          not what was expected\r
-*/ \r
-/*\r
-void CardLib_SetAcesHigh(bool fHigh);\r
-bool operator != (const Card &lhs, const Card &rhs);\r
-bool operator == (const Card &lhs, const Card &rhs);\r
-bool operator <  (const Card &lhs, const Card &rhs);\r
-bool operator <= (const Card &lhs, const Card &rhs);\r
-bool operator >  (const Card &lhs, const Card &rhs);\r
-bool operator >= (const Card &lhs, const Card &rhs);\r
-*/\r
-\r
-/*\r
-void CardLib_SetAcesHigh(bool fHigh)\r
-{\r
-    __CARDLIB_ACES_HIGH = fHigh;\r
-}\r
-\r
-bool operator == (const Card &lhs, const Card &rhs)\r
-{\r
-    if(__CARDLIB_ACES_HIGH)\r
-        return lhs.HiVal() == rhs.HiVal();\r
-    else\r
-        return lhs.LoVal() == rhs.LoVal();\r
-}\r
-\r
-bool operator != (const Card &lhs, const Card &rhs)\r
-{\r
-    if(__CARDLIB_ACES_HIGH)\r
-        return lhs.HiVal() != rhs.HiVal();\r
-    else\r
-        return lhs.LoVal() != rhs.LoVal();\r
-}\r
-\r
-bool operator > (const Card &lhs, const Card &rhs)\r
-{\r
-    if(__CARDLIB_ACES_HIGH)\r
-        return lhs.HiVal() > rhs.HiVal();\r
-    else\r
-        return lhs.LoVal() > rhs.LoVal();\r
-}\r
-\r
-bool operator >= (const Card &lhs, const Card &rhs)\r
-{\r
-    if(__CARDLIB_ACES_HIGH)\r
-        return lhs.HiVal() >= rhs.HiVal();\r
-    else\r
-        return lhs.LoVal() >= rhs.LoVal();\r
-}\r
-\r
-bool operator < (const Card &lhs, const Card &rhs)\r
-{\r
-    if(__CARDLIB_ACES_HIGH)\r
-        return lhs.HiVal() < rhs.HiVal();\r
-    else\r
-        return lhs.LoVal() < rhs.LoVal();\r
-}\r
-\r
-bool operator <= (const Card &lhs, const Card &rhs)\r
-{\r
-    if(__CARDLIB_ACES_HIGH)\r
-        return lhs.HiVal() <= rhs.HiVal();\r
-    else\r
-        return lhs.LoVal() <= rhs.LoVal();\r
-}\r
-*/\r
-\r
-void PaintRect(HDC hdc, RECT *rect, COLORREF colour)\r
-{\r
-    COLORREF oldcr = SetBkColor(hdc, colour);\r
-    ExtTextOut(hdc, 0, 0, ETO_OPAQUE, rect, "", 0, 0);\r
-    SetBkColor(hdc, oldcr);\r
-}\r
+//
+//    CardLib - not much of interest in here
+//
+//    Freeware
+//    Copyright J Brown 2001
+//
+#include <windows.h>
+#include "cardlib.h"
+#include "globals.h"
+
+void LoadCardBitmaps(void);
+
+//static bool __CARDLIB_ACES_HIGH = false;
+extern double __CARDZOOMSPEED;
+
+//
+//    Global variables!
+//
+HDC     __hdcCardBitmaps;
+HBITMAP __hbmCardBitmaps;
+
+HDC        __hdcPlaceHolder;
+HBITMAP    __hbmPlaceHolder;
+HPALETTE __holdplacepal;
+
+int        __cardwidth;
+int        __cardheight;
+
+HPALETTE __hPalette;
+
+
+//
+//    Cardlib global functions!
+//
+void CardLib_SetZoomSpeed(int speed)
+{
+    __CARDZOOMSPEED = (double)speed;
+}
+
+/*
+
+  It's dangerous to use these operators, because of all
+  the implicit conversions that could take place, which
+  would have unpredicted side-effects.
+
+  e.g. Card card(Hearts, 4);
+       if(card == 4)    - how does 4 get converted??
+                          It uses the Card(int uval) constructor,
+                          which results in a 2 of clubs...
+                          not what was expected
+*/ 
+/*
+void CardLib_SetAcesHigh(bool fHigh);
+bool operator != (const Card &lhs, const Card &rhs);
+bool operator == (const Card &lhs, const Card &rhs);
+bool operator <  (const Card &lhs, const Card &rhs);
+bool operator <= (const Card &lhs, const Card &rhs);
+bool operator >  (const Card &lhs, const Card &rhs);
+bool operator >= (const Card &lhs, const Card &rhs);
+*/
+
+/*
+void CardLib_SetAcesHigh(bool fHigh)
+{
+    __CARDLIB_ACES_HIGH = fHigh;
+}
+
+bool operator == (const Card &lhs, const Card &rhs)
+{
+    if(__CARDLIB_ACES_HIGH)
+        return lhs.HiVal() == rhs.HiVal();
+    else
+        return lhs.LoVal() == rhs.LoVal();
+}
+
+bool operator != (const Card &lhs, const Card &rhs)
+{
+    if(__CARDLIB_ACES_HIGH)
+        return lhs.HiVal() != rhs.HiVal();
+    else
+        return lhs.LoVal() != rhs.LoVal();
+}
+
+bool operator > (const Card &lhs, const Card &rhs)
+{
+    if(__CARDLIB_ACES_HIGH)
+        return lhs.HiVal() > rhs.HiVal();
+    else
+        return lhs.LoVal() > rhs.LoVal();
+}
+
+bool operator >= (const Card &lhs, const Card &rhs)
+{
+    if(__CARDLIB_ACES_HIGH)
+        return lhs.HiVal() >= rhs.HiVal();
+    else
+        return lhs.LoVal() >= rhs.LoVal();
+}
+
+bool operator < (const Card &lhs, const Card &rhs)
+{
+    if(__CARDLIB_ACES_HIGH)
+        return lhs.HiVal() < rhs.HiVal();
+    else
+        return lhs.LoVal() < rhs.LoVal();
+}
+
+bool operator <= (const Card &lhs, const Card &rhs)
+{
+    if(__CARDLIB_ACES_HIGH)
+        return lhs.HiVal() <= rhs.HiVal();
+    else
+        return lhs.LoVal() <= rhs.LoVal();
+}
+*/
+
+void PaintRect(HDC hdc, RECT *rect, COLORREF colour)
+{
+    COLORREF oldcr = SetBkColor(hdc, colour);
+    ExtTextOut(hdc, 0, 0, ETO_OPAQUE, rect, "", 0, 0);
+    SetBkColor(hdc, oldcr);
+}
index ee0ab4a..33f5c02 100644 (file)
-#ifndef CARDLIB_INCLUDED\r
-#define CARDLIB_INCLUDED\r
-\r
-#define CARDLIBPROC __stdcall\r
-\r
-void CardBlt(HDC hdc, int x, int y, int nCardNum);\r
-void CardLib_SetZoomSpeed(int);\r
-\r
-#define CS_EI_NONE     0\r
-#define CS_EI_SUNK     1\r
-\r
-#define CS_DEFXOFF                     12              //x-offset\r
-#define CS_DEFYOFF                     18              //y-offset\r
-#define CS_NO3D                                1               //default 3d counts (recommened)\r
-#define CS_DEF3D                       10              //(best for decks)\r
-\r
-//#define CS_EI_CIRC   2\r
-//#define CS_EI_X              3\r
-\r
-#define CS_DRAG_NONE           0\r
-#define CS_DRAG_TOP                    1\r
-#define CS_DRAG_ALL                    2\r
-#define CS_DRAG_CALLBACK       3\r
-\r
-#define CS_DROP_NONE           0\r
-#define CS_DROP_ALL                    1\r
-#define        CS_DROP_CALLBACK        2\r
-\r
-#define CS_XJUST_NONE          0\r
-#define CS_XJUST_RIGHT         1\r
-#define CS_XJUST_CENTER                2\r
-\r
-#define CS_YJUST_NONE          0\r
-#define CS_YJUST_BOTTOM                1\r
-#define CS_YJUST_CENTER                2\r
-\r
-#define CB_STATIC                      0               //static text label\r
-#define CB_PUSHBUTTON          1               //normal button\r
-#define CB_ALIGN_CENTER                0               //centered is default\r
-#define CB_ALIGN_LEFT          2\r
-#define CB_ALIGN_RIGHT         4\r
-\r
-#define CS_FACE_UP              0      //all cards face-up\r
-#define CS_FACE_DOWN    1      //all cards face-down\r
-#define CS_FACE_DOWNUP  2      //bottom X cards down, top-most face-up\r
-#define CS_FACE_UPDOWN  3      //bottom X cards up, top-most face-down\r
-#define CS_FACE_ANY             4      //cards can be any orientation\r
-\r
-#define CS_DROPZONE_NODROP     -1\r
-\r
-//\r
-//     Define the standard card-back indices\r
-//\r
-#define ecbCROSSHATCH  53\r
-#define ecbWEAVE1              54\r
-#define ecbWEAVE2              55\r
-#define ecbROBOT               56\r
-#define ecbFLOWERS             57\r
-#define ecbVINE1               58\r
-#define ecbVINE2               59\r
-#define ecbFISH1               60\r
-#define ecbFISH2               61\r
-#define ecbSHELLS              62\r
-#define ecbCASTLE              63\r
-#define ecbISLAND              64\r
-#define ecbCARDHAND            65\r
-#define ecbUNUSED              66\r
-#define ecbTHE_X               67\r
-#define ecbTHE_O               68\r
-\r
-\r
-class CardRegion;\r
-class CardButton;\r
-class CardStack;\r
-class CardWindow;\r
-\r
-typedef bool (CARDLIBPROC *pCanDragProc)    (CardRegion &stackobj, int iNumDragging);\r
-typedef bool (CARDLIBPROC *pCanDropProc)    (CardRegion &stackobj, const CardStack &cards);\r
-typedef void (CARDLIBPROC *pClickProc)      (CardRegion &stackobj, int iNumCards);\r
-typedef void (CARDLIBPROC *pAddProc)        (CardRegion &stackobj, const CardStack &cards);\r
-typedef void (CARDLIBPROC *pRemoveProc)     (CardRegion &stackobj, int iNumRemoved);\r
-\r
-typedef void (CARDLIBPROC *pResizeWndProc)  (int width, int height);\r
-typedef int  (CARDLIBPROC *pDropZoneProc)   (int dzid, const CardStack &cards);\r
-\r
-typedef void (CARDLIBPROC *pButtonProc)                (CardButton &pButton);\r
-\r
-\r
-#include "card.h"\r
-#include "cardbutton.h"\r
-#include "cardstack.h"\r
-#include "cardregion.h"\r
-#include "cardcount.h"\r
-#include "cardwindow.h"\r
-\r
-#ifdef _DEBUG\r
-typedef bool (CARDLIBPROC *pDebugClickProc) (CardRegion &stackobj);\r
-void CardLib_SetStackClickProc(pDebugClickProc proc);\r
-#endif\r
-\r
-\r
-#endif\r
+#ifndef CARDLIB_INCLUDED
+#define CARDLIB_INCLUDED
+
+#define CARDLIBPROC __stdcall
+
+void CardBlt(HDC hdc, int x, int y, int nCardNum);
+void CardLib_SetZoomSpeed(int);
+
+#define CS_EI_NONE     0
+#define CS_EI_SUNK     1
+
+#define CS_DEFXOFF                     12              //x-offset
+#define CS_DEFYOFF                     18              //y-offset
+#define CS_NO3D                                1               //default 3d counts (recommened)
+#define CS_DEF3D                       10              //(best for decks)
+
+//#define CS_EI_CIRC   2
+//#define CS_EI_X              3
+
+#define CS_DRAG_NONE           0
+#define CS_DRAG_TOP                    1
+#define CS_DRAG_ALL                    2
+#define CS_DRAG_CALLBACK       3
+
+#define CS_DROP_NONE           0
+#define CS_DROP_ALL                    1
+#define        CS_DROP_CALLBACK        2
+
+#define CS_XJUST_NONE          0
+#define CS_XJUST_RIGHT         1
+#define CS_XJUST_CENTER                2
+
+#define CS_YJUST_NONE          0
+#define CS_YJUST_BOTTOM                1
+#define CS_YJUST_CENTER                2
+
+#define CB_STATIC                      0               //static text label
+#define CB_PUSHBUTTON          1               //normal button
+#define CB_ALIGN_CENTER                0               //centered is default
+#define CB_ALIGN_LEFT          2
+#define CB_ALIGN_RIGHT         4
+
+#define CS_FACE_UP              0      //all cards face-up
+#define CS_FACE_DOWN    1      //all cards face-down
+#define CS_FACE_DOWNUP  2      //bottom X cards down, top-most face-up
+#define CS_FACE_UPDOWN  3      //bottom X cards up, top-most face-down
+#define CS_FACE_ANY             4      //cards can be any orientation
+
+#define CS_DROPZONE_NODROP     -1
+
+//
+//     Define the standard card-back indices
+//
+#define ecbCROSSHATCH  53
+#define ecbWEAVE1              54
+#define ecbWEAVE2              55
+#define ecbROBOT               56
+#define ecbFLOWERS             57
+#define ecbVINE1               58
+#define ecbVINE2               59
+#define ecbFISH1               60
+#define ecbFISH2               61
+#define ecbSHELLS              62
+#define ecbCASTLE              63
+#define ecbISLAND              64
+#define ecbCARDHAND            65
+#define ecbUNUSED              66
+#define ecbTHE_X               67
+#define ecbTHE_O               68
+
+
+class CardRegion;
+class CardButton;
+class CardStack;
+class CardWindow;
+
+typedef bool (CARDLIBPROC *pCanDragProc)    (CardRegion &stackobj, int iNumDragging);
+typedef bool (CARDLIBPROC *pCanDropProc)    (CardRegion &stackobj, const CardStack &cards);
+typedef void (CARDLIBPROC *pClickProc)      (CardRegion &stackobj, int iNumCards);
+typedef void (CARDLIBPROC *pAddProc)        (CardRegion &stackobj, const CardStack &cards);
+typedef void (CARDLIBPROC *pRemoveProc)     (CardRegion &stackobj, int iNumRemoved);
+
+typedef void (CARDLIBPROC *pResizeWndProc)  (int width, int height);
+typedef int  (CARDLIBPROC *pDropZoneProc)   (int dzid, const CardStack &cards);
+
+typedef void (CARDLIBPROC *pButtonProc)                (CardButton &pButton);
+
+
+#include "card.h"
+#include "cardbutton.h"
+#include "cardstack.h"
+#include "cardregion.h"
+#include "cardcount.h"
+#include "cardwindow.h"
+
+#ifdef _DEBUG
+typedef bool (CARDLIBPROC *pDebugClickProc) (CardRegion &stackobj);
+void CardLib_SetStackClickProc(pDebugClickProc proc);
+#endif
+
+
+#endif
index 5eb1c3f..b37d086 100644 (file)
-//\r
-//    CardLib - CardRegion class\r
-//\r
-//    Freeware\r
-//    Copyright J Brown 2001\r
-//\r
-#include <windows.h>\r
-\r
-#include "cardlib.h"\r
-#include "cardregion.h"\r
-#include "cardwindow.h"\r
-#include "cardcolor.h"\r
-\r
-HBITMAP CreateSinkBmp(HDC hdcCompat, HDC hdc, int width, int height);\r
-\r
-void PaintRect(HDC hdc, RECT *rect, COLORREF colour);\r
-\r
-CardRegion::CardRegion(CardWindow &parent, int Id, bool visible, int x, int y, int xOffset, int yOffset) \r
-: id(Id), parentWnd(parent), xpos(x), ypos(y), xoffset(xOffset), yoffset(yOffset), fVisible(visible)\r
-{\r
-    width  = __cardwidth;\r
-    height = __cardheight;\r
-\r
-    crBackgnd  = RGB(0, 64, 100);\r
-\r
-    uFaceDirType   = CS_FACE_UP;\r
-    nFaceDirOption = 0;\r
-    uEmptyImage  = CS_EI_SUNK;\r
-\r
-    fVisible     = visible;\r
-\r
-    nThreedCount = 1;\r
-    nBackCardIdx = 53;\r
-\r
-    Update();                //Update this stack's size+card count\r
-\r
-    hdcBackGnd = 0;\r
-    hbmBackGnd = 0;\r
-    hdcDragCard = 0;\r
-    hbmDragCard = 0;\r
-\r
-    nDragCardWidth = 0;\r
-    nDragCardHeight = 0;\r
-    \r
-    CanDragCallback  = 0;\r
-    CanDropCallback  = 0;\r
-    AddCallback      = 0;\r
-    RemoveCallback   = 0;\r
-    ClickCallback    = 0;\r
-    DblClickCallback = 0;\r
-\r
-    uDragRule = CS_DRAG_ALL;\r
-    uDropRule = CS_DROP_ALL;\r
-\r
-    xjustify = yjustify = xadjust = yadjust = 0;\r
-\r
-    nFlashCount        = 0;\r
-    fFlashVisible    = false;\r
-    uFlashTimer        = (UINT)-1;\r
-\r
-    fMouseDragging = false;\r
-\r
-    mxlock = CreateMutex(0, FALSE, 0);\r
-}\r
-\r
-CardRegion::~CardRegion()\r
-{\r
-    CloseHandle(mxlock);\r
-}\r
-\r
-void CardRegion::SetBackColor(COLORREF cr)\r
-{\r
-    crBackgnd = cr;\r
-}\r
-\r
-int CardRegion::CalcApparentCards(int realnum)\r
-{\r
-    return ((realnum + nThreedCount - 1) - (realnum + nThreedCount - 1) % nThreedCount) / nThreedCount;\r
-}\r
-\r
-void CardRegion::CalcApparentCards()\r
-{\r
-    nNumApparentCards = CalcApparentCards(cardstack.NumCards());\r
-}\r
-\r
-\r
-void CardRegion::UpdateSize(void)\r
-{\r
-    if(cardstack.NumCards() > 0)\r
-    {\r
-        if(xoffset > 0)\r
-            width  = (nNumApparentCards - 1) * xoffset + __cardwidth;\r
-        else\r
-            width  = (nNumApparentCards - 1) * -xoffset + __cardwidth;\r
-\r
-        if(yoffset > 0)\r
-            height = (nNumApparentCards - 1) * yoffset + __cardheight;\r
-        else\r
-            height = (nNumApparentCards - 1) * -yoffset + __cardheight;\r
-    }\r
-    else\r
-    {\r
-        width = __cardwidth;\r
-        height = __cardheight;\r
-    }\r
-}\r
-\r
-CardRegion *CardWindow::CreateRegion(int id, bool fVisible, int x, int y, int xoffset, int yoffset)\r
-{\r
-    CardRegion *cr;\r
-\r
-    if(nNumCardRegions == MAXCARDSTACKS)\r
-        return FALSE;\r
-\r
-    cr = new CardRegion(*this, id, fVisible, x, y, xoffset, yoffset);\r
-    cr->SetBackColor(crBackgnd);\r
-    cr->SetBackCardIdx(nBackCardIdx);\r
-\r
-    Regions[nNumCardRegions++] = cr;\r
-    \r
-    return cr;\r
-}\r
-\r
-int CardRegion::GetOverlapRatio(int x, int y, int w, int h)\r
-{\r
-    RECT me, him;\r
-    RECT inter;\r
-    SetRect(&him, x, y, x+w, y+h);\r
-    SetRect(&me,  xpos, ypos, xpos+width, ypos+height);\r
-\r
-    //see if the specified rectangle overlaps us\r
-    if(IntersectRect(&inter, &me, &him))\r
-    {\r
-        int wi = inter.right  - inter.left;\r
-        int hi = inter.bottom - inter.top;\r
-\r
-        int overlap = wi * hi;\r
-        int total   = width * height;\r
-\r
-        int percent = (overlap << 16) / total;\r
-        return (percent * 100) >> 16;\r
-    }\r
-    //do not overlap\r
-    else\r
-    {\r
-        return 0;\r
-    }\r
-}\r
-\r
-bool CardRegion::SetDragRule(UINT uDragType, pCanDragProc proc)\r
-{ \r
-    switch(uDragType)\r
-    {\r
-    case CS_DRAG_NONE: case CS_DRAG_ALL: case CS_DRAG_TOP:\r
-        uDragRule = uDragType;\r
-        return true;\r
-\r
-    case CS_DRAG_CALLBACK:\r
-        uDragRule = uDragType;\r
-        CanDragCallback = proc;\r
-        return true;\r
-\r
-    default:\r
-        return false;\r
-    }\r
-}\r
-\r
-bool CardRegion::SetDropRule(UINT uDropType, pCanDropProc proc)\r
-{ \r
-    switch(uDropType)\r
-    {\r
-    case CS_DROP_NONE: case CS_DROP_ALL: \r
-        uDropRule = uDropType;\r
-        return true;\r
-\r
-    case CS_DROP_CALLBACK:\r
-        uDropRule = uDropType;\r
-        CanDropCallback = proc;\r
-        return true;\r
-\r
-    default:\r
-        return false;\r
-    }\r
-}\r
-\r
-void CardRegion::SetClickProc(pClickProc proc)\r
-{\r
-    ClickCallback = proc;\r
-}\r
-\r
-void CardRegion::SetDblClickProc(pClickProc proc)\r
-{\r
-    DblClickCallback = proc;\r
-}\r
-\r
-void CardRegion::SetAddCardProc(pAddProc proc)\r
-{\r
-    AddCallback = proc;\r
-}\r
-\r
-void CardRegion::SetRemoveCardProc(pRemoveProc proc)\r
-{\r
-    RemoveCallback = proc;\r
-}\r
-\r
-void CardRegion::Update()\r
-{\r
-    CalcApparentCards();\r
-    UpdateSize(); \r
-    UpdateFaceDir(cardstack);\r
-}\r
-\r
-\r
-bool CardRegion::SetThreedCount(int count)\r
-{\r
-    if(count < 1) \r
-    {\r
-        return false;\r
-    }\r
-    else\r
-    {\r
-        nThreedCount = count;\r
-        return true;\r
-    }\r
-}\r
-\r
-void CardRegion::SetOffsets(int x, int y)\r
-{\r
-    xoffset = x;\r
-    yoffset = y;\r
-}\r
-\r
-void CardRegion::SetPos(int x, int y)\r
-{\r
-    xpos = x;\r
-    ypos = y;\r
-}\r
-\r
-void CardRegion::Show(bool fShow)\r
-{\r
-    fVisible = fShow;\r
-}\r
-\r
-bool CardRegion::IsVisible()\r
-{ \r
-    return fVisible;\r
-}\r
-\r
-void CardRegion::SetPlacement(UINT xJustify, UINT yJustify, int xAdjust, int yAdjust)\r
-{\r
-    xjustify = xJustify;\r
-    yjustify = yJustify;\r
-    xadjust  = xAdjust;\r
-    yadjust  = yAdjust;\r
-}\r
-\r
-void CardRegion::SetFaceDirection(UINT uDirType, int nOption)\r
-{\r
-    switch(uDirType)\r
-    {\r
-    case CS_FACE_UP:     case CS_FACE_DOWN: case CS_FACE_DOWNUP:\r
-    case CS_FACE_UPDOWN: case CS_FACE_ANY:\r
-        uFaceDirType    = uDirType;\r
-        nFaceDirOption  = nOption;\r
-\r
-        UpdateFaceDir(cardstack);\r
-\r
-        break;\r
-    }\r
-}\r
-\r
-UINT CardRegion::GetFaceDirection(int *pnOption)\r
-{\r
-    if(pnOption)\r
-        *pnOption = nFaceDirOption;\r
-\r
-    return uFaceDirType;\r
-}\r
-\r
-void CardRegion::AdjustPosition(int winwidth, int winheight)\r
-{\r
-    Update();            //Update this stack's card count + size\r
-\r
-    switch(xjustify)\r
-    {\r
-    default: case CS_XJUST_NONE: break;\r
-    \r
-    case CS_XJUST_CENTER:        //centered\r
-        xpos = (winwidth - (width & ~0x1)) / 2;\r
-        xpos += xadjust;\r
-\r
-        if(xoffset < 0)    xpos += (width - __cardwidth);\r
-    \r
-        break;\r
-\r
-    case CS_XJUST_RIGHT:        //right-aligned\r
-        xpos = winwidth - __cardwidth;//width - 20;\r
-        xpos += xadjust;\r
-        break;\r
-    }\r
-\r
-    switch(yjustify)\r
-    {\r
-    default: case CS_YJUST_NONE: break;\r
-    \r
-    case CS_YJUST_CENTER:        //centered\r
-        ypos = (winheight - height) / 2;\r
-        ypos += yadjust;\r
-        if(yoffset < 0)    ypos += (height - __cardheight);\r
-        break;\r
-\r
-    case CS_YJUST_BOTTOM:        //bottom-aligned\r
-        ypos = winheight - __cardheight;//height - 20;\r
-        ypos += yadjust;\r
-        break;\r
-    }\r
-\r
-}\r
-\r
-\r
-void CardRegion::Flash(int count, int milliseconds)\r
-{\r
-    if(count <= 0) return;\r
-\r
-    nFlashCount        = count;\r
-    fFlashVisible   = false;\r
-    uFlashTimer        = SetTimer((HWND)parentWnd, (WPARAM)this, milliseconds, 0);\r
-    \r
-    parentWnd.Redraw();\r
-}\r
-\r
-void CardRegion::StopFlash()\r
-{\r
-    if(uFlashTimer != (UINT)-1)\r
-    {\r
-        KillTimer((HWND)parentWnd, uFlashTimer);\r
-        nFlashCount        = 0;\r
-        uFlashTimer        = (UINT)-1;\r
-        fFlashVisible    = true;\r
-    }\r
-}\r
-\r
-void CardRegion::DoFlash()\r
-{\r
-    if(uFlashTimer != (UINT)-1)\r
-    {\r
-        fFlashVisible = !fFlashVisible;\r
-\r
-        if(--nFlashCount == 0)\r
-        {\r
-            KillTimer((HWND)parentWnd, uFlashTimer);\r
-            uFlashTimer = (UINT)-1;\r
-            fFlashVisible = true;\r
-        }\r
-    \r
-        parentWnd.Redraw();\r
-    }\r
-}\r
-\r
-int CardRegion::Id()\r
-{\r
-    return id;\r
-}\r
-\r
-void CardRegion::SetEmptyImage(UINT uImage)\r
-{\r
-    switch(uImage)\r
-    {\r
-    case CS_EI_NONE: case CS_EI_SUNK:\r
-        uEmptyImage = uImage;\r
-        break;\r
-\r
-    default:\r
-        uEmptyImage = CS_EI_NONE;\r
-        break;\r
-    }\r
-    \r
-}\r
-\r
-void CardRegion::SetBackCardIdx(UINT uBackIdx)\r
-{\r
-    if(uBackIdx >= 52 && uBackIdx <= 68)\r
-        nBackCardIdx = uBackIdx;\r
-}\r
-\r
-void CardRegion::SetCardStack(const CardStack &cs)\r
-{ \r
-    //make a complete copy of the specified stack..\r
-    cardstack = cs; \r
-\r
-    // Update the face-direction and stack-size\r
-    Update();\r
-}\r
-\r
-const CardStack & CardRegion::GetCardStack()\r
-{ \r
-    //return reference to our internal stack\r
-    return cardstack; \r
-}\r
-\r
-//\r
-//    Update specified card-stack using THIS stack's\r
-//  face direction rules!\r
-//\r
-void CardRegion::UpdateFaceDir(CardStack &cards)\r
-{\r
-    int i, n, num;\r
-\r
-    num = cards.NumCards();\r
-\r
-    //Now apply the face direction rules..\r
-    switch(uFaceDirType)\r
-    {\r
-    case CS_FACE_UP:\r
-\r
-        for(i = 0; i < num; i++)\r
-        {\r
-            cards[i].SetFaceUp(true);\r
-        }\r
-\r
-        break;\r
-\r
-    case CS_FACE_DOWN:\r
-\r
-        for(i = 0; i < num; i++)\r
-        {\r
-            cards[i].SetFaceUp(false);\r
-        }\r
-\r
-        break;\r
-\r
-    case CS_FACE_DOWNUP:\r
-\r
-        num = cardstack.NumCards();\r
-        n = min(nFaceDirOption, num);\r
-\r
-        //bottom n cards..\r
-        for(i = 0; i < n; i++)\r
-        {\r
-            cards[num - i - 1].SetFaceUp(false);\r
-        }\r
-\r
-        for(i = n; i < num; i++)\r
-        {\r
-            cards[num - i - 1].SetFaceUp(true);\r
-        }\r
-\r
-        break;\r
-\r
-    case CS_FACE_UPDOWN:\r
-\r
-        num = cardstack.NumCards();\r
-        n = min(nFaceDirOption, num);\r
-\r
-        for(i = 0; i < n; i++)\r
-        {\r
-            cards[num - i - 1].SetFaceUp(true);\r
-        }\r
-\r
-        for(i = n; i < num; i++)\r
-        {\r
-            cards[num - i - 1].SetFaceUp(false);\r
-        }\r
-\r
-        break;\r
-\r
-    case CS_FACE_ANY:    //cards can be any orientation\r
-    default:\r
-        break;\r
-    }\r
-}\r
-\r
-bool CardRegion::MoveCard(CardRegion *pDestStack, int nNumCards, bool fAnimate)\r
-{\r
-    HDC hdc;\r
-\r
-    int x, y;\r
-\r
-    if(pDestStack == 0) return false; //{ forcedfacedir = -1 ;return 0; }\r
-\r
-    if(nNumCards < 0 || nNumCards > cardstack.NumCards())\r
-        return false;\r
-\r
-    x = xpos + xoffset * (nNumApparentCards - nNumCards);\r
-    y = ypos + yoffset * (nNumApparentCards - nNumCards);\r
-\r
-    oldx = x;\r
-    oldy = y;\r
-    \r
-    dragstack = cardstack.Pop(nNumCards);\r
-\r
-    //Alter the drag-stack so that it's cards are the same way up\r
-    //as the destination. Use the destination's drag-rules\r
-    //instead of this ones!!\r
-    CardStack temp;\r
-    temp.Push(pDestStack->GetCardStack());\r
-    temp.Push(dragstack);\r
-\r
-    pDestStack->UpdateFaceDir(temp);\r
-\r
-    dragstack = temp.Pop(nNumCards);\r
-\r
-    if(fAnimate)\r
-    {\r
-        iNumDragCards = nNumCards;\r
-        PrepareDragBitmaps(nNumCards);\r
-    }\r
-\r
-    Update();        //Update this stack's size+card count\r
-\r
-    if(fAnimate)\r
-    {\r
-        hdc = GetDC((HWND)parentWnd);\r
-\r
-        ZoomCard(hdc, x, y, pDestStack);\r
-        \r
-        ReleaseDC((HWND)parentWnd, hdc);\r
-        ReleaseDragBitmaps();\r
-    }\r
-\r
-    // Get a copy of the cardstack\r
-    CardStack cs = pDestStack->GetCardStack();\r
-    cs.Push(dragstack);\r
-    \r
-    pDestStack->SetCardStack(cs);\r
-    \r
-    //cs = pDestStack->GetCardStack();\r
-    //pDestStack->Update();\r
-    //pDestStack->UpdateFaceDir(cs);\r
-\r
-    RedrawIfNotDim(pDestStack, false);\r
-\r
-    //forcedfacedir = -1;\r
-    return true;\r
-}\r
-\r
-//\r
-//    Simple wrappers\r
-//\r
-int CardRegion::NumCards() const\r
-{\r
-    if(fMouseDragging)\r
-        return cardstack.NumCards() + dragstack.NumCards();\r
-    else\r
-        return cardstack.NumCards(); \r
-}\r
-\r
-bool CardRegion::Lock()\r
-{\r
-    DWORD dw = WaitForSingleObject(mxlock, 0);\r
-\r
-    if(dw == WAIT_OBJECT_0)\r
-    {\r
-        //TRACE("LockStack succeeded\n");\r
-        return true; \r
-    }\r
-    else\r
-    {\r
-        //TRACE("LockStack failed\n");\r
-        return false;\r
-    }\r
-    return false;\r
-}\r
-\r
-bool CardRegion::UnLock()\r
-{\r
-    if(ReleaseMutex(mxlock))\r
-    {\r
-        //TRACE("Unlocking stack\n");\r
-        return true;\r
-    }\r
-    else\r
-    {\r
-        //TRACE("Unlocking stack failed\n");    \r
-        return false;\r
-    }\r
-}\r
-\r
-bool CardRegion::PlayCard(CardRegion *pDestStack, int value, int num)\r
-{\r
-    //search the stack for the specified card value...\r
-    while(num--)\r
-    {\r
-        for(int i = 0; i < cardstack.NumCards(); i++)\r
-        {\r
-            if(cardstack[i].HiVal() == value)\r
-            {\r
-                //swap the card with one at top pos...\r
-                Card card = cardstack.RemoveCard(i);\r
-                cardstack.Push(card);\r
-\r
-                Redraw();\r
-\r
-                MoveCard(pDestStack, 1, true);\r
-                break;\r
-            }\r
-        }\r
-    }\r
-\r
-    return true;\r
-}\r
-\r
-//\r
-//    Redraw the current stack if it has a different\r
-//    layout than the comparison stack.\r
-//\r
-void CardRegion::RedrawIfNotDim(CardRegion *pCompare, bool fFullRedraw)\r
-{\r
-    //\r
-    //\r
-    //\r
-    if( pCompare->xoffset != xoffset || \r
-        pCompare->yoffset != yoffset || \r
-        pCompare->nThreedCount != nThreedCount ||\r
-        pCompare->uFaceDirType != uFaceDirType ||\r
-        pCompare->uFaceDirType != CS_FACE_ANY\r
-        )\r
-    {\r
-        if(fFullRedraw)\r
-            parentWnd.Redraw();\r
-        else\r
-            pCompare->Redraw();\r
-    }\r
-    \r
-}\r
-\r
-//\r
-//    SimulateDrag mimicks the complete drag+drop process.\r
-//  It basically just a MoveCard(..), but it calls the\r
-//  event callbacks as well.\r
-//\r
-bool CardRegion::SimulateDrag(CardRegion *pDestStack, int iNumDragCards, bool fAnimate)\r
-{\r
-    if(pDestStack == 0)\r
-        return false;\r
-\r
-    if(CanDragCards(iNumDragCards) != false)\r
-    {\r
-        //make a list of the cards that would be in the drag list\r
-        CardStack tempstack = cardstack.Top(iNumDragCards);\r
-\r
-        if(pDestStack->CanDropCards(tempstack)) \r
-        {\r
-            MoveCard(pDestStack, iNumDragCards, fAnimate);        \r
-                \r
-            if(RemoveCallback)\r
-                RemoveCallback(*this, iNumDragCards);\r
-\r
-            if(pDestStack->AddCallback)\r
-                pDestStack->AddCallback(*pDestStack, pDestStack->cardstack);\r
-        \r
-            RedrawIfNotDim(pDestStack, true);\r
-        }    \r
-\r
-    }\r
-\r
-    return true;\r
-}\r
+//
+//    CardLib - CardRegion class
+//
+//    Freeware
+//    Copyright J Brown 2001
+//
+#include <windows.h>
+
+#include "cardlib.h"
+#include "cardregion.h"
+#include "cardwindow.h"
+#include "cardcolor.h"
+
+HBITMAP CreateSinkBmp(HDC hdcCompat, HDC hdc, int width, int height);
+
+void PaintRect(HDC hdc, RECT *rect, COLORREF colour);
+
+CardRegion::CardRegion(CardWindow &parent, int Id, bool visible, int x, int y, int xOffset, int yOffset) 
+: id(Id), parentWnd(parent), xpos(x), ypos(y), xoffset(xOffset), yoffset(yOffset), fVisible(visible)
+{
+    width  = __cardwidth;
+    height = __cardheight;
+
+    crBackgnd  = RGB(0, 64, 100);
+
+    uFaceDirType   = CS_FACE_UP;
+    nFaceDirOption = 0;
+    uEmptyImage  = CS_EI_SUNK;
+
+    fVisible     = visible;
+
+    nThreedCount = 1;
+    nBackCardIdx = 53;
+
+    Update();                //Update this stack's size+card count
+
+    hdcBackGnd = 0;
+    hbmBackGnd = 0;
+    hdcDragCard = 0;
+    hbmDragCard = 0;
+
+    nDragCardWidth = 0;
+    nDragCardHeight = 0;
+    
+    CanDragCallback  = 0;
+    CanDropCallback  = 0;
+    AddCallback      = 0;
+    RemoveCallback   = 0;
+    ClickCallback    = 0;
+    DblClickCallback = 0;
+
+    uDragRule = CS_DRAG_ALL;
+    uDropRule = CS_DROP_ALL;
+
+    xjustify = yjustify = xadjust = yadjust = 0;
+
+    nFlashCount        = 0;
+    fFlashVisible    = false;
+    uFlashTimer        = (UINT)-1;
+
+    fMouseDragging = false;
+
+    mxlock = CreateMutex(0, FALSE, 0);
+}
+
+CardRegion::~CardRegion()
+{
+    CloseHandle(mxlock);
+}
+
+void CardRegion::SetBackColor(COLORREF cr)
+{
+    crBackgnd = cr;
+}
+
+int CardRegion::CalcApparentCards(int realnum)
+{
+    return ((realnum + nThreedCount - 1) - (realnum + nThreedCount - 1) % nThreedCount) / nThreedCount;
+}
+
+void CardRegion::CalcApparentCards()
+{
+    nNumApparentCards = CalcApparentCards(cardstack.NumCards());
+}
+
+
+void CardRegion::UpdateSize(void)
+{
+    if(cardstack.NumCards() > 0)
+    {
+        if(xoffset > 0)
+            width  = (nNumApparentCards - 1) * xoffset + __cardwidth;
+        else
+            width  = (nNumApparentCards - 1) * -xoffset + __cardwidth;
+
+        if(yoffset > 0)
+            height = (nNumApparentCards - 1) * yoffset + __cardheight;
+        else
+            height = (nNumApparentCards - 1) * -yoffset + __cardheight;
+    }
+    else
+    {
+        width = __cardwidth;
+        height = __cardheight;
+    }
+}
+
+CardRegion *CardWindow::CreateRegion(int id, bool fVisible, int x, int y, int xoffset, int yoffset)
+{
+    CardRegion *cr;
+
+    if(nNumCardRegions == MAXCARDSTACKS)
+        return FALSE;
+
+    cr = new CardRegion(*this, id, fVisible, x, y, xoffset, yoffset);
+    cr->SetBackColor(crBackgnd);
+    cr->SetBackCardIdx(nBackCardIdx);
+
+    Regions[nNumCardRegions++] = cr;
+    
+    return cr;
+}
+
+int CardRegion::GetOverlapRatio(int x, int y, int w, int h)
+{
+    RECT me, him;
+    RECT inter;
+    SetRect(&him, x, y, x+w, y+h);
+    SetRect(&me,  xpos, ypos, xpos+width, ypos+height);
+
+    //see if the specified rectangle overlaps us
+    if(IntersectRect(&inter, &me, &him))
+    {
+        int wi = inter.right  - inter.left;
+        int hi = inter.bottom - inter.top;
+
+        int overlap = wi * hi;
+        int total   = width * height;
+
+        int percent = (overlap << 16) / total;
+        return (percent * 100) >> 16;
+    }
+    //do not overlap
+    else
+    {
+        return 0;
+    }
+}
+
+bool CardRegion::SetDragRule(UINT uDragType, pCanDragProc proc)
+{ 
+    switch(uDragType)
+    {
+    case CS_DRAG_NONE: case CS_DRAG_ALL: case CS_DRAG_TOP:
+        uDragRule = uDragType;
+        return true;
+
+    case CS_DRAG_CALLBACK:
+        uDragRule = uDragType;
+        CanDragCallback = proc;
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+bool CardRegion::SetDropRule(UINT uDropType, pCanDropProc proc)
+{ 
+    switch(uDropType)
+    {
+    case CS_DROP_NONE: case CS_DROP_ALL: 
+        uDropRule = uDropType;
+        return true;
+
+    case CS_DROP_CALLBACK:
+        uDropRule = uDropType;
+        CanDropCallback = proc;
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+void CardRegion::SetClickProc(pClickProc proc)
+{
+    ClickCallback = proc;
+}
+
+void CardRegion::SetDblClickProc(pClickProc proc)
+{
+    DblClickCallback = proc;
+}
+
+void CardRegion::SetAddCardProc(pAddProc proc)
+{
+    AddCallback = proc;
+}
+
+void CardRegion::SetRemoveCardProc(pRemoveProc proc)
+{
+    RemoveCallback = proc;
+}
+
+void CardRegion::Update()
+{
+    CalcApparentCards();
+    UpdateSize(); 
+    UpdateFaceDir(cardstack);
+}
+
+
+bool CardRegion::SetThreedCount(int count)
+{
+    if(count < 1) 
+    {
+        return false;
+    }
+    else
+    {
+        nThreedCount = count;
+        return true;
+    }
+}
+
+void CardRegion::SetOffsets(int x, int y)
+{
+    xoffset = x;
+    yoffset = y;
+}
+
+void CardRegion::SetPos(int x, int y)
+{
+    xpos = x;
+    ypos = y;
+}
+
+void CardRegion::Show(bool fShow)
+{
+    fVisible = fShow;
+}
+
+bool CardRegion::IsVisible()
+{ 
+    return fVisible;
+}
+
+void CardRegion::SetPlacement(UINT xJustify, UINT yJustify, int xAdjust, int yAdjust)
+{
+    xjustify = xJustify;
+    yjustify = yJustify;
+    xadjust  = xAdjust;
+    yadjust  = yAdjust;
+}
+
+void CardRegion::SetFaceDirection(UINT uDirType, int nOption)
+{
+    switch(uDirType)
+    {
+    case CS_FACE_UP:     case CS_FACE_DOWN: case CS_FACE_DOWNUP:
+    case CS_FACE_UPDOWN: case CS_FACE_ANY:
+        uFaceDirType    = uDirType;
+        nFaceDirOption  = nOption;
+
+        UpdateFaceDir(cardstack);
+
+        break;
+    }
+}
+
+UINT CardRegion::GetFaceDirection(int *pnOption)
+{
+    if(pnOption)
+        *pnOption = nFaceDirOption;
+
+    return uFaceDirType;
+}
+
+void CardRegion::AdjustPosition(int winwidth, int winheight)
+{
+    Update();            //Update this stack's card count + size
+
+    switch(xjustify)
+    {
+    default: case CS_XJUST_NONE: break;
+    
+    case CS_XJUST_CENTER:        //centered
+        xpos = (winwidth - (width & ~0x1)) / 2;
+        xpos += xadjust;
+
+        if(xoffset < 0)    xpos += (width - __cardwidth);
+    
+        break;
+
+    case CS_XJUST_RIGHT:        //right-aligned
+        xpos = winwidth - __cardwidth;//width - 20;
+        xpos += xadjust;
+        break;
+    }
+
+    switch(yjustify)
+    {
+    default: case CS_YJUST_NONE: break;
+    
+    case CS_YJUST_CENTER:        //centered
+        ypos = (winheight - height) / 2;
+        ypos += yadjust;
+        if(yoffset < 0)    ypos += (height - __cardheight);
+        break;
+
+    case CS_YJUST_BOTTOM:        //bottom-aligned
+        ypos = winheight - __cardheight;//height - 20;
+        ypos += yadjust;
+        break;
+    }
+
+}
+
+
+void CardRegion::Flash(int count, int milliseconds)
+{
+    if(count <= 0) return;
+
+    nFlashCount        = count;
+    fFlashVisible   = false;
+    uFlashTimer        = SetTimer((HWND)parentWnd, (WPARAM)this, milliseconds, 0);
+    
+    parentWnd.Redraw();
+}
+
+void CardRegion::StopFlash()
+{
+    if(uFlashTimer != (UINT)-1)
+    {
+        KillTimer((HWND)parentWnd, uFlashTimer);
+        nFlashCount        = 0;
+        uFlashTimer        = (UINT)-1;
+        fFlashVisible    = true;
+    }
+}
+
+void CardRegion::DoFlash()
+{
+    if(uFlashTimer != (UINT)-1)
+    {
+        fFlashVisible = !fFlashVisible;
+
+        if(--nFlashCount == 0)
+        {
+            KillTimer((HWND)parentWnd, uFlashTimer);
+            uFlashTimer = (UINT)-1;
+            fFlashVisible = true;
+        }
+    
+        parentWnd.Redraw();
+    }
+}
+
+int CardRegion::Id()
+{
+    return id;
+}
+
+void CardRegion::SetEmptyImage(UINT uImage)
+{
+    switch(uImage)
+    {
+    case CS_EI_NONE: case CS_EI_SUNK:
+        uEmptyImage = uImage;
+        break;
+
+    default:
+        uEmptyImage = CS_EI_NONE;
+        break;
+    }
+    
+}
+
+void CardRegion::SetBackCardIdx(UINT uBackIdx)
+{
+    if(uBackIdx >= 52 && uBackIdx <= 68)
+        nBackCardIdx = uBackIdx;
+}
+
+void CardRegion::SetCardStack(const CardStack &cs)
+{ 
+    //make a complete copy of the specified stack..
+    cardstack = cs; 
+
+    // Update the face-direction and stack-size
+    Update();
+}
+
+const CardStack & CardRegion::GetCardStack()
+{ 
+    //return reference to our internal stack
+    return cardstack; 
+}
+
+//
+//    Update specified card-stack using THIS stack's
+//  face direction rules!
+//
+void CardRegion::UpdateFaceDir(CardStack &cards)
+{
+    int i, n, num;
+
+    num = cards.NumCards();
+
+    //Now apply the face direction rules..
+    switch(uFaceDirType)
+    {
+    case CS_FACE_UP:
+
+        for(i = 0; i < num; i++)
+        {
+            cards[i].SetFaceUp(true);
+        }
+
+        break;
+
+    case CS_FACE_DOWN:
+
+        for(i = 0; i < num; i++)
+        {
+            cards[i].SetFaceUp(false);
+        }
+
+        break;
+
+    case CS_FACE_DOWNUP:
+
+        num = cardstack.NumCards();
+        n = min(nFaceDirOption, num);
+
+        //bottom n cards..
+        for(i = 0; i < n; i++)
+        {
+            cards[num - i - 1].SetFaceUp(false);
+        }
+
+        for(i = n; i < num; i++)
+        {
+            cards[num - i - 1].SetFaceUp(true);
+        }
+
+        break;
+
+    case CS_FACE_UPDOWN:
+
+        num = cardstack.NumCards();
+        n = min(nFaceDirOption, num);
+
+        for(i = 0; i < n; i++)
+        {
+            cards[num - i - 1].SetFaceUp(true);
+        }
+
+        for(i = n; i < num; i++)
+        {
+            cards[num - i - 1].SetFaceUp(false);
+        }
+
+        break;
+
+    case CS_FACE_ANY:    //cards can be any orientation
+    default:
+        break;
+    }
+}
+
+bool CardRegion::MoveCard(CardRegion *pDestStack, int nNumCards, bool fAnimate)
+{
+    HDC hdc;
+
+    int x, y;
+
+    if(pDestStack == 0) return false; //{ forcedfacedir = -1 ;return 0; }
+
+    if(nNumCards < 0 || nNumCards > cardstack.NumCards())
+        return false;
+
+    x = xpos + xoffset * (nNumApparentCards - nNumCards);
+    y = ypos + yoffset * (nNumApparentCards - nNumCards);
+
+    oldx = x;
+    oldy = y;
+    
+    dragstack = cardstack.Pop(nNumCards);
+
+    //Alter the drag-stack so that it's cards are the same way up
+    //as the destination. Use the destination's drag-rules
+    //instead of this ones!!
+    CardStack temp;
+    temp.Push(pDestStack->GetCardStack());
+    temp.Push(dragstack);
+
+    pDestStack->UpdateFaceDir(temp);
+
+    dragstack = temp.Pop(nNumCards);
+
+    if(fAnimate)
+    {
+        iNumDragCards = nNumCards;
+        PrepareDragBitmaps(nNumCards);
+    }
+
+    Update();        //Update this stack's size+card count
+
+    if(fAnimate)
+    {
+        hdc = GetDC((HWND)parentWnd);
+
+        ZoomCard(hdc, x, y, pDestStack);
+        
+        ReleaseDC((HWND)parentWnd, hdc);
+        ReleaseDragBitmaps();
+    }
+
+    // Get a copy of the cardstack
+    CardStack cs = pDestStack->GetCardStack();
+    cs.Push(dragstack);
+    
+    pDestStack->SetCardStack(cs);
+    
+    //cs = pDestStack->GetCardStack();
+    //pDestStack->Update();
+    //pDestStack->UpdateFaceDir(cs);
+
+    RedrawIfNotDim(pDestStack, false);
+
+    //forcedfacedir = -1;
+    return true;
+}
+
+//
+//    Simple wrappers
+//
+int CardRegion::NumCards() const
+{
+    if(fMouseDragging)
+        return cardstack.NumCards() + dragstack.NumCards();
+    else
+        return cardstack.NumCards(); 
+}
+
+bool CardRegion::Lock()
+{
+    DWORD dw = WaitForSingleObject(mxlock, 0);
+
+    if(dw == WAIT_OBJECT_0)
+    {
+        //TRACE("LockStack succeeded\n");
+        return true; 
+    }
+    else
+    {
+        //TRACE("LockStack failed\n");
+        return false;
+    }
+    return false;
+}
+
+bool CardRegion::UnLock()
+{
+    if(ReleaseMutex(mxlock))
+    {
+        //TRACE("Unlocking stack\n");
+        return true;
+    }
+    else
+    {
+        //TRACE("Unlocking stack failed\n");    
+        return false;
+    }
+}
+
+bool CardRegion::PlayCard(CardRegion *pDestStack, int value, int num)
+{
+    //search the stack for the specified card value...
+    while(num--)
+    {
+        for(int i = 0; i < cardstack.NumCards(); i++)
+        {
+            if(cardstack[i].HiVal() == value)
+            {
+                //swap the card with one at top pos...
+                Card card = cardstack.RemoveCard(i);
+                cardstack.Push(card);
+
+                Redraw();
+
+                MoveCard(pDestStack, 1, true);
+                break;
+            }
+        }
+    }
+
+    return true;
+}
+
+//
+//    Redraw the current stack if it has a different
+//    layout than the comparison stack.
+//
+void CardRegion::RedrawIfNotDim(CardRegion *pCompare, bool fFullRedraw)
+{
+    //
+    //
+    //
+    if( pCompare->xoffset != xoffset || 
+        pCompare->yoffset != yoffset || 
+        pCompare->nThreedCount != nThreedCount ||
+        pCompare->uFaceDirType != uFaceDirType ||
+        pCompare->uFaceDirType != CS_FACE_ANY
+        )
+    {
+        if(fFullRedraw)
+            parentWnd.Redraw();
+        else
+            pCompare->Redraw();
+    }
+    
+}
+
+//
+//    SimulateDrag mimicks the complete drag+drop process.
+//  It basically just a MoveCard(..), but it calls the
+//  event callbacks as well.
+//
+bool CardRegion::SimulateDrag(CardRegion *pDestStack, int iNumDragCards, bool fAnimate)
+{
+    if(pDestStack == 0)
+        return false;
+
+    if(CanDragCards(iNumDragCards) != false)
+    {
+        //make a list of the cards that would be in the drag list
+        CardStack tempstack = cardstack.Top(iNumDragCards);
+
+        if(pDestStack->CanDropCards(tempstack)) 
+        {
+            MoveCard(pDestStack, iNumDragCards, fAnimate);        
+                
+            if(RemoveCallback)
+                RemoveCallback(*this, iNumDragCards);
+
+            if(pDestStack->AddCallback)
+                pDestStack->AddCallback(*pDestStack, pDestStack->cardstack);
+        
+            RedrawIfNotDim(pDestStack, true);
+        }    
+
+    }
+
+    return true;
+}
index 1dc9498..d3b4179 100644 (file)
-#ifndef CARDREGION_INCLUDED\r
-#define CARDREGION_INCLUDED\r
-\r
-#include "globals.h"\r
-#include "cardstack.h"\r
-#include "cardlib.h"\r
-\r
-class CardWindow;\r
-\r
-//\r
-//     This class defines a physical card-stack,\r
-//     which draws the cards, supports\r
-//\r
-\r
-class CardRegion\r
-{\r
-       friend class CardWindow;\r
-       friend class CardStack;\r
-\r
-       //\r
-       //      Constructor is PRIVATE - only\r
-       //  a CardWindow can create cardstacks!\r
-       //\r
-       CardRegion(CardWindow &parent, int id, bool fVisible, \r
-               int x, int y, int xOffset, int yOffset);\r
-\r
-       ~CardRegion();\r
-\r
-public:\r
-\r
-       void SetBackColor(COLORREF cr);\r
-       \r
-       void              SetCardStack(const CardStack &cs);\r
-       const CardStack & GetCardStack();\r
-\r
-       //\r
-       //      Event-callback support\r
-       //\r
-       bool SetDragRule(UINT uDragType, pCanDragProc proc = 0);\r
-       bool SetDropRule(UINT uDropType, pCanDropProc proc = 0);\r
-       \r
-       void SetClickProc    (pClickProc proc);\r
-       void SetDblClickProc (pClickProc proc);\r
-\r
-       void SetAddCardProc    (pAddProc proc);\r
-       void SetRemoveCardProc (pRemoveProc proc);\r
-\r
-       //\r
-       //      Physical attribute support\r
-       //\r
-       bool SetThreedCount (int count);\r
-       void SetOffsets     (int x, int y);\r
-       void SetPos         (int x, int y);\r
-       void Show           (bool fShow);\r
-       bool IsVisible      ();\r
-\r
-       void SetEmptyImage      (UINT uImage);\r
-       void SetBackCardIdx (UINT uBackIdx);\r
-       void SetPlacement   (UINT xJustify, UINT yJustify, int xAdjust, int yAdjust);\r
-\r
-       void Update();\r
-       void Redraw();\r
-\r
-       void SetFaceDirection(UINT uDirType, int nOption);\r
-       UINT GetFaceDirection(int *pnOption);\r
-\r
-       void Flash(int count, int timeout);\r
-       void StopFlash();\r
-\r
-       int  Id();\r
-\r
-       CardWindow &GetCardWindow() { return parentWnd; }\r
-\r
-       bool PlayCard(CardRegion *pDestStack, int value, int num);\r
-       bool MoveCard(CardRegion *pDestStack, int nNumCards, bool fAnimate);\r
-       bool SimulateDrag(CardRegion *pDestStack, int nNumCards, bool fAnimate);\r
-\r
-       bool Lock();\r
-       bool UnLock();\r
-\r
-       //\r
-       //      Common wrappers for the CardStack object\r
-       //\r
-       int         NumCards() const;\r
-       void        NewDeck()        { cardstack.NewDeck();  }\r
-       void        Shuffle()        { cardstack.Shuffle();  }\r
-       void        Clear()          { cardstack.Clear();    }\r
-\r
-       void            Reverse()        { cardstack.Reverse();  }\r
-       \r
-       void            Push(const Card card)     { cardstack.Push(card); }\r
-       void            Push(const CardStack &cs) { cardstack.Push(cs);   }\r
-\r
-       Card            Pop()          { return cardstack.Pop();      }\r
-       CardStack       Pop(int items) { return cardstack.Pop(items); }\r
-\r
-       Card            Top()          { return cardstack.Top();      }\r
-       CardStack       Top(int items) { return cardstack.Top(items); }\r
-\r
-\r
-private:\r
-\r
-       void DoFlash();\r
-       void RedrawIfNotDim(CardRegion *compare, bool fFullRedraw);\r
-\r
-       void UpdateFaceDir(CardStack &cards);\r
-       void Clip(HDC hdc);\r
-       void Render(HDC hdc);\r
-       int      GetOverlapRatio(int x, int y, int width, int height);\r
-\r
-       void MoveDragCardTo(HDC hdc, int x, int y);\r
-       void ZoomCard(HDC hdc, int xpos, int ypos, CardRegion *dest);\r
-\r
-       void RenderBottomMost(HDC hdc, int minustopmost = 0);\r
-       void PrepareDragBitmaps(int numtodrag);\r
-       void PrepareDragBitmapsThreed(int numtodrag);\r
-       void ReleaseDragBitmaps(void);\r
-\r
-       bool CanDragCards(int iNumCards);\r
-       bool CanDropCards(CardStack &cards);\r
-       \r
-       void CalcApparentCards();\r
-       int      CalcApparentCards(int realnum);\r
-\r
-       void UpdateSize();\r
-       void AdjustPosition(int winwidth, int winheight);\r
-\r
-       bool IsPointInStack(int x, int y);\r
-\r
-       int       GetNumDragCards(int x, int y);\r
-       bool  OnLButtonDown(int x, int y);\r
-       bool  OnLButtonDblClk(int x, int y);\r
-       bool  OnMouseMove(int x, int y);\r
-       bool  OnLButtonUp(int x, int y);\r
-\r
-       \r
-       //\r
-       //      Private data members\r
-       //\r
-\r
-       int             id;\r
-       \r
-       CardWindow &parentWnd;\r
-       \r
-       CardStack  cardstack;   //cards in this stack\r
-       CardStack  dragstack;   //cards which we might be dragging\r
-\r
-       bool    fMouseDragging;\r
-\r
-       int             xpos;                   //coordinates of stack\r
-       int             ypos;\r
-\r
-       int             xoffset;                //direction that cards take\r
-       int             yoffset;\r
-\r
-       int             width;                  //stack-size of all cards\r
-       int             height;\r
-\r
-       //\r
-       //      justify / placement vars\r
-       int             xjustify;\r
-       int             yjustify;\r
-       int             xadjust;\r
-       int             yadjust;\r
-\r
-       //\r
-       //      Used for mouse-dragging / moving cards\r
-       //\r
-       int             iNumDragCards;\r
-       int             mousexoffset;   \r
-       int             mouseyoffset;\r
-       int             oldx;\r
-       int             oldy;\r
-       \r
-       int             nDragCardWidth;\r
-       int             nDragCardHeight;\r
-       \r
-       HDC             hdcBackGnd;\r
-       HBITMAP hbmBackGnd;\r
-       HDC             hdcDragCard;\r
-       HBITMAP hbmDragCard;\r
-\r
-       int             nNumApparentCards;\r
-       int             nThreedCount;\r
-       bool    fVisible;\r
-       \r
-       int             nFlashCount;\r
-       bool    fFlashVisible;\r
-       UINT    uFlashTimer;\r
-\r
-       COLORREF crBackgnd;\r
-\r
-       UINT    uEmptyImage;\r
-       UINT    uFaceDirType;\r
-       int             nFaceDirOption;\r
-       int             nBackCardIdx;\r
-\r
-       UINT    uDragRule;\r
-       UINT    uDropRule;\r
-       \r
-       //\r
-       //      Stack callback support\r
-       //      \r
-       pCanDragProc    CanDragCallback;\r
-       pCanDropProc    CanDropCallback;\r
-       pClickProc              ClickCallback;\r
-       pClickProc              DblClickCallback;\r
-       pAddProc                AddCallback;\r
-       pRemoveProc             RemoveCallback;\r
-\r
-       //locking mechanism to prevent user dragging etc\r
-       HANDLE                  mxlock;         \r
-};\r
-\r
-#endif\r
-\r
+#ifndef CARDREGION_INCLUDED
+#define CARDREGION_INCLUDED
+
+#include "globals.h"
+#include "cardstack.h"
+#include "cardlib.h"
+
+class CardWindow;
+
+//
+//     This class defines a physical card-stack,
+//     which draws the cards, supports
+//
+
+class CardRegion
+{
+       friend class CardWindow;
+       friend class CardStack;
+
+       //
+       //      Constructor is PRIVATE - only
+       //  a CardWindow can create cardstacks!
+       //
+       CardRegion(CardWindow &parent, int id, bool fVisible, 
+               int x, int y, int xOffset, int yOffset);
+
+       ~CardRegion();
+
+public:
+
+       void SetBackColor(COLORREF cr);
+       
+       void              SetCardStack(const CardStack &cs);
+       const CardStack & GetCardStack();
+
+       //
+       //      Event-callback support
+       //
+       bool SetDragRule(UINT uDragType, pCanDragProc proc = 0);
+       bool SetDropRule(UINT uDropType, pCanDropProc proc = 0);
+       
+       void SetClickProc    (pClickProc proc);
+       void SetDblClickProc (pClickProc proc);
+
+       void SetAddCardProc    (pAddProc proc);
+       void SetRemoveCardProc (pRemoveProc proc);
+
+       //
+       //      Physical attribute support
+       //
+       bool SetThreedCount (int count);
+       void SetOffsets     (int x, int y);
+       void SetPos         (int x, int y);
+       void Show           (bool fShow);
+       bool IsVisible      ();
+
+       void SetEmptyImage      (UINT uImage);
+       void SetBackCardIdx (UINT uBackIdx);
+       void SetPlacement   (UINT xJustify, UINT yJustify, int xAdjust, int yAdjust);
+
+       void Update();
+       void Redraw();
+
+       void SetFaceDirection(UINT uDirType, int nOption);
+       UINT GetFaceDirection(int *pnOption);
+
+       void Flash(int count, int timeout);
+       void StopFlash();
+
+       int  Id();
+
+       CardWindow &GetCardWindow() { return parentWnd; }
+
+       bool PlayCard(CardRegion *pDestStack, int value, int num);
+       bool MoveCard(CardRegion *pDestStack, int nNumCards, bool fAnimate);
+       bool SimulateDrag(CardRegion *pDestStack, int nNumCards, bool fAnimate);
+
+       bool Lock();
+       bool UnLock();
+
+       //
+       //      Common wrappers for the CardStack object
+       //
+       int         NumCards() const;
+       void        NewDeck()        { cardstack.NewDeck();  }
+       void        Shuffle()        { cardstack.Shuffle();  }
+       void        Clear()          { cardstack.Clear();    }
+
+       void            Reverse()        { cardstack.Reverse();  }
+       
+       void            Push(const Card card)     { cardstack.Push(card); }
+       void            Push(const CardStack &cs) { cardstack.Push(cs);   }
+
+       Card            Pop()          { return cardstack.Pop();      }
+       CardStack       Pop(int items) { return cardstack.Pop(items); }
+
+       Card            Top()          { return cardstack.Top();      }
+       CardStack       Top(int items) { return cardstack.Top(items); }
+
+
+private:
+
+       void DoFlash();
+       void RedrawIfNotDim(CardRegion *compare, bool fFullRedraw);
+
+       void UpdateFaceDir(CardStack &cards);
+       void Clip(HDC hdc);
+       void Render(HDC hdc);
+       int      GetOverlapRatio(int x, int y, int width, int height);
+
+       void MoveDragCardTo(HDC hdc, int x, int y);
+       void ZoomCard(HDC hdc, int xpos, int ypos, CardRegion *dest);
+
+       void RenderBottomMost(HDC hdc, int minustopmost = 0);
+       void PrepareDragBitmaps(int numtodrag);
+       void PrepareDragBitmapsThreed(int numtodrag);
+       void ReleaseDragBitmaps(void);
+
+       bool CanDragCards(int iNumCards);
+       bool CanDropCards(CardStack &cards);
+       
+       void CalcApparentCards();
+       int      CalcApparentCards(int realnum);
+
+       void UpdateSize();
+       void AdjustPosition(int winwidth, int winheight);
+
+       bool IsPointInStack(int x, int y);
+
+       int       GetNumDragCards(int x, int y);
+       bool  OnLButtonDown(int x, int y);
+       bool  OnLButtonDblClk(int x, int y);
+       bool  OnMouseMove(int x, int y);
+       bool  OnLButtonUp(int x, int y);
+
+       
+       //
+       //      Private data members
+       //
+
+       int             id;
+       
+       CardWindow &parentWnd;
+       
+       CardStack  cardstack;   //cards in this stack
+       CardStack  dragstack;   //cards which we might be dragging
+
+       bool    fMouseDragging;
+
+       int             xpos;                   //coordinates of stack
+       int             ypos;
+
+       int             xoffset;                //direction that cards take
+       int             yoffset;
+
+       int             width;                  //stack-size of all cards
+       int             height;
+
+       //
+       //      justify / placement vars
+       int             xjustify;
+       int             yjustify;
+       int             xadjust;
+       int             yadjust;
+
+       //
+       //      Used for mouse-dragging / moving cards
+       //
+       int             iNumDragCards;
+       int             mousexoffset;   
+       int             mouseyoffset;
+       int             oldx;
+       int             oldy;
+       
+       int             nDragCardWidth;
+       int             nDragCardHeight;
+       
+       HDC             hdcBackGnd;
+       HBITMAP hbmBackGnd;
+       HDC             hdcDragCard;
+       HBITMAP hbmDragCard;
+
+       int             nNumApparentCards;
+       int             nThreedCount;
+       bool    fVisible;
+       
+       int             nFlashCount;
+       bool    fFlashVisible;
+       UINT    uFlashTimer;
+
+       COLORREF crBackgnd;
+
+       UINT    uEmptyImage;
+       UINT    uFaceDirType;
+       int             nFaceDirOption;
+       int             nBackCardIdx;
+
+       UINT    uDragRule;
+       UINT    uDropRule;
+       
+       //
+       //      Stack callback support
+       //      
+       pCanDragProc    CanDragCallback;
+       pCanDropProc    CanDropCallback;
+       pClickProc              ClickCallback;
+       pClickProc              DblClickCallback;
+       pAddProc                AddCallback;
+       pRemoveProc             RemoveCallback;
+
+       //locking mechanism to prevent user dragging etc
+       HANDLE                  mxlock;         
+};
+
+#endif
+
index a5da84d..2f20010 100644 (file)
-//\r
-//    CardLib - CardRegion drawing support\r
-//\r
-//    Freeware\r
-//    Copyright J Brown 2001\r
-//\r
-#include <windows.h>\r
-#include "cardlib.h"\r
-#include "cardregion.h"\r
-#include "cardcolor.h"\r
-\r
-HPALETTE UseNicePalette(HDC hdc, HPALETTE hPalette);\r
-void PaintRect(HDC hdc, RECT *rect, COLORREF colour);\r
-void CardBlt(HDC hdc, int x, int y, int nCardNum);\r
-void DrawCard(HDC hdc, int x, int y, HDC hdcSource, int width, int height);\r
-\r
-//\r
-//    Draw specified card at position x, y\r
-//    xoff   - source offset from left of card\r
-//    yoff   - source offset from top of card\r
-//    width  - width to draw\r
-//    height - height to draw\r
-//\r
-void CardBlt(HDC hdc, int x, int y, int nCardNum)//, int xoff, int yoff, int width, int height)\r
-{\r
-    int sx = nCardNum * __cardwidth;\r
-    int sy = 0;\r
-    int width  = __cardwidth;\r
-    int height = __cardheight;\r
-\r
-    //draw main center band\r
-    BitBlt(hdc, x+2, y, width - 4, height, __hdcCardBitmaps, sx+2, sy+0, SRCCOPY);\r
-\r
-    //draw the two bits to the left\r
-    BitBlt(hdc, x,   y+2, 1, height - 4, __hdcCardBitmaps, sx+0, sy+2, SRCCOPY);\r
-    BitBlt(hdc, x+1, y+1, 1, height - 2, __hdcCardBitmaps, sx+1, sy+1, SRCCOPY);\r
-\r
-    //draw the two bits to the right\r
-    BitBlt(hdc, x+width-2, y+1, 1, height - 2, __hdcCardBitmaps, sx+width-2, sy+1, SRCCOPY);\r
-    BitBlt(hdc, x+width-1, y+2, 1, height - 4, __hdcCardBitmaps, sx+width-1, sy+2, SRCCOPY);\r
-}\r
-\r
-//\r
-//    Draw a shape this this:\r
-//\r
-//   ++++++++++++\r
-//  ++++++++++++++\r
-// ++            ++\r
-//\r
-void DrawHorzCardStrip(HDC hdc, int x, int y, int nCardNum, int height, BOOL fDrawTips)\r
-{\r
-    int sx  = nCardNum * __cardwidth;\r
-    int sy  = 0;\r
-    int one = 1;\r
-    int two = 2;\r
-    BOOL tips = fDrawTips ? FALSE : TRUE;\r
-\r
-    if(height == 0) return;\r
-\r
-    if(height < 0)\r
-    {\r
-        sy = sy + __cardheight;\r
-        y  -= height;\r
-        one = -one;\r
-        two = -two;\r
-    }\r
-\r
-    // draw the main vertical band\r
-    //\r
-    BitBlt(hdc, x + 2, y, __cardwidth - 4, height, __hdcCardBitmaps, sx+2, sy, SRCCOPY);\r
-\r
-    //if(height <= 1) return;\r
-\r
-    // draw the "lips" at the left and right\r
-    BitBlt(hdc, x+1,             y+one, 1, height-one*tips, __hdcCardBitmaps, sx+1,             sy+one, SRCCOPY);\r
-    BitBlt(hdc, x+__cardwidth-2, y+one, 1, height-one*tips, __hdcCardBitmaps, sx+__cardwidth-2, sy+one, SRCCOPY);\r
-\r
-    //if(height <= 2) return;\r
-\r
-    // draw the outer-most lips\r
-    BitBlt(hdc, x,               y+two, 1, height-two*tips, __hdcCardBitmaps, sx,               sy+two, SRCCOPY);\r
-    BitBlt(hdc, x+__cardwidth-1, y+two, 1, height-two*tips, __hdcCardBitmaps, sx+__cardwidth-1, sy+two, SRCCOPY);    \r
-}\r
-\r
-//\r
-//    Draw a shape like this:\r
-//\r
-//     +++\r
-//      +++\r
-//   +++\r
-//   +++\r
-//   +++\r
-//   +++\r
-//   +++\r
-//   +++\r
-//    +++\r
-//     +++\r
-//\r
-//\r
-void DrawVertCardStrip(HDC hdc, int x, int y, int nCardNum, int width, BOOL fDrawTips)\r
-{\r
-    int sx  = nCardNum * __cardwidth;\r
-    int sy  = 0;\r
-    int one = 1;\r
-    int two = 2;\r
-    BOOL tips = fDrawTips ? FALSE : TRUE;\r
-\r
-    if(width == 0) return;\r
-    \r
-\r
-    if(width < 0)\r
-    {\r
-        sx = sx + __cardwidth;\r
-        x  -= width;\r
-        one = -1;\r
-        two = -2;\r
-    }\r
-\r
-    // draw the main vertical band\r
-    //\r
-    BitBlt(hdc, x, y + 2, width, __cardheight - 4, __hdcCardBitmaps, sx, sy+2, SRCCOPY);\r
-\r
-    //if(width <= 1) return;\r
-\r
-    // draw the "lips" at the top and bottom\r
-    BitBlt(hdc, x+one, y+1,              width-one*tips, 1, __hdcCardBitmaps, sx+one, sy + 1,              SRCCOPY);\r
-    BitBlt(hdc, x+one, y+__cardheight-2, width-one*tips, 1, __hdcCardBitmaps, sx+one, sy + __cardheight-2, SRCCOPY);\r
-\r
-    //if(width <= 2) return;\r
-\r
-    // draw the outer-most lips\r
-    BitBlt(hdc, x+two, y,                width-two*tips, 1, __hdcCardBitmaps, sx+two, sy,                  SRCCOPY);\r
-    BitBlt(hdc, x+two, y+__cardheight-1, width-two*tips, 1, __hdcCardBitmaps, sx+two, sy + __cardheight-1, SRCCOPY);\r
-}\r
-\r
-//\r
-//    xdir -   <0 or >0\r
-//    ydir -   <0 or >0\r
-//\r
-void DrawCardCorner(HDC hdc, int x, int y, int cardval, int xdir, int ydir)\r
-{\r
-    int sx = cardval * __cardwidth;\r
-    int sy = 0;\r
-\r
-    HDC hdcSource = __hdcCardBitmaps;\r
-\r
-    if(xdir < 0) \r
-    {\r
-        x  += __cardwidth + xdir - 1;\r
-        sx += __cardwidth + xdir - 1;\r
-    }\r
-    else\r
-    {\r
-        x  += xdir;\r
-        sx += xdir;\r
-    }\r
-\r
-    if(ydir < 0) \r
-    {\r
-        y  += __cardheight + ydir - 1;\r
-        sy += __cardheight + ydir - 1;\r
-    }\r
-    else\r
-    {\r
-        y  += ydir;\r
-        sy += ydir;\r
-    }\r
-\r
-    //convert x,y directions to -1, +1\r
-    xdir = xdir < 0 ? -1 : 1;\r
-    ydir = ydir < 0 ? -1 : 1;\r
-\r
-    SetPixel(hdc, x+xdir, y ,     GetPixel(hdcSource, sx+xdir, sy));\r
-    SetPixel(hdc, x,      y,      GetPixel(hdcSource, sx,      sy));\r
-    SetPixel(hdc, x,      y+ydir, GetPixel(hdcSource, sx,      sy+ydir));\r
-\r
-}\r
-\r
-//\r
-//    Draw a card (i.e. miss out the corners)\r
-//\r
-void DrawCard(HDC hdc, int x, int y, HDC hdcDragCard, int width, int height)\r
-{\r
-    //draw main center band\r
-    BitBlt(hdc, x+2, y, width - 4, height, hdcDragCard, 2, 0, SRCCOPY);\r
-\r
-    //draw the two bits to the left\r
-    BitBlt(hdc, x,   y+2, 1, height - 4, hdcDragCard, 0, 2, SRCCOPY);\r
-    BitBlt(hdc, x+1, y+1, 1, height - 2, hdcDragCard, 1, 1, SRCCOPY);\r
-\r
-    //draw the two bits to the right\r
-    BitBlt(hdc, x+width-2, y+1, 1, height - 2, hdcDragCard, width-2, 1, SRCCOPY);\r
-    BitBlt(hdc, x+width-1, y+2, 1, height - 4, hdcDragCard, width-1, 2, SRCCOPY);\r
-}\r
-\r
-//\r
-//    Clip a card SHAPE - basically any rectangle\r
-//  with rounded corners\r
-//\r
-int ClipCard(HDC hdc, int x, int y, int width, int height)\r
-{\r
-    ExcludeClipRect(hdc, x+2,        y,     x+2+width-4, y+  height);\r
-    ExcludeClipRect(hdc, x,            y+2, x+1,          y+2+height-4);\r
-    ExcludeClipRect(hdc, x+1,        y+1, x+2,          y+1+height-2);\r
-    ExcludeClipRect(hdc, x+width-2, y+1, x+width-2+1, y+1+height-2);\r
-    ExcludeClipRect(hdc, x+width-1, y+2, x+width-1+1, y+2+height-4);\r
-    return 0;\r
-}\r
-\r
-void CardRegion::Clip(HDC hdc)\r
-{\r
-    int numtoclip;\r
-\r
-    if(fVisible == false) \r
-        return;\r
-\r
-    Update();                //Update this stack's size+card count\r
-    numtoclip = nNumApparentCards;\r
-\r
-    //if we are making this stack flash on/off, then only \r
-    //clip the stack for drawing if the flash is in its ON state\r
-    if(nFlashCount != 0)\r
-    {\r
-        if(fFlashVisible == FALSE)\r
-            numtoclip = 0;\r
-    }\r
-\r
-    //if offset along a diagonal\r
-    if(xoffset != 0 && yoffset != 0 && cardstack.NumCards() != 0)\r
-    {\r
-        for(int j = 0; j < numtoclip; j ++)\r
-        {    \r
-            ClipCard(hdc, xpos + xoffset * j, ypos + yoffset * j, __cardwidth, __cardheight);\r
-        }    \r
-    }\r
-    //otherwise if just offset along a horizontal/vertical axis\r
-    else\r
-    {\r
-        if(yoffset < 0 && numtoclip > 0)\r
-        {\r
-            ClipCard(hdc, xpos, ypos-((numtoclip-1)*-yoffset), width, height);\r
-        }\r
-        else if(xoffset < 0 && numtoclip > 0)\r
-        {\r
-            ClipCard(hdc, xpos-((numtoclip-1)*-xoffset), ypos, width, height);\r
-        }\r
-        else\r
-        {\r
-            ClipCard(hdc, xpos, ypos, width, height);\r
-        }\r
-    }\r
-\r
-}\r
-\r
-void CardRegion::Render(HDC hdc)\r
-{\r
-    int cardnum = 0;\r
-    int numtodraw;\r
-    BOOL fDrawTips;\r
-    \r
-    Update();            //Update this stack's card count + size\r
-\r
-    numtodraw = nNumApparentCards;\r
-\r
-    if(nFlashCount != 0)\r
-    {\r
-        if(fFlashVisible == false)\r
-            numtodraw = 0;\r
-    }\r
-\r
-    if(fVisible == 0) return;\r
-    \r
-    cardnum = cardstack.NumCards() - numtodraw;\r
-    int counter;\r
-\r
-    for(counter = 0; counter < numtodraw; counter++)\r
-    {\r
-        int cardval;\r
-        \r
-        int x = xoffset * counter + xpos;\r
-        int y = yoffset * counter + ypos;\r
-\r
-        //if about to draw last card, then actually draw the top card\r
-        if(counter == numtodraw - 1) cardnum = cardstack.NumCards() - 1;\r
-        \r
-        Card card = cardstack.cardlist[cardnum];\r
-        cardval = card.Idx();\r
-        \r
-        if(card.FaceDown())\r
-            cardval = nBackCardIdx;    //card-back\r
-            \r
-        //only draw the visible part of the card\r
-        if(counter < numtodraw - 1)\r
-        {\r
-            if(yoffset != 0 && xoffset != 0)\r
-                fDrawTips = FALSE;\r
-            else\r
-                fDrawTips = TRUE;\r
-\r
-            if(yoffset != 0 && abs(xoffset) == 1 ||    xoffset != 0 && abs(yoffset) == 1)\r
-                fDrawTips = TRUE;\r
-\r
-            //draw horizontal strips\r
-            if(yoffset > 0) \r
-            {\r
-                DrawHorzCardStrip(hdc, x, y, cardval, yoffset, fDrawTips);\r
-            }\r
-            else if(yoffset < 0)\r
-            {\r
-                DrawHorzCardStrip(hdc, x, y+__cardheight+yoffset, cardval, yoffset, fDrawTips);\r
-            }\r
-\r
-            //draw some vertical bars\r
-            if(xoffset > 0)\r
-            {\r
-                DrawVertCardStrip(hdc, x, y, cardval, xoffset, fDrawTips);\r
-            }\r
-            else if(xoffset < 0)\r
-            {\r
-                DrawVertCardStrip(hdc, x+__cardwidth+xoffset, y, cardval, xoffset, fDrawTips);\r
-            }\r
-\r
-            if(yoffset != 0 && xoffset != 0)//fDrawTips == FALSE)\r
-            {\r
-                //if we didn't draw any tips, then this is a 2-dim stack\r
-                //(i.e, it goes at a diagonal).\r
-                //in this case, we need to fill in the small triangle in\r
-                //each corner!\r
-                DrawCardCorner(hdc, x, y, cardval, xoffset, yoffset);\r
-            }\r
-        }\r
-        //if the top card, draw the whole thing\r
-        else\r
-        {\r
-            CardBlt(hdc, x, y, cardval);\r
-        }\r
-\r
-        cardnum ++;\r
-\r
-    } //end of index\r
-    \r
-    if(counter == 0)    //if the cardstack is empty, then draw it that way\r
-    {\r
-        int x = xpos;\r
-        int y = ypos;\r
-        \r
-        switch(uEmptyImage)\r
-        {\r
-        default: case CS_EI_NONE:\r
-            //this wipes the RECT variable, so watch out!\r
-            //SetRect(&rect, x, y, x+__cardwidth, y+__cardheight);\r
-            //PaintRect(hdc, &rect, MAKE_PALETTERGB(crBackgnd));\r
-            parentWnd.PaintCardRgn(hdc, x, y, __cardwidth, __cardheight, x, y);\r
-            break;\r
-            \r
-        case CS_EI_SUNK:    //case CS_EI_CIRC: case CS_EI_X:\r
-            DrawCard(hdc, x, y, __hdcPlaceHolder, __cardwidth, __cardheight);\r
-            break;\r
-        }\r
-        \r
-    }\r
-\r
-    return;\r
-}\r
-\r
-int calc_offset(int offset, int numcards, int numtodrag, int realvisible)\r
-{\r
-    if(offset >= 0)\r
-        return -offset * numcards;\r
-    else\r
-        return -offset * (numtodrag)       + \r
-               -offset * (realvisible - 1);\r
-}\r
-\r
-void CardRegion::PrepareDragBitmaps(int numtodrag)\r
-{\r
-    RECT rect;\r
-    HDC hdc;\r
-    int icard;\r
-    int numcards = cardstack.NumCards();\r
-    int xoff, yoff;\r
-\r
-    if(nThreedCount > 1)\r
-    {\r
-        PrepareDragBitmapsThreed(numtodrag);\r
-        return;\r
-    }\r
-\r
-    //work out how big the bitmaps need to be\r
-    nDragCardWidth  = (numtodrag - 1) * abs(xoffset) + __cardwidth;\r
-    nDragCardHeight = (numtodrag - 1) * abs(yoffset) + __cardheight;\r
-\r
-    //Create bitmap for the back-buffer\r
-    hdc = GetDC(NULL);\r
-    hdcBackGnd = CreateCompatibleDC(hdc);\r
-    hbmBackGnd = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight);\r
-    SelectObject(hdcBackGnd, hbmBackGnd);\r
-\r
-    //Create bitmap for the drag-image\r
-    hdcDragCard = CreateCompatibleDC(hdc);\r
-    hbmDragCard = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight);\r
-    SelectObject(hdcDragCard, hbmDragCard);\r
-    ReleaseDC(NULL, hdc);\r
-\r
-    UseNicePalette(hdcBackGnd,  __hPalette);\r
-    UseNicePalette(hdcDragCard, __hPalette);\r
-\r
-    int realvisible = numcards / nThreedCount;\r
-\r
-    //if(numcards > 0 && realvisible == 0) realvisible = 1;\r
-    int iwhichcard = numcards - 1;\r
-    if(nThreedCount == 1) iwhichcard = 0;\r
-\r
-    //grab the first bit of background so we can prep the back buffer; do this by\r
-    //rendering the card stack (minus the card we are dragging) to the temporary\r
-    //background buffer, so it appears if we have lifted the card from the stack\r
-    //PaintRect(hdcBackGnd, &rect, crBackgnd);\r
-    SetRect(&rect, 0, 0, nDragCardWidth, nDragCardHeight);\r
\r
-    xoff = calc_offset(xoffset, numcards, numtodrag, realvisible);\r
-    yoff = calc_offset(yoffset, numcards, numtodrag, realvisible);\r
-    \r
-    parentWnd.PaintCardRgn(hdcBackGnd, 0, 0, nDragCardWidth, nDragCardHeight, xpos - xoff,    ypos - yoff);\r
-\r
-    //\r
-    //    Render the cardstack into the back-buffer. The stack\r
-    //    has already had the dragcards removed, so just draw\r
-    //    what is left\r
-    //\r
-    for(icard = 0; icard < realvisible; icard++)\r
-    {\r
-        Card card = cardstack.cardlist[iwhichcard];\r
-        int nCardVal;\r
-        \r
-        nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx;\r
-\r
-        xoff = xoffset * icard + calc_offset(xoffset, numcards, numtodrag, realvisible);//- xoffset * ((numcards+numtodrag) / nThreedCount - numtodrag);\r
-        yoff = yoffset * icard + calc_offset(yoffset, numcards, numtodrag, realvisible);//- yoffset * ((numcards+numtodrag) / nThreedCount - numtodrag);\r
-\r
-        CardBlt(hdcBackGnd, xoff, yoff, nCardVal);\r
-        iwhichcard++;\r
-    }\r
-    \r
-    //\r
-    // If there are no cards under this one, just draw the place holder\r
-    //\r
-    if(numcards == 0)   \r
-    {\r
-        int xoff = 0, yoff = 0;\r
-\r
-        if(xoffset < 0)    xoff = nDragCardWidth  -  __cardwidth;\r
-        if(yoffset < 0)    yoff = nDragCardHeight -  __cardheight;\r
-\r
-        switch(uEmptyImage)\r
-        {\r
-        case CS_EI_NONE:\r
-            //No need to draw anything: We already cleared the\r
-            //back-buffer before the main loop..\r
-\r
-            //SetRect(&rc, xoff, yoff, xoff+ __cardwidth, yoff + __cardheight);\r
-            //PaintRect(hdcBackGnd, &rc, MAKE_PALETTERGB(crBackgnd));\r
-            //parentWnd.PaintCardRgn(hdcBackGnd, xoff, yoff, __cardwidth, __cardheight, xpos, ypos);// + xoff, ypos + yoff);\r
-            break;\r
-\r
-        case CS_EI_SUNK:\r
-            DrawCard(hdcBackGnd, xoff, yoff, __hdcPlaceHolder, __cardwidth, __cardheight);\r
-            break;\r
-        }\r
-    }\r
-\r
-    //\r
-    //    now render the drag-cards into the dragcard image\r
-    //\r
-    PaintRect(hdcDragCard, &rect, crBackgnd);\r
-\r
-    for(icard = 0; icard < numtodrag; icard++)\r
-    {\r
-        int nCardVal;\r
-\r
-        if(xoffset >= 0) xoff =  xoffset * icard;\r
-        else              xoff = -xoffset * (numtodrag - icard - 1);\r
-            \r
-        if(yoffset >= 0) yoff =  yoffset * icard;\r
-        else             yoff = -yoffset * (numtodrag - icard - 1);\r
-\r
-        Card card = dragstack.cardlist[icard];\r
-        \r
-        nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx;\r
-\r
-        CardBlt(hdcDragCard, xoff, yoff, nCardVal);\r
-    }\r
-}\r
-\r
-void CardRegion::PrepareDragBitmapsThreed(int numtodrag)\r
-{\r
-    RECT rect;\r
-    HDC hdc;\r
-    int icard;\r
-    int numunder = 0;\r
-    int iwhichcard;\r
-\r
-    int numcards = cardstack.NumCards();\r
-\r
-    //work out how big the bitmaps need to be\r
-    nDragCardWidth  = (numtodrag - 1) * abs(xoffset) + __cardwidth;\r
-    nDragCardHeight = (numtodrag - 1) * abs(yoffset) + __cardheight;\r
-\r
-    //Create bitmap for the back-buffer\r
-    hdc = GetDC(NULL);\r
-    hdcBackGnd = CreateCompatibleDC(hdc);\r
-    hbmBackGnd = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight);\r
-    SelectObject(hdcBackGnd, hbmBackGnd);\r
-\r
-    //create bitmap for the drag-image\r
-    hdcDragCard = CreateCompatibleDC(hdc);\r
-    hbmDragCard = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight);\r
-    SelectObject(hdcDragCard, hbmDragCard);\r
-    ReleaseDC(NULL, hdc);\r
-\r
-    UseNicePalette(hdcBackGnd,  __hPalette);\r
-    UseNicePalette(hdcDragCard, __hPalette);\r
-\r
-    //grab the first bit of background so we can prep the back buffer; do this by\r
-    //rendering the card stack (minus the card we are dragging) to the temporary\r
-    //background buffer, so it appears if we have lifted the card from the stack\r
-    //--SetRect(&rect, 0, 0, nDragCardWidth, nDragCardHeight);\r
-    //--PaintRect(hdcBackGnd, &rect, crBackgnd);\r
-\r
-    int threedadjust = numcards  % nThreedCount == 0;\r
-    \r
-    numunder = CalcApparentCards(numcards);\r
-    iwhichcard = (numcards+numtodrag) - numunder - 1;\r
-    if(nThreedCount == 1) iwhichcard = 0;\r
-    \r
-    int xoff = calc_offset(xoffset, numunder, numtodrag, numunder);\r
-    int yoff = calc_offset(yoffset, numunder, numtodrag, numunder);\r
-\r
-    parentWnd.PaintCardRgn(hdcBackGnd, 0,0,    nDragCardWidth,nDragCardHeight,    xpos - xoff,ypos - yoff);\r
-\r
-    //\r
-    //    Render the cardstack into the back-buffer. The stack\r
-    //    has already had the dragcards removed, so just draw\r
-    //    what is left\r
-    //\r
-    for(icard = 0; icard < numunder; icard++)\r
-    {\r
-        Card card = cardstack.cardlist[iwhichcard];\r
-        int nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx;\r
-\r
-        CardBlt(hdcBackGnd, \r
-                xoffset * icard - xoffset*(numunder-numtodrag+threedadjust),\r
-                yoffset * icard - yoffset*(numunder-numtodrag+threedadjust),\r
-                nCardVal);\r
-\r
-        iwhichcard++;\r
-    }\r
-    \r
-    //\r
-    // If there are no cards under this one, just draw the place holder\r
-    //\r
-    if(numcards == 0)   \r
-    {\r
-        switch(uEmptyImage)\r
-        {\r
-        case CS_EI_NONE:\r
-            //no need! we've already cleared the whole\r
-            //back-buffer before the main loop!\r
-            //SetRect(&rect, 0, 0, __cardwidth, __cardheight);\r
-            //PaintRect(hdcBackGnd, &rect, MAKE_PALETTERGB(crBackgnd));\r
-            break;\r
-\r
-        case CS_EI_SUNK:\r
-            DrawCard(hdcBackGnd, 0, 0, __hdcPlaceHolder, __cardwidth, __cardheight);\r
-            break;\r
-    \r
-        }\r
-    }\r
-\r
-    //\r
-    //    now render the drag-cards into the dragcard image\r
-    //\r
-    PaintRect(hdcDragCard, &rect, crBackgnd);\r
-    \r
-    for(icard = 0; icard < numtodrag; icard++)\r
-    {\r
-        Card card = dragstack.cardlist[icard];\r
-        int nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx;\r
-\r
-        CardBlt(hdcDragCard, xoffset * icard, yoffset * icard, nCardVal);\r
-    }\r
-}\r
-\r
-void CardRegion::ReleaseDragBitmaps(void)\r
-{\r
-    //SelectObject(hdcBackGnd, hOld1);\r
-    DeleteObject(hbmBackGnd);\r
-    DeleteDC(hdcBackGnd);\r
-\r
-    //SelectObject(hdcDragCard, hOld2);\r
-    DeleteObject(hbmDragCard);\r
-    DeleteDC(hdcDragCard);\r
-}\r
-\r
-\r
-void CardRegion::Redraw()\r
-{\r
-    HDC hdc = GetDC((HWND)parentWnd);\r
-\r
-    Update();\r
-    Render(hdc);\r
-\r
-    ReleaseDC((HWND)parentWnd, hdc);\r
-}\r
+//
+//    CardLib - CardRegion drawing support
+//
+//    Freeware
+//    Copyright J Brown 2001
+//
+#include <windows.h>
+#include "cardlib.h"
+#include "cardregion.h"
+#include "cardcolor.h"
+
+HPALETTE UseNicePalette(HDC hdc, HPALETTE hPalette);
+void PaintRect(HDC hdc, RECT *rect, COLORREF colour);
+void CardBlt(HDC hdc, int x, int y, int nCardNum);
+void DrawCard(HDC hdc, int x, int y, HDC hdcSource, int width, int height);
+
+//
+//    Draw specified card at position x, y
+//    xoff   - source offset from left of card
+//    yoff   - source offset from top of card
+//    width  - width to draw
+//    height - height to draw
+//
+void CardBlt(HDC hdc, int x, int y, int nCardNum)//, int xoff, int yoff, int width, int height)
+{
+    int sx = nCardNum * __cardwidth;
+    int sy = 0;
+    int width  = __cardwidth;
+    int height = __cardheight;
+
+    //draw main center band
+    BitBlt(hdc, x+2, y, width - 4, height, __hdcCardBitmaps, sx+2, sy+0, SRCCOPY);
+
+    //draw the two bits to the left
+    BitBlt(hdc, x,   y+2, 1, height - 4, __hdcCardBitmaps, sx+0, sy+2, SRCCOPY);
+    BitBlt(hdc, x+1, y+1, 1, height - 2, __hdcCardBitmaps, sx+1, sy+1, SRCCOPY);
+
+    //draw the two bits to the right
+    BitBlt(hdc, x+width-2, y+1, 1, height - 2, __hdcCardBitmaps, sx+width-2, sy+1, SRCCOPY);
+    BitBlt(hdc, x+width-1, y+2, 1, height - 4, __hdcCardBitmaps, sx+width-1, sy+2, SRCCOPY);
+}
+
+//
+//    Draw a shape this this:
+//
+//   ++++++++++++
+//  ++++++++++++++
+// ++            ++
+//
+void DrawHorzCardStrip(HDC hdc, int x, int y, int nCardNum, int height, BOOL fDrawTips)
+{
+    int sx  = nCardNum * __cardwidth;
+    int sy  = 0;
+    int one = 1;
+    int two = 2;
+    BOOL tips = fDrawTips ? FALSE : TRUE;
+
+    if(height == 0) return;
+
+    if(height < 0)
+    {
+        sy = sy + __cardheight;
+        y  -= height;
+        one = -one;
+        two = -two;
+    }
+
+    // draw the main vertical band
+    //
+    BitBlt(hdc, x + 2, y, __cardwidth - 4, height, __hdcCardBitmaps, sx+2, sy, SRCCOPY);
+
+    //if(height <= 1) return;
+
+    // draw the "lips" at the left and right
+    BitBlt(hdc, x+1,             y+one, 1, height-one*tips, __hdcCardBitmaps, sx+1,             sy+one, SRCCOPY);
+    BitBlt(hdc, x+__cardwidth-2, y+one, 1, height-one*tips, __hdcCardBitmaps, sx+__cardwidth-2, sy+one, SRCCOPY);
+
+    //if(height <= 2) return;
+
+    // draw the outer-most lips
+    BitBlt(hdc, x,               y+two, 1, height-two*tips, __hdcCardBitmaps, sx,               sy+two, SRCCOPY);
+    BitBlt(hdc, x+__cardwidth-1, y+two, 1, height-two*tips, __hdcCardBitmaps, sx+__cardwidth-1, sy+two, SRCCOPY);    
+}
+
+//
+//    Draw a shape like this:
+//
+//     +++
+//      +++
+//   +++
+//   +++
+//   +++
+//   +++
+//   +++
+//   +++
+//    +++
+//     +++
+//
+//
+void DrawVertCardStrip(HDC hdc, int x, int y, int nCardNum, int width, BOOL fDrawTips)
+{
+    int sx  = nCardNum * __cardwidth;
+    int sy  = 0;
+    int one = 1;
+    int two = 2;
+    BOOL tips = fDrawTips ? FALSE : TRUE;
+
+    if(width == 0) return;
+    
+
+    if(width < 0)
+    {
+        sx = sx + __cardwidth;
+        x  -= width;
+        one = -1;
+        two = -2;
+    }
+
+    // draw the main vertical band
+    //
+    BitBlt(hdc, x, y + 2, width, __cardheight - 4, __hdcCardBitmaps, sx, sy+2, SRCCOPY);
+
+    //if(width <= 1) return;
+
+    // draw the "lips" at the top and bottom
+    BitBlt(hdc, x+one, y+1,              width-one*tips, 1, __hdcCardBitmaps, sx+one, sy + 1,              SRCCOPY);
+    BitBlt(hdc, x+one, y+__cardheight-2, width-one*tips, 1, __hdcCardBitmaps, sx+one, sy + __cardheight-2, SRCCOPY);
+
+    //if(width <= 2) return;
+
+    // draw the outer-most lips
+    BitBlt(hdc, x+two, y,                width-two*tips, 1, __hdcCardBitmaps, sx+two, sy,                  SRCCOPY);
+    BitBlt(hdc, x+two, y+__cardheight-1, width-two*tips, 1, __hdcCardBitmaps, sx+two, sy + __cardheight-1, SRCCOPY);
+}
+
+//
+//    xdir -   <0 or >0
+//    ydir -   <0 or >0
+//
+void DrawCardCorner(HDC hdc, int x, int y, int cardval, int xdir, int ydir)
+{
+    int sx = cardval * __cardwidth;
+    int sy = 0;
+
+    HDC hdcSource = __hdcCardBitmaps;
+
+    if(xdir < 0) 
+    {
+        x  += __cardwidth + xdir - 1;
+        sx += __cardwidth + xdir - 1;
+    }
+    else
+    {
+        x  += xdir;
+        sx += xdir;
+    }
+
+    if(ydir < 0) 
+    {
+        y  += __cardheight + ydir - 1;
+        sy += __cardheight + ydir - 1;
+    }
+    else
+    {
+        y  += ydir;
+        sy += ydir;
+    }
+
+    //convert x,y directions to -1, +1
+    xdir = xdir < 0 ? -1 : 1;
+    ydir = ydir < 0 ? -1 : 1;
+
+    SetPixel(hdc, x+xdir, y ,     GetPixel(hdcSource, sx+xdir, sy));
+    SetPixel(hdc, x,      y,      GetPixel(hdcSource, sx,      sy));
+    SetPixel(hdc, x,      y+ydir, GetPixel(hdcSource, sx,      sy+ydir));
+
+}
+
+//
+//    Draw a card (i.e. miss out the corners)
+//
+void DrawCard(HDC hdc, int x, int y, HDC hdcDragCard, int width, int height)
+{
+    //draw main center band
+    BitBlt(hdc, x+2, y, width - 4, height, hdcDragCard, 2, 0, SRCCOPY);
+
+    //draw the two bits to the left
+    BitBlt(hdc, x,   y+2, 1, height - 4, hdcDragCard, 0, 2, SRCCOPY);
+    BitBlt(hdc, x+1, y+1, 1, height - 2, hdcDragCard, 1, 1, SRCCOPY);
+
+    //draw the two bits to the right
+    BitBlt(hdc, x+width-2, y+1, 1, height - 2, hdcDragCard, width-2, 1, SRCCOPY);
+    BitBlt(hdc, x+width-1, y+2, 1, height - 4, hdcDragCard, width-1, 2, SRCCOPY);
+}
+
+//
+//    Clip a card SHAPE - basically any rectangle
+//  with rounded corners
+//
+int ClipCard(HDC hdc, int x, int y, int width, int height)
+{
+    ExcludeClipRect(hdc, x+2,        y,     x+2+width-4, y+  height);
+    ExcludeClipRect(hdc, x,            y+2, x+1,          y+2+height-4);
+    ExcludeClipRect(hdc, x+1,        y+1, x+2,          y+1+height-2);
+    ExcludeClipRect(hdc, x+width-2, y+1, x+width-2+1, y+1+height-2);
+    ExcludeClipRect(hdc, x+width-1, y+2, x+width-1+1, y+2+height-4);
+    return 0;
+}
+
+void CardRegion::Clip(HDC hdc)
+{
+    int numtoclip;
+
+    if(fVisible == false) 
+        return;
+
+    Update();                //Update this stack's size+card count
+    numtoclip = nNumApparentCards;
+
+    //if we are making this stack flash on/off, then only 
+    //clip the stack for drawing if the flash is in its ON state
+    if(nFlashCount != 0)
+    {
+        if(fFlashVisible == FALSE)
+            numtoclip = 0;
+    }
+
+    //if offset along a diagonal
+    if(xoffset != 0 && yoffset != 0 && cardstack.NumCards() != 0)
+    {
+        for(int j = 0; j < numtoclip; j ++)
+        {    
+            ClipCard(hdc, xpos + xoffset * j, ypos + yoffset * j, __cardwidth, __cardheight);
+        }    
+    }
+    //otherwise if just offset along a horizontal/vertical axis
+    else
+    {
+        if(yoffset < 0 && numtoclip > 0)
+        {
+            ClipCard(hdc, xpos, ypos-((numtoclip-1)*-yoffset), width, height);
+        }
+        else if(xoffset < 0 && numtoclip > 0)
+        {
+            ClipCard(hdc, xpos-((numtoclip-1)*-xoffset), ypos, width, height);
+        }
+        else
+        {
+            ClipCard(hdc, xpos, ypos, width, height);
+        }
+    }
+
+}
+
+void CardRegion::Render(HDC hdc)
+{
+    int cardnum = 0;
+    int numtodraw;
+    BOOL fDrawTips;
+    
+    Update();            //Update this stack's card count + size
+
+    numtodraw = nNumApparentCards;
+
+    if(nFlashCount != 0)
+    {
+        if(fFlashVisible == false)
+            numtodraw = 0;
+    }
+
+    if(fVisible == 0) return;
+    
+    cardnum = cardstack.NumCards() - numtodraw;
+    int counter;
+
+    for(counter = 0; counter < numtodraw; counter++)
+    {
+        int cardval;
+        
+        int x = xoffset * counter + xpos;
+        int y = yoffset * counter + ypos;
+
+        //if about to draw last card, then actually draw the top card
+        if(counter == numtodraw - 1) cardnum = cardstack.NumCards() - 1;
+        
+        Card card = cardstack.cardlist[cardnum];
+        cardval = card.Idx();
+        
+        if(card.FaceDown())
+            cardval = nBackCardIdx;    //card-back
+            
+        //only draw the visible part of the card
+        if(counter < numtodraw - 1)
+        {
+            if(yoffset != 0 && xoffset != 0)
+                fDrawTips = FALSE;
+            else
+                fDrawTips = TRUE;
+
+            if(yoffset != 0 && abs(xoffset) == 1 ||    xoffset != 0 && abs(yoffset) == 1)
+                fDrawTips = TRUE;
+
+            //draw horizontal strips
+            if(yoffset > 0) 
+            {
+                DrawHorzCardStrip(hdc, x, y, cardval, yoffset, fDrawTips);
+            }
+            else if(yoffset < 0)
+            {
+                DrawHorzCardStrip(hdc, x, y+__cardheight+yoffset, cardval, yoffset, fDrawTips);
+            }
+
+            //draw some vertical bars
+            if(xoffset > 0)
+            {
+                DrawVertCardStrip(hdc, x, y, cardval, xoffset, fDrawTips);
+            }
+            else if(xoffset < 0)
+            {
+                DrawVertCardStrip(hdc, x+__cardwidth+xoffset, y, cardval, xoffset, fDrawTips);
+            }
+
+            if(yoffset != 0 && xoffset != 0)//fDrawTips == FALSE)
+            {
+                //if we didn't draw any tips, then this is a 2-dim stack
+                //(i.e, it goes at a diagonal).
+                //in this case, we need to fill in the small triangle in
+                //each corner!
+                DrawCardCorner(hdc, x, y, cardval, xoffset, yoffset);
+            }
+        }
+        //if the top card, draw the whole thing
+        else
+        {
+            CardBlt(hdc, x, y, cardval);
+        }
+
+        cardnum ++;
+
+    } //end of index
+    
+    if(counter == 0)    //if the cardstack is empty, then draw it that way
+    {
+        int x = xpos;
+        int y = ypos;
+        
+        switch(uEmptyImage)
+        {
+        default: case CS_EI_NONE:
+            //this wipes the RECT variable, so watch out!
+            //SetRect(&rect, x, y, x+__cardwidth, y+__cardheight);
+            //PaintRect(hdc, &rect, MAKE_PALETTERGB(crBackgnd));
+            parentWnd.PaintCardRgn(hdc, x, y, __cardwidth, __cardheight, x, y);
+            break;
+            
+        case CS_EI_SUNK:    //case CS_EI_CIRC: case CS_EI_X:
+            DrawCard(hdc, x, y, __hdcPlaceHolder, __cardwidth, __cardheight);
+            break;
+        }
+        
+    }
+
+    return;
+}
+
+int calc_offset(int offset, int numcards, int numtodrag, int realvisible)
+{
+    if(offset >= 0)
+        return -offset * numcards;
+    else
+        return -offset * (numtodrag)       + 
+               -offset * (realvisible - 1);
+}
+
+void CardRegion::PrepareDragBitmaps(int numtodrag)
+{
+    RECT rect;
+    HDC hdc;
+    int icard;
+    int numcards = cardstack.NumCards();
+    int xoff, yoff;
+
+    if(nThreedCount > 1)
+    {
+        PrepareDragBitmapsThreed(numtodrag);
+        return;
+    }
+
+    //work out how big the bitmaps need to be
+    nDragCardWidth  = (numtodrag - 1) * abs(xoffset) + __cardwidth;
+    nDragCardHeight = (numtodrag - 1) * abs(yoffset) + __cardheight;
+
+    //Create bitmap for the back-buffer
+    hdc = GetDC(NULL);
+    hdcBackGnd = CreateCompatibleDC(hdc);
+    hbmBackGnd = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight);
+    SelectObject(hdcBackGnd, hbmBackGnd);
+
+    //Create bitmap for the drag-image
+    hdcDragCard = CreateCompatibleDC(hdc);
+    hbmDragCard = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight);
+    SelectObject(hdcDragCard, hbmDragCard);
+    ReleaseDC(NULL, hdc);
+
+    UseNicePalette(hdcBackGnd,  __hPalette);
+    UseNicePalette(hdcDragCard, __hPalette);
+
+    int realvisible = numcards / nThreedCount;
+
+    //if(numcards > 0 && realvisible == 0) realvisible = 1;
+    int iwhichcard = numcards - 1;
+    if(nThreedCount == 1) iwhichcard = 0;
+
+    //grab the first bit of background so we can prep the back buffer; do this by
+    //rendering the card stack (minus the card we are dragging) to the temporary
+    //background buffer, so it appears if we have lifted the card from the stack
+    //PaintRect(hdcBackGnd, &rect, crBackgnd);
+    SetRect(&rect, 0, 0, nDragCardWidth, nDragCardHeight);
+    xoff = calc_offset(xoffset, numcards, numtodrag, realvisible);
+    yoff = calc_offset(yoffset, numcards, numtodrag, realvisible);
+    
+    parentWnd.PaintCardRgn(hdcBackGnd, 0, 0, nDragCardWidth, nDragCardHeight, xpos - xoff,    ypos - yoff);
+
+    //
+    //    Render the cardstack into the back-buffer. The stack
+    //    has already had the dragcards removed, so just draw
+    //    what is left
+    //
+    for(icard = 0; icard < realvisible; icard++)
+    {
+        Card card = cardstack.cardlist[iwhichcard];
+        int nCardVal;
+        
+        nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx;
+
+        xoff = xoffset * icard + calc_offset(xoffset, numcards, numtodrag, realvisible);//- xoffset * ((numcards+numtodrag) / nThreedCount - numtodrag);
+        yoff = yoffset * icard + calc_offset(yoffset, numcards, numtodrag, realvisible);//- yoffset * ((numcards+numtodrag) / nThreedCount - numtodrag);
+
+        CardBlt(hdcBackGnd, xoff, yoff, nCardVal);
+        iwhichcard++;
+    }
+    
+    //
+    // If there are no cards under this one, just draw the place holder
+    //
+    if(numcards == 0)   
+    {
+        int xoff = 0, yoff = 0;
+
+        if(xoffset < 0)    xoff = nDragCardWidth  -  __cardwidth;
+        if(yoffset < 0)    yoff = nDragCardHeight -  __cardheight;
+
+        switch(uEmptyImage)
+        {
+        case CS_EI_NONE:
+            //No need to draw anything: We already cleared the
+            //back-buffer before the main loop..
+
+            //SetRect(&rc, xoff, yoff, xoff+ __cardwidth, yoff + __cardheight);
+            //PaintRect(hdcBackGnd, &rc, MAKE_PALETTERGB(crBackgnd));
+            //parentWnd.PaintCardRgn(hdcBackGnd, xoff, yoff, __cardwidth, __cardheight, xpos, ypos);// + xoff, ypos + yoff);
+            break;
+
+        case CS_EI_SUNK:
+            DrawCard(hdcBackGnd, xoff, yoff, __hdcPlaceHolder, __cardwidth, __cardheight);
+            break;
+        }
+    }
+
+    //
+    //    now render the drag-cards into the dragcard image
+    //
+    PaintRect(hdcDragCard, &rect, crBackgnd);
+
+    for(icard = 0; icard < numtodrag; icard++)
+    {
+        int nCardVal;
+
+        if(xoffset >= 0) xoff =  xoffset * icard;
+        else              xoff = -xoffset * (numtodrag - icard - 1);
+            
+        if(yoffset >= 0) yoff =  yoffset * icard;
+        else             yoff = -yoffset * (numtodrag - icard - 1);
+
+        Card card = dragstack.cardlist[icard];
+        
+        nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx;
+
+        CardBlt(hdcDragCard, xoff, yoff, nCardVal);
+    }
+}
+
+void CardRegion::PrepareDragBitmapsThreed(int numtodrag)
+{
+    RECT rect;
+    HDC hdc;
+    int icard;
+    int numunder = 0;
+    int iwhichcard;
+
+    int numcards = cardstack.NumCards();
+
+    //work out how big the bitmaps need to be
+    nDragCardWidth  = (numtodrag - 1) * abs(xoffset) + __cardwidth;
+    nDragCardHeight = (numtodrag - 1) * abs(yoffset) + __cardheight;
+
+    //Create bitmap for the back-buffer
+    hdc = GetDC(NULL);
+    hdcBackGnd = CreateCompatibleDC(hdc);
+    hbmBackGnd = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight);
+    SelectObject(hdcBackGnd, hbmBackGnd);
+
+    //create bitmap for the drag-image
+    hdcDragCard = CreateCompatibleDC(hdc);
+    hbmDragCard = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight);
+    SelectObject(hdcDragCard, hbmDragCard);
+    ReleaseDC(NULL, hdc);
+
+    UseNicePalette(hdcBackGnd,  __hPalette);
+    UseNicePalette(hdcDragCard, __hPalette);
+
+    //grab the first bit of background so we can prep the back buffer; do this by
+    //rendering the card stack (minus the card we are dragging) to the temporary
+    //background buffer, so it appears if we have lifted the card from the stack
+    //--SetRect(&rect, 0, 0, nDragCardWidth, nDragCardHeight);
+    //--PaintRect(hdcBackGnd, &rect, crBackgnd);
+
+    int threedadjust = numcards  % nThreedCount == 0;
+    
+    numunder = CalcApparentCards(numcards);
+    iwhichcard = (numcards+numtodrag) - numunder - 1;
+    if(nThreedCount == 1) iwhichcard = 0;
+    
+    int xoff = calc_offset(xoffset, numunder, numtodrag, numunder);
+    int yoff = calc_offset(yoffset, numunder, numtodrag, numunder);
+
+    parentWnd.PaintCardRgn(hdcBackGnd, 0,0,    nDragCardWidth,nDragCardHeight,    xpos - xoff,ypos - yoff);
+
+    //
+    //    Render the cardstack into the back-buffer. The stack
+    //    has already had the dragcards removed, so just draw
+    //    what is left
+    //
+    for(icard = 0; icard < numunder; icard++)
+    {
+        Card card = cardstack.cardlist[iwhichcard];
+        int nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx;
+
+        CardBlt(hdcBackGnd, 
+                xoffset * icard - xoffset*(numunder-numtodrag+threedadjust),
+                yoffset * icard - yoffset*(numunder-numtodrag+threedadjust),
+                nCardVal);
+
+        iwhichcard++;
+    }
+    
+    //
+    // If there are no cards under this one, just draw the place holder
+    //
+    if(numcards == 0)   
+    {
+        switch(uEmptyImage)
+        {
+        case CS_EI_NONE:
+            //no need! we've already cleared the whole
+            //back-buffer before the main loop!
+            //SetRect(&rect, 0, 0, __cardwidth, __cardheight);
+            //PaintRect(hdcBackGnd, &rect, MAKE_PALETTERGB(crBackgnd));
+            break;
+
+        case CS_EI_SUNK:
+            DrawCard(hdcBackGnd, 0, 0, __hdcPlaceHolder, __cardwidth, __cardheight);
+            break;
+    
+        }
+    }
+
+    //
+    //    now render the drag-cards into the dragcard image
+    //
+    PaintRect(hdcDragCard, &rect, crBackgnd);
+    
+    for(icard = 0; icard < numtodrag; icard++)
+    {
+        Card card = dragstack.cardlist[icard];
+        int nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx;
+
+        CardBlt(hdcDragCard, xoffset * icard, yoffset * icard, nCardVal);
+    }
+}
+
+void CardRegion::ReleaseDragBitmaps(void)
+{
+    //SelectObject(hdcBackGnd, hOld1);
+    DeleteObject(hbmBackGnd);
+    DeleteDC(hdcBackGnd);
+
+    //SelectObject(hdcDragCard, hOld2);
+    DeleteObject(hbmDragCard);
+    DeleteDC(hdcDragCard);
+}
+
+
+void CardRegion::Redraw()
+{
+    HDC hdc = GetDC((HWND)parentWnd);
+
+    Update();
+    Render(hdc);
+
+    ReleaseDC((HWND)parentWnd, hdc);
+}
index 317986a..a64bef2 100644 (file)
-//\r
-//    CardLib - CardRegion mouse-related stuff\r
-//\r
-//    Freeware\r
-//    Copyright J Brown 2001\r
-//\r
-#include <windows.h>\r
-#include <math.h>\r
-#include <stdio.h>\r
-\r
-#include "cardlib.h"\r
-#include "cardwindow.h"\r
-#include "cardregion.h"\r
-\r
-#if 1\r
-#define TRACE(s)\r
-#else\r
-#define TRACE(s) printf("%s(%i): %s",__FILE__,__LINE__,s)\r
-#endif\r
-\r
-double __CARDZOOMSPEED = 32;\r
-\r
-int ClipCard(HDC hdc, int x, int y, int width, int height);\r
-void DrawCard(HDC hdc, int x, int y, HDC hdcSource, int width, int height);\r
-\r
-#ifdef _DEBUG\r
-\r
-static pDebugClickProc DebugStackClickProc = 0;\r
-\r
-void CardLib_SetStackClickProc(pDebugClickProc proc)\r
-{\r
-    DebugStackClickProc = proc;\r
-}\r
-\r
-#endif\r
-\r
-CardRegion *CardWindow::GetBestStack(int x, int y, int w, int h)\r
-{\r
-    int maxoverlap    =  0;\r
-    int maxoverlapidx = -1;\r
-\r
-    //find the stack which is most covered by the dropped\r
-    //cards. Only include those which allow drops.\r
-    //\r
-    for(int i = 0; i < nNumCardRegions; i++)\r
-    {\r
-        int percent = Regions[i]->GetOverlapRatio(x, y, w, h);\r
-\r
-        //if this stack has the biggest coverage yet\r
-        if(percent > maxoverlap && Regions[i]->IsVisible())\r
-        {\r
-            maxoverlap = percent;\r
-            maxoverlapidx = i;\r
-        }\r
-    }\r
-    \r
-    //if we found a stack to drop onto\r
-    if(maxoverlapidx != -1)\r
-    {\r
-        return Regions[maxoverlapidx];\r
-    }\r
-    else\r
-    {\r
-        return 0;\r
-    }\r
-}\r
-\r
-bool CardRegion::IsPointInStack(int x, int y)\r
-{\r
-    int axpos = xoffset < 0 ? xpos + (nNumApparentCards-1)*xoffset : xpos;\r
-    int aypos = yoffset < 0 ? ypos + (nNumApparentCards-1)*yoffset : ypos;\r
-    \r
-    if(x >= axpos && x < axpos + width && y >= aypos && y < aypos + height && fVisible)\r
-        return true;\r
-    else\r
-        return false;\r
-}\r
-\r
-int CardRegion::GetNumDragCards(int x, int y)\r
-{\r
-    int cardindex = 0;        //index from stack start\r
-    int maxidx;\r
-\r
-    //make x,y relative to the stack's upper left corner\r
-    x -= xpos + (xoffset < 0 ? (nNumApparentCards/*cardstack.NumCards()*/ - 1) * xoffset : 0);\r
-    y -= ypos + (yoffset < 0 ? (nNumApparentCards/*cardstack.NumCards()*/ - 1) * yoffset : 0);\r
-    \r
-    //if stack is empty, cannot drag any cards from it\r
-    if(cardstack.NumCards() <= 0)\r
-        return 0;\r
-\r
-    //see which card in the stack has been clicked on\r
-    //top-bottom ordering\r
-    if(yoffset > 0)\r
-    {\r
-        if(y < height - __cardheight)\r
-            cardindex = y / yoffset;\r
-        else\r
-            cardindex = cardstack.NumCards() - 1;\r
-    }\r
-    else if(yoffset < 0)\r
-    {\r
-        if(y < __cardheight)\r
-            cardindex = cardstack.NumCards() - 1;\r
-        else\r
-            cardindex = cardstack.NumCards() - ((y - __cardheight) / -yoffset) - 2;\r
-    }\r
-    else    //yoffset == 0\r
-    {\r
-        cardindex = cardstack.NumCards() - 1;\r
-    }\r
-\r
-    maxidx = cardindex;\r
-\r
-    //if left-right\r
-    if(xoffset > 0)\r
-    {\r
-        if(x < width - __cardwidth)\r
-            cardindex = x / xoffset;\r
-        else\r
-            cardindex = cardstack.NumCards() - 1;\r
-    }\r
-    else if(xoffset < 0)\r
-    {\r
-        if(x < __cardwidth)\r
-            cardindex = cardstack.NumCards() - 1;\r
-        else\r
-            cardindex = cardstack.NumCards() - ((x - __cardwidth) / -xoffset) - 2;\r
-    }\r
-    else\r
-    {\r
-        cardindex = cardstack.NumCards() - 1;\r
-    }\r
-\r
-    if(cardindex > maxidx) cardindex = maxidx;\r
-\r
-    if(cardindex > cardstack.NumCards())\r
-        cardindex = 1;\r
-\r
-    //if are trying to drag too many cards at once\r
-    return cardstack.NumCards() - cardindex;\r
-}\r
-\r
-bool CardRegion::CanDragCards(int iNumCards)\r
-{\r
-    if(iNumCards <= 0) return false;\r
-    if(nThreedCount > 1 && iNumCards > 1) return false;\r
-\r
-    if(WaitForSingleObject(mxlock, 0) != WAIT_OBJECT_0)\r
-    {\r
-//        TRACE("Failed to gain access to card stack\n");\r
-        return false;\r
-    }\r
-\r
-    ReleaseMutex(mxlock);\r
-\r
-    switch(uDragRule)\r
-    {\r
-    case CS_DRAG_ALL:\r
-        return true;\r
-        \r
-    case CS_DRAG_TOP:\r
-\r
-        if(iNumCards == 1)\r
-            return true;\r
-        else\r
-            return false;\r
-        \r
-    case CS_DRAG_NONE:\r
-        return false;\r
-        \r
-    case CS_DRAG_CALLBACK:\r
-        \r
-        if(CanDragCallback)\r
-        {\r
-            return CanDragCallback(*this, iNumCards);\r
-        }\r
-        else\r
-        {\r
-            return false;\r
-        }\r
-        \r
-    default:\r
-        return false;\r
-    }\r
-}\r
-\r
-bool CardRegion::CanDropCards(CardStack &cards)\r
-{\r
-    if(WaitForSingleObject(mxlock, 0) != WAIT_OBJECT_0)\r
-    {\r
-        return false;\r
-    }\r
-\r
-    ReleaseMutex(mxlock);\r
-\r
-    switch(uDropRule)\r
-    {\r
-    case CS_DROP_ALL:\r
-        return true;\r
-\r
-    case CS_DROP_NONE:\r
-        return false;\r
-\r
-    case CS_DROP_CALLBACK:\r
-        \r
-        if(CanDropCallback)\r
-        {\r
-            return CanDropCallback(*this, cards);\r
-        }\r
-        else\r
-        {\r
-            return false;\r
-        }\r
-\r
-    default:\r
-        return false;\r
-    }\r
-}\r
-\r
-bool CardRegion::OnLButtonDblClk(int x, int y)\r
-{\r
-    iNumDragCards = GetNumDragCards(x, y); \r
-\r
-    if(DblClickCallback)\r
-        DblClickCallback(*this, iNumDragCards);\r
-\r
-    return true;\r
-}\r
-\r
-bool CardRegion::OnLButtonDown(int x, int y)\r
-{\r
-    iNumDragCards = GetNumDragCards(x, y); \r
-\r
-#ifdef _DEBUG\r
-    if(DebugStackClickProc)\r
-    {\r
-        if(!DebugStackClickProc(*this))\r
-            return false;\r
-    }\r
-#endif\r
-\r
-    if(ClickCallback)\r
-        ClickCallback(*this, iNumDragCards);\r
-\r
-    if(CanDragCards(iNumDragCards) != false)\r
-    {\r
-\r
-        //offset of the mouse cursor relative to the top-left corner\r
-        //of the cards that are being dragged\r
-        mousexoffset = x - xpos - xoffset * (nNumApparentCards - iNumDragCards);\r
-        mouseyoffset = y - ypos - yoffset * (nNumApparentCards - iNumDragCards);\r
-        \r
-        if(xoffset < 0)\r
-            mousexoffset += -xoffset * (iNumDragCards - 1);\r
-\r
-        if(yoffset < 0)\r
-            mouseyoffset += -yoffset * (iNumDragCards - 1);\r
-        \r
-        //remove the cards from the source stack\r
-        dragstack = cardstack.Pop(iNumDragCards);\r
-\r
-        //prepare the back buffer, and the drag image\r
-        PrepareDragBitmaps(iNumDragCards);\r
-\r
-        oldx = x - mousexoffset;\r
-        oldy = y - mouseyoffset;\r
-        \r
-        Update();            //Update this stack's card count + size\r
-\r
-        SetCapture((HWND)parentWnd);\r
-\r
-        //set AFTER settings the dragstack...\r
-        fMouseDragging = true;\r
-\r
-        return true;\r
-    }\r
-\r
-    return false;\r
-}\r
-\r
-bool CardRegion::OnLButtonUp(int x, int y)\r
-{\r
-    CardRegion *pDestStack = 0;\r
-    HDC hdc;\r
-    int dropstackid = CS_DROPZONE_NODROP;\r
-    \r
-    RECT dragrect;\r
-    DropZone *dropzone;\r
-\r
-    fMouseDragging = false;\r
-\r
-    //first of all, see if any drop zones have been registered\r
-    SetRect(&dragrect, x-mousexoffset, y-mouseyoffset, x-mousexoffset+nDragCardWidth, y-mouseyoffset+nDragCardHeight);\r
-\r
-    dropzone = parentWnd.GetDropZoneFromRect(&dragrect);\r
-\r
-    if(dropzone)\r
-    {\r
-        dropstackid = dropzone->DropCards(dragstack);\r
-        \r
-        if(dropstackid != CS_DROPZONE_NODROP)\r
-            pDestStack = parentWnd.CardRegionFromId(dropstackid);\r
-        else\r
-            pDestStack = 0;\r
-    }\r
-    else\r
-    {\r
-        pDestStack = parentWnd.GetBestStack(x - mousexoffset, y - mouseyoffset, nDragCardWidth, nDragCardHeight);\r
-    }\r
-    \r
-    // If have found a stack to drop onto\r
-    //\r
-    TRACE ( "can I drop card?\n" );\r
-    if(pDestStack && pDestStack->CanDropCards(dragstack)) \r
-    {\r
-        TRACE ( "yes, dropping card\n" );\r
-        hdc = GetDC((HWND)parentWnd);\r
-        //            UseNicePalette(hdc);\r
-        ZoomCard(hdc, x - mousexoffset, y  - mouseyoffset, pDestStack);\r
-        ReleaseDC((HWND)parentWnd, hdc);\r
-        \r
-        //\r
-        //add the cards to the destination stack\r
-        //\r
-        CardStack temp = pDestStack->GetCardStack();\r
-        temp.Push(dragstack);\r
-        \r
-        pDestStack->SetCardStack(temp);\r
-//        pDestStack->Update();        //Update this stack's card count + size\r
-//        pDestStack->UpdateFaceDir(temp);\r
-        \r
-        //    Call the remove callback on THIS stack, if one is specified\r
-        //\r
-        if(RemoveCallback)\r
-            RemoveCallback(*this, iNumDragCards);\r
-\r
-        //    Call the add callback, if one is specified\r
-        //\r
-        if(pDestStack->AddCallback)\r
-            pDestStack->AddCallback(*pDestStack, pDestStack->cardstack);//index, deststack->numcards);\r
-        \r
-        RedrawIfNotDim(pDestStack, true);\r
-        TRACE ( "done dropping card\n" );\r
-    }\r
-\r
-    //\r
-    //    Otherwise, let the cards snap back onto this stack\r
-    //\r
-    else\r
-    {\r
-        TRACE ( "no, putting card back\n" );\r
-        hdc = GetDC((HWND)parentWnd);\r
-        TRACE ( "calling ZoomCard()\n" );\r
-        ZoomCard(hdc, x - mousexoffset, y - mouseyoffset, this);\r
-        TRACE ( "cardstack += dragstack\n" );\r
-        cardstack += dragstack;\r
-        TRACE ( "calling ReleaseDC()\n" );\r
-        ReleaseDC((HWND)parentWnd, hdc);\r
-\r
-        TRACE ( "calling Update()\n" );\r
-        Update();        //Update this stack's card count + size\r
-        TRACE ( "done putting card back\n" );\r
-    }\r
-    \r
-    ReleaseDragBitmaps();\r
-    ReleaseCapture();\r
-    \r
-    TRACE ( "OnLButtonUp() done\n" );\r
-    return true;\r
-}\r
-\r
-bool CardRegion::OnMouseMove(int x, int y)\r
-{\r
-    HDC hdc;\r
-\r
-    hdc = GetDC((HWND)parentWnd);\r
-        \r
-    x -= mousexoffset;\r
-    y -= mouseyoffset;\r
-        \r
-    MoveDragCardTo(hdc, x, y);\r
-\r
-    //BitBlt(hdc, nDragCardWidth+10, 0, nDragCardWidth, nDragCardHeight, hdcBackGnd, 0, 0, SRCCOPY);\r
-    //BitBlt(hdc, 0, 0, nDragCardWidth, nDragCardHeight, hdcDragCard, 0, 0, SRCCOPY);\r
-    \r
-    ReleaseDC((HWND)parentWnd, hdc);\r
-        \r
-    oldx = x;\r
-    oldy = y;\r
-    \r
-    return true;\r
-}\r
-\r
-//\r
-//    There is a bug in BitBlt when the source x,y\r
-//    become < 0. So this wrapper function simply adjusts\r
-//    the coords so that we never try to blt in from this range\r
-//\r
-BOOL ClippedBitBlt(HDC hdcDest, int x, int y, int width, int height, HDC hdcSrc, int srcx, int srcy, DWORD dwROP)\r
-{\r
-    if(srcx < 0)\r
-    {\r
-        x = 0 - srcx;\r
-        width = width + srcx;\r
-        srcx = 0;\r
-    }\r
-\r
-    if(srcy < 0)\r
-    {\r
-        y = 0 - srcy;\r
-        height = height + srcy;\r
-        srcy = 0;\r
-    }\r
-\r
-    return BitBlt(hdcDest, x, y, width, height, hdcSrc, srcx, srcy, dwROP);\r
-}\r
-\r
-void CardRegion::MoveDragCardTo(HDC hdc, int x, int y)\r
-{\r
-    RECT inter, rect1, rect2;\r
-\r
-    //mask off the new position of the drag-card, so\r
-    //that it will not be painted over\r
-    ClipCard(hdc, x, y, nDragCardWidth, nDragCardHeight);\r
-    \r
-    //restore the area covered by the card at its previous position\r
-    BitBlt(hdc, oldx, oldy, nDragCardWidth, nDragCardHeight, hdcBackGnd, 0, 0, SRCCOPY);\r
-\r
-    //remove clipping so we can draw the card at its new place\r
-    SelectClipRgn(hdc, NULL);\r
-    \r
-    //if the card's old and new positions overlap, then we\r
-    //need some funky code to update the "saved background" image,\r
-    SetRect(&rect1, oldx, oldy, oldx+nDragCardWidth, oldy+nDragCardHeight);\r
-    SetRect(&rect2,    x,    y,    x+nDragCardWidth,    y+nDragCardHeight);\r
-    \r
-    if(IntersectRect(&inter, &rect1, &rect2))\r
-    {\r
-        int interwidth = inter.right-inter.left;\r
-        int interheight = inter.bottom-inter.top;\r
-        int destx, desty, srcx, srcy;\r
-        \r
-        if(rect2.left > rect1.left) \r
-        {    \r
-            destx = 0; srcx = nDragCardWidth - interwidth; \r
-        }\r
-        else\r
-        {\r
-            destx = nDragCardWidth  - interwidth; srcx = 0;\r
-        }\r
-        \r
-        if(rect2.top  > rect1.top) \r
-        {\r
-            desty = 0; srcy = nDragCardHeight - interheight;\r
-        }\r
-        else \r
-        {\r
-            desty = nDragCardHeight - interheight; srcy = 0;\r
-        }\r
-        \r
-        //shift the bit we didn't use for the restore (due to the clipping)\r
-        //into the opposite corner\r
-        BitBlt(hdcBackGnd, destx,desty, interwidth, interheight, hdcBackGnd, srcx, srcy, SRCCOPY);\r
-        \r
-        ExcludeClipRect(hdcBackGnd, destx, desty, destx+interwidth, desty+interheight);\r
-        \r
-        //this bit requires us to clip the BitBlt (from screen to background)\r
-        //as BitBlt is a bit buggy it seems\r
-        ClippedBitBlt(hdcBackGnd, 0,0, nDragCardWidth, nDragCardHeight, hdc, x, y, SRCCOPY);\r
-        SelectClipRgn(hdcBackGnd, NULL);\r
-    }\r
-    else\r
-    {\r
-        BitBlt(hdcBackGnd, 0,0, nDragCardWidth, nDragCardHeight, hdc, x, y, SRCCOPY);\r
-    }\r
-    \r
-    //finally draw the card to the screen\r
-    DrawCard(hdc, x, y, hdcDragCard, nDragCardWidth, nDragCardHeight);\r
-}\r
-\r
-\r
-//extern "C" int _fltused(void) { return 0; }\r
-//extern "C" int _ftol(void) { return 0; }\r
-\r
-//\r
-//    Better do this in fixed-point, to stop\r
-//    VC from linking in floatingpoint-long conversions\r
-//\r
-//#define FIXED_PREC_MOVE\r
-#ifdef  FIXED_PREC_MOVE\r
-#define PRECISION 12\r
-void ZoomCard(HDC hdc, int xpos, int ypos, CARDSTACK *dest)\r
-{\r
-    long dx, dy, x , y;\r
-\r
-    \r
-    int apparentcards;\r
-    x = xpos << PRECISION; y = ypos << PRECISION;\r
-\r
-    oldx = (int)xpos;\r
-    oldy = (int)ypos;\r
-\r
-    apparentcards=dest->numcards/dest->threedcount;\r
-\r
-    int idestx = dest->xpos + dest->xoffset * (apparentcards);// - iNumDragCards); \r
-    int idesty = dest->ypos + dest->yoffset * (apparentcards);// - iNumDragCards);\r
-\r
-    //normalise the motion vector\r
-    dx = (idestx<<PRECISION) - x;\r
-    dy = (idesty<<PRECISION) - y;\r
-    long recip = (1 << PRECISION) / 1;//sqrt(dx*dx + dy*dy);\r
-\r
-    dx *= recip * 16;//CARDZOOMSPEED; \r
-    dy *= recip * 16;//CARDZOOMSPEED;\r
-\r
-    //if(dx < 0) dxinc = 1.001; else\r
-\r
-    for(;;)\r
-    {\r
-        int ix, iy;\r
-        x += dx;\r
-        y += dy;\r
-\r
-        ix = (int)x>>PRECISION;\r
-        iy = (int)y>>PRECISION;\r
-        if(dx < 0 && ix < idestx) ix = idestx;\r
-        else if(dx > 0 && ix > idestx) ix = idestx;\r
-\r
-        if(dy < 0 && iy < idesty) iy = idesty;\r
-        else if(dy > 0 && iy > idesty) iy = idesty;\r
-\r
-        MoveDragCardTo(hdc, ix, iy);\r
-\r
-        if(ix == idestx && iy == idesty)\r
-            break;\r
-\r
-        oldx = (int)x >> PRECISION;\r
-        oldy = (int)y >> PRECISION;\r
-\r
-        //dx *= 1.2;\r
-        //dy *= 1.2;\r
-\r
-        Sleep(10);\r
-    }\r
-}\r
-#else\r
-void CardRegion::ZoomCard(HDC hdc, int xpos, int ypos, CardRegion *pDestStack)\r
-{\r
-    TRACE ( "ENTER ZoomCard()\n" );\r
-    double dx, dy, x ,y;\r
-    int apparentcards;\r
-    x = (double)xpos; y = (double)ypos;\r
-\r
-    oldx = (int)x;\r
-    oldy = (int)y;\r
-\r
-    apparentcards = pDestStack->cardstack.NumCards() / pDestStack->nThreedCount;\r
-\r
-    int idestx = pDestStack->xpos + pDestStack->xoffset * (apparentcards);\r
-    int idesty = pDestStack->ypos + pDestStack->yoffset * (apparentcards);\r
-\r
-    if(pDestStack->yoffset < 0)\r
-        idesty += pDestStack->yoffset * (iNumDragCards-1);\r
-\r
-    if(pDestStack->xoffset < 0)\r
-        idestx += pDestStack->xoffset * (iNumDragCards-1);\r
-\r
-    //normalise the motion vector\r
-    dx = idestx - x;\r
-    dy = idesty - y;\r
-    if ( fabs(dx) + fabs(dy) < 0.001f )\r
-    {\r
-        MoveDragCardTo(hdc, idestx, idesty);\r
-        return;\r
-    }\r
-    double recip = 1.0 / sqrt(dx*dx + dy*dy);\r
-    dx *= recip * __CARDZOOMSPEED; dy *= recip * __CARDZOOMSPEED;\r
-\r
-    //if(dx < 0) dxinc = 1.001; else\r
-\r
-    for(;;)\r
-    {\r
-        bool attarget = true;\r
-        int ix, iy;\r
-        x += dx;\r
-        y += dy;\r
-\r
-        ix = (int)x;\r
-        iy = (int)y;\r
-\r
-        if(dx < 0.0 && ix < idestx) ix = idestx;\r
-        else if(dx > 0.0 && ix > idestx) ix = idestx;\r
-        else attarget = false;\r
-\r
-        if(dy < 0.0 && iy < idesty) iy = idesty;\r
-        else if(dy > 0.0 && iy > idesty) iy = idesty;\r
-        else attarget = false;\r
-\r
-        //if the target stack wants the drag cards drawn differently\r
-        //to how they are, then redraw the drag card image just before\r
-        //the cards land\r
-        /*if(attarget == true)\r
-        {\r
-            for(int i = 0; i < iNumDragCards; i++)\r
-            {\r
-                int xdraw = pDestStack->xoffset*i;\r
-                int ydraw = pDestStack->yoffset*i;\r
-\r
-                if(pDestStack->yoffset < 0)\r
-                    ydraw = -pDestStack->yoffset * (iNumDragCards-i-1);\r
-                if(pDestStack->xoffset < 0)\r
-                    xdraw = -pDestStack->xoffset * (iNumDragCards-i-1);\r
-\r
-                if(pDestStack->facedirection == CS_FACEUP && \r
-                    pDestStack->numcards+i >= dest->numfacedown)\r
-                {\r
-                    //cdtDraw(hdcDragCard, xdraw, ydraw, iDragCards[i], ectFACES, 0);\r
-                }\r
-                else\r
-                {\r
-                    //cdtDraw(hdcDragCard, xdraw, ydraw, CARDSTACK::backcard, ectBACKS, 0);\r
-                }\r
-            }\r
-        }*/\r
-\r
-        MoveDragCardTo(hdc, ix, iy);\r
-\r
-        if(attarget || ix == idestx && iy == idesty)\r
-            break;\r
-\r
-        oldx = (int)x;\r
-        oldy = (int)y;\r
-\r
-        //dx *= 1.2;\r
-        //dy *= 1.2;\r
-\r
-        Sleep(10);\r
-    }\r
-    TRACE ( "EXIT ZoomCard()\n" );\r
-}\r
-#endif\r
+//
+//    CardLib - CardRegion mouse-related stuff
+//
+//    Freeware
+//    Copyright J Brown 2001
+//
+#include <windows.h>
+#include <math.h>
+#include <stdio.h>
+
+#include "cardlib.h"
+#include "cardwindow.h"
+#include "cardregion.h"
+
+#if 1
+#define TRACE(s)
+#else
+#define TRACE(s) printf("%s(%i): %s",__FILE__,__LINE__,s)
+#endif
+
+double __CARDZOOMSPEED = 32;
+
+int ClipCard(HDC hdc, int x, int y, int width, int height);
+void DrawCard(HDC hdc, int x, int y, HDC hdcSource, int width, int height);
+
+#ifdef _DEBUG
+
+static pDebugClickProc DebugStackClickProc = 0;
+
+void CardLib_SetStackClickProc(pDebugClickProc proc)
+{
+    DebugStackClickProc = proc;
+}
+
+#endif
+
+CardRegion *CardWindow::GetBestStack(int x, int y, int w, int h)
+{
+    int maxoverlap    =  0;
+    int maxoverlapidx = -1;
+
+    //find the stack which is most covered by the dropped
+    //cards. Only include those which allow drops.
+    //
+    for(int i = 0; i < nNumCardRegions; i++)
+    {
+        int percent = Regions[i]->GetOverlapRatio(x, y, w, h);
+
+        //if this stack has the biggest coverage yet
+        if(percent > maxoverlap && Regions[i]->IsVisible())
+        {
+            maxoverlap = percent;
+            maxoverlapidx = i;
+        }
+    }
+    
+    //if we found a stack to drop onto
+    if(maxoverlapidx != -1)
+    {
+        return Regions[maxoverlapidx];
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+bool CardRegion::IsPointInStack(int x, int y)
+{
+    int axpos = xoffset < 0 ? xpos + (nNumApparentCards-1)*xoffset : xpos;
+    int aypos = yoffset < 0 ? ypos + (nNumApparentCards-1)*yoffset : ypos;
+    
+    if(x >= axpos && x < axpos + width && y >= aypos && y < aypos + height && fVisible)
+        return true;
+    else
+        return false;
+}
+
+int CardRegion::GetNumDragCards(int x, int y)
+{
+    int cardindex = 0;        //index from stack start
+    int maxidx;
+
+    //make x,y relative to the stack's upper left corner
+    x -= xpos + (xoffset < 0 ? (nNumApparentCards/*cardstack.NumCards()*/ - 1) * xoffset : 0);
+    y -= ypos + (yoffset < 0 ? (nNumApparentCards/*cardstack.NumCards()*/ - 1) * yoffset : 0);
+    
+    //if stack is empty, cannot drag any cards from it
+    if(cardstack.NumCards() <= 0)
+        return 0;
+
+    //see which card in the stack has been clicked on
+    //top-bottom ordering
+    if(yoffset > 0)
+    {
+        if(y < height - __cardheight)
+            cardindex = y / yoffset;
+        else
+            cardindex = cardstack.NumCards() - 1;
+    }
+    else if(yoffset < 0)
+    {
+        if(y < __cardheight)
+            cardindex = cardstack.NumCards() - 1;
+        else
+            cardindex = cardstack.NumCards() - ((y - __cardheight) / -yoffset) - 2;
+    }
+    else    //yoffset == 0
+    {
+        cardindex = cardstack.NumCards() - 1;
+    }
+
+    maxidx = cardindex;
+
+    //if left-right
+    if(xoffset > 0)
+    {
+        if(x < width - __cardwidth)
+            cardindex = x / xoffset;
+        else
+            cardindex = cardstack.NumCards() - 1;
+    }
+    else if(xoffset < 0)
+    {
+        if(x < __cardwidth)
+            cardindex = cardstack.NumCards() - 1;
+        else
+            cardindex = cardstack.NumCards() - ((x - __cardwidth) / -xoffset) - 2;
+    }
+    else
+    {
+        cardindex = cardstack.NumCards() - 1;
+    }
+
+    if(cardindex > maxidx) cardindex = maxidx;
+
+    if(cardindex > cardstack.NumCards())
+        cardindex = 1;
+
+    //if are trying to drag too many cards at once
+    return cardstack.NumCards() - cardindex;
+}
+
+bool CardRegion::CanDragCards(int iNumCards)
+{
+    if(iNumCards <= 0) return false;
+    if(nThreedCount > 1 && iNumCards > 1) return false;
+
+    if(WaitForSingleObject(mxlock, 0) != WAIT_OBJECT_0)
+    {
+//        TRACE("Failed to gain access to card stack\n");
+        return false;
+    }
+
+    ReleaseMutex(mxlock);
+
+    switch(uDragRule)
+    {
+    case CS_DRAG_ALL:
+        return true;
+        
+    case CS_DRAG_TOP:
+
+        if(iNumCards == 1)
+            return true;
+        else
+            return false;
+        
+    case CS_DRAG_NONE:
+        return false;
+        
+    case CS_DRAG_CALLBACK:
+        
+        if(CanDragCallback)
+        {
+            return CanDragCallback(*this, iNumCards);
+        }
+        else
+        {
+            return false;
+        }
+        
+    default:
+        return false;
+    }
+}
+
+bool CardRegion::CanDropCards(CardStack &cards)
+{
+    if(WaitForSingleObject(mxlock, 0) != WAIT_OBJECT_0)
+    {
+        return false;
+    }
+
+    ReleaseMutex(mxlock);
+
+    switch(uDropRule)
+    {
+    case CS_DROP_ALL:
+        return true;
+
+    case CS_DROP_NONE:
+        return false;
+
+    case CS_DROP_CALLBACK:
+        
+        if(CanDropCallback)
+        {
+            return CanDropCallback(*this, cards);
+        }
+        else
+        {
+            return false;
+        }
+
+    default:
+        return false;
+    }
+}
+
+bool CardRegion::OnLButtonDblClk(int x, int y)
+{
+    iNumDragCards = GetNumDragCards(x, y); 
+
+    if(DblClickCallback)
+        DblClickCallback(*this, iNumDragCards);
+
+    return true;
+}
+
+bool CardRegion::OnLButtonDown(int x, int y)
+{
+    iNumDragCards = GetNumDragCards(x, y); 
+
+#ifdef _DEBUG
+    if(DebugStackClickProc)
+    {
+        if(!DebugStackClickProc(*this))
+            return false;
+    }
+#endif
+
+    if(ClickCallback)
+        ClickCallback(*this, iNumDragCards);
+
+    if(CanDragCards(iNumDragCards) != false)
+    {
+
+        //offset of the mouse cursor relative to the top-left corner
+        //of the cards that are being dragged
+        mousexoffset = x - xpos - xoffset * (nNumApparentCards - iNumDragCards);
+        mouseyoffset = y - ypos - yoffset * (nNumApparentCards - iNumDragCards);
+        
+        if(xoffset < 0)
+            mousexoffset += -xoffset * (iNumDragCards - 1);
+
+        if(yoffset < 0)
+            mouseyoffset += -yoffset * (iNumDragCards - 1);
+        
+        //remove the cards from the source stack
+        dragstack = cardstack.Pop(iNumDragCards);
+
+        //prepare the back buffer, and the drag image
+        PrepareDragBitmaps(iNumDragCards);
+
+        oldx = x - mousexoffset;
+        oldy = y - mouseyoffset;
+        
+        Update();            //Update this stack's card count + size
+
+        SetCapture((HWND)parentWnd);
+
+        //set AFTER settings the dragstack...
+        fMouseDragging = true;
+
+        return true;
+    }
+
+    return false;
+}
+
+bool CardRegion::OnLButtonUp(int x, int y)
+{
+    CardRegion *pDestStack = 0;
+    HDC hdc;
+    int dropstackid = CS_DROPZONE_NODROP;
+    
+    RECT dragrect;
+    DropZone *dropzone;
+
+    fMouseDragging = false;
+
+    //first of all, see if any drop zones have been registered
+    SetRect(&dragrect, x-mousexoffset, y-mouseyoffset, x-mousexoffset+nDragCardWidth, y-mouseyoffset+nDragCardHeight);
+
+    dropzone = parentWnd.GetDropZoneFromRect(&dragrect);
+
+    if(dropzone)
+    {
+        dropstackid = dropzone->DropCards(dragstack);
+        
+        if(dropstackid != CS_DROPZONE_NODROP)
+            pDestStack = parentWnd.CardRegionFromId(dropstackid);
+        else
+            pDestStack = 0;
+    }
+    else
+    {
+        pDestStack = parentWnd.GetBestStack(x - mousexoffset, y - mouseyoffset, nDragCardWidth, nDragCardHeight);
+    }
+    
+    // If have found a stack to drop onto
+    //
+    TRACE ( "can I drop card?\n" );
+    if(pDestStack && pDestStack->CanDropCards(dragstack)) 
+    {
+        TRACE ( "yes, dropping card\n" );
+        hdc = GetDC((HWND)parentWnd);
+        //            UseNicePalette(hdc);
+        ZoomCard(hdc, x - mousexoffset, y  - mouseyoffset, pDestStack);
+        ReleaseDC((HWND)parentWnd, hdc);
+        
+        //
+        //add the cards to the destination stack
+        //
+        CardStack temp = pDestStack->GetCardStack();
+        temp.Push(dragstack);
+        
+        pDestStack->SetCardStack(temp);
+//        pDestStack->Update();        //Update this stack's card count + size
+//        pDestStack->UpdateFaceDir(temp);
+        
+        //    Call the remove callback on THIS stack, if one is specified
+        //
+        if(RemoveCallback)
+            RemoveCallback(*this, iNumDragCards);
+
+        //    Call the add callback, if one is specified
+        //
+        if(pDestStack->AddCallback)
+            pDestStack->AddCallback(*pDestStack, pDestStack->cardstack);//index, deststack->numcards);
+        
+        RedrawIfNotDim(pDestStack, true);
+        TRACE ( "done dropping card\n" );
+    }
+
+    //
+    //    Otherwise, let the cards snap back onto this stack
+    //
+    else
+    {
+        TRACE ( "no, putting card back\n" );
+        hdc = GetDC((HWND)parentWnd);
+        TRACE ( "calling ZoomCard()\n" );
+        ZoomCard(hdc, x - mousexoffset, y - mouseyoffset, this);
+        TRACE ( "cardstack += dragstack\n" );
+        cardstack += dragstack;
+        TRACE ( "calling ReleaseDC()\n" );
+        ReleaseDC((HWND)parentWnd, hdc);
+
+        TRACE ( "calling Update()\n" );
+        Update();        //Update this stack's card count + size
+        TRACE ( "done putting card back\n" );
+    }
+    
+    ReleaseDragBitmaps();
+    ReleaseCapture();
+    
+    TRACE ( "OnLButtonUp() done\n" );
+    return true;
+}
+
+bool CardRegion::OnMouseMove(int x, int y)
+{
+    HDC hdc;
+
+    hdc = GetDC((HWND)parentWnd);
+        
+    x -= mousexoffset;
+    y -= mouseyoffset;
+        
+    MoveDragCardTo(hdc, x, y);
+
+    //BitBlt(hdc, nDragCardWidth+10, 0, nDragCardWidth, nDragCardHeight, hdcBackGnd, 0, 0, SRCCOPY);
+    //BitBlt(hdc, 0, 0, nDragCardWidth, nDragCardHeight, hdcDragCard, 0, 0, SRCCOPY);
+    
+    ReleaseDC((HWND)parentWnd, hdc);
+        
+    oldx = x;
+    oldy = y;
+    
+    return true;
+}
+
+//
+//    There is a bug in BitBlt when the source x,y
+//    become < 0. So this wrapper function simply adjusts
+//    the coords so that we never try to blt in from this range
+//
+BOOL ClippedBitBlt(HDC hdcDest, int x, int y, int width, int height, HDC hdcSrc, int srcx, int srcy, DWORD dwROP)
+{
+    if(srcx < 0)
+    {
+        x = 0 - srcx;
+        width = width + srcx;
+        srcx = 0;
+    }
+
+    if(srcy < 0)
+    {
+        y = 0 - srcy;
+        height = height + srcy;
+        srcy = 0;
+    }
+
+    return BitBlt(hdcDest, x, y, width, height, hdcSrc, srcx, srcy, dwROP);
+}
+
+void CardRegion::MoveDragCardTo(HDC hdc, int x, int y)
+{
+    RECT inter, rect1, rect2;
+
+    //mask off the new position of the drag-card, so
+    //that it will not be painted over
+    ClipCard(hdc, x, y, nDragCardWidth, nDragCardHeight);
+    
+    //restore the area covered by the card at its previous position
+    BitBlt(hdc, oldx, oldy, nDragCardWidth, nDragCardHeight, hdcBackGnd, 0, 0, SRCCOPY);
+
+    //remove clipping so we can draw the card at its new place
+    SelectClipRgn(hdc, NULL);
+    
+    //if the card's old and new positions overlap, then we
+    //need some funky code to update the "saved background" image,
+    SetRect(&rect1, oldx, oldy, oldx+nDragCardWidth, oldy+nDragCardHeight);
+    SetRect(&rect2,    x,    y,    x+nDragCardWidth,    y+nDragCardHeight);
+    
+    if(IntersectRect(&inter, &rect1, &rect2))
+    {
+        int interwidth = inter.right-inter.left;
+        int interheight = inter.bottom-inter.top;
+        int destx, desty, srcx, srcy;
+        
+        if(rect2.left > rect1.left) 
+        {    
+            destx = 0; srcx = nDragCardWidth - interwidth; 
+        }
+        else
+        {
+            destx = nDragCardWidth  - interwidth; srcx = 0;
+        }
+        
+        if(rect2.top  > rect1.top) 
+        {
+            desty = 0; srcy = nDragCardHeight - interheight;
+        }
+        else 
+        {
+            desty = nDragCardHeight - interheight; srcy = 0;
+        }
+        
+        //shift the bit we didn't use for the restore (due to the clipping)
+        //into the opposite corner
+        BitBlt(hdcBackGnd, destx,desty, interwidth, interheight, hdcBackGnd, srcx, srcy, SRCCOPY);
+        
+        ExcludeClipRect(hdcBackGnd, destx, desty, destx+interwidth, desty+interheight);
+        
+        //this bit requires us to clip the BitBlt (from screen to background)
+        //as BitBlt is a bit buggy it seems
+        ClippedBitBlt(hdcBackGnd, 0,0, nDragCardWidth, nDragCardHeight, hdc, x, y, SRCCOPY);
+        SelectClipRgn(hdcBackGnd, NULL);
+    }
+    else
+    {
+        BitBlt(hdcBackGnd, 0,0, nDragCardWidth, nDragCardHeight, hdc, x, y, SRCCOPY);
+    }
+    
+    //finally draw the card to the screen
+    DrawCard(hdc, x, y, hdcDragCard, nDragCardWidth, nDragCardHeight);
+}
+
+
+//extern "C" int _fltused(void) { return 0; }
+//extern "C" int _ftol(void) { return 0; }
+
+//
+//    Better do this in fixed-point, to stop
+//    VC from linking in floatingpoint-long conversions
+//
+//#define FIXED_PREC_MOVE
+#ifdef  FIXED_PREC_MOVE
+#define PRECISION 12
+void ZoomCard(HDC hdc, int xpos, int ypos, CARDSTACK *dest)
+{
+    long dx, dy, x , y;
+
+    
+    int apparentcards;
+    x = xpos << PRECISION; y = ypos << PRECISION;
+
+    oldx = (int)xpos;
+    oldy = (int)ypos;
+
+    apparentcards=dest->numcards/dest->threedcount;
+
+    int idestx = dest->xpos + dest->xoffset * (apparentcards);// - iNumDragCards); 
+    int idesty = dest->ypos + dest->yoffset * (apparentcards);// - iNumDragCards);
+
+    //normalise the motion vector
+    dx = (idestx<<PRECISION) - x;
+    dy = (idesty<<PRECISION) - y;
+    long recip = (1 << PRECISION) / 1;//sqrt(dx*dx + dy*dy);
+
+    dx *= recip * 16;//CARDZOOMSPEED; 
+    dy *= recip * 16;//CARDZOOMSPEED;
+
+    //if(dx < 0) dxinc = 1.001; else
+
+    for(;;)
+    {
+        int ix, iy;
+        x += dx;
+        y += dy;
+
+        ix = (int)x>>PRECISION;
+        iy = (int)y>>PRECISION;
+        if(dx < 0 && ix < idestx) ix = idestx;
+        else if(dx > 0 && ix > idestx) ix = idestx;
+
+        if(dy < 0 && iy < idesty) iy = idesty;
+        else if(dy > 0 && iy > idesty) iy = idesty;
+
+        MoveDragCardTo(hdc, ix, iy);
+
+        if(ix == idestx && iy == idesty)
+            break;
+
+        oldx = (int)x >> PRECISION;
+        oldy = (int)y >> PRECISION;
+
+        //dx *= 1.2;
+        //dy *= 1.2;
+
+        Sleep(10);
+    }
+}
+#else
+void CardRegion::ZoomCard(HDC hdc, int xpos, int ypos, CardRegion *pDestStack)
+{
+    TRACE ( "ENTER ZoomCard()\n" );
+    double dx, dy, x ,y;
+    int apparentcards;
+    x = (double)xpos; y = (double)ypos;
+
+    oldx = (int)x;
+    oldy = (int)y;
+
+    apparentcards = pDestStack->cardstack.NumCards() / pDestStack->nThreedCount;
+
+    int idestx = pDestStack->xpos + pDestStack->xoffset * (apparentcards);
+    int idesty = pDestStack->ypos + pDestStack->yoffset * (apparentcards);
+
+    if(pDestStack->yoffset < 0)
+        idesty += pDestStack->yoffset * (iNumDragCards-1);
+
+    if(pDestStack->xoffset < 0)
+        idestx += pDestStack->xoffset * (iNumDragCards-1);
+
+    //normalise the motion vector
+    dx = idestx - x;
+    dy = idesty - y;
+    if ( fabs(dx) + fabs(dy) < 0.001f )
+    {
+        MoveDragCardTo(hdc, idestx, idesty);
+        return;
+    }
+    double recip = 1.0 / sqrt(dx*dx + dy*dy);
+    dx *= recip * __CARDZOOMSPEED; dy *= recip * __CARDZOOMSPEED;
+
+    //if(dx < 0) dxinc = 1.001; else
+
+    for(;;)
+    {
+        bool attarget = true;
+        int ix, iy;
+        x += dx;
+        y += dy;
+
+        ix = (int)x;
+        iy = (int)y;
+
+        if(dx < 0.0 && ix < idestx) ix = idestx;
+        else if(dx > 0.0 && ix > idestx) ix = idestx;
+        else attarget = false;
+
+        if(dy < 0.0 && iy < idesty) iy = idesty;
+        else if(dy > 0.0 && iy > idesty) iy = idesty;
+        else attarget = false;
+
+        //if the target stack wants the drag cards drawn differently
+        //to how they are, then redraw the drag card image just before
+        //the cards land
+        /*if(attarget == true)
+        {
+            for(int i = 0; i < iNumDragCards; i++)
+            {
+                int xdraw = pDestStack->xoffset*i;
+                int ydraw = pDestStack->yoffset*i;
+
+                if(pDestStack->yoffset < 0)
+                    ydraw = -pDestStack->yoffset * (iNumDragCards-i-1);
+                if(pDestStack->xoffset < 0)
+                    xdraw = -pDestStack->xoffset * (iNumDragCards-i-1);
+
+                if(pDestStack->facedirection == CS_FACEUP && 
+                    pDestStack->numcards+i >= dest->numfacedown)
+                {
+                    //cdtDraw(hdcDragCard, xdraw, ydraw, iDragCards[i], ectFACES, 0);
+                }
+                else
+                {
+                    //cdtDraw(hdcDragCard, xdraw, ydraw, CARDSTACK::backcard, ectBACKS, 0);
+                }
+            }
+        }*/
+
+        MoveDragCardTo(hdc, ix, iy);
+
+        if(attarget || ix == idestx && iy == idesty)
+            break;
+
+        oldx = (int)x;
+        oldy = (int)y;
+
+        //dx *= 1.2;
+        //dy *= 1.2;
+
+        Sleep(10);
+    }
+    TRACE ( "EXIT ZoomCard()\n" );
+}
+#endif
index 06b9f25..8273b23 100644 (file)
-//\r
-//    CardLib - CardStack class\r
-//\r
-//    Freeware\r
-//    Copyright J Brown 2001\r
-//\r
-#include <windows.h>\r
-#include <stdlib.h>\r
-\r
-#include "cardstack.h"\r
-\r
-Card &CardStack::operator[] (size_t index)\r
-{\r
-    if(index >= (size_t)nNumCards) index = nNumCards - 1;\r
-    return cardlist[nNumCards - index - 1];\r
-}\r
-\r
-const Card &CardStack::operator[] (size_t index) const\r
-{\r
-    if(index >= (size_t)nNumCards) index = nNumCards - 1;\r
-    return cardlist[nNumCards - index - 1];\r
-}\r
-\r
-//    Subscripting operator for a constant sequence\r
-//\r
-/*Card CardStack::operator[] (size_t index) const\r
-{\r
-    return cardlist[index];\r
-}*/\r
-\r
-//\r
-//    Subscripting operator for a non-const sequence\r
-//\r
-/*CardStack::ref  CardStack::operator[] (size_t index)\r
-{\r
-    return ref(this, index);\r
-}*/\r
-\r
-void CardStack::Clear()\r
-{\r
-    nNumCards = 0;\r
-}\r
-\r
-void CardStack::NewDeck()\r
-{\r
-    nNumCards = 52;\r
-\r
-    for(int i = 0; i < 52; i++)\r
-        cardlist[i].nValue = i;\r
-}\r
-\r
-void CardStack::Shuffle()\r
-{\r
-    int src, dest;\r
-    Card temp;\r
-\r
-    //shuffle 8 times..\r
-    for(int i = 0; i < 8; i++)\r
-        for(dest = nNumCards - 1; dest > 0; dest--)\r
-        {\r
-            //want to do this:\r
-            //  bad:   src = rand() % (dest + 1)\r
-            //  good:  src = rand() / (RAND_MAX / (dest+1) + 1)\r
-            \r
-            //positions from 0 to dest\r
-            src = rand() / (RAND_MAX / (dest+1) + 1);\r
-            \r
-            //swap the cards\r
-            temp           = cardlist[src];\r
-            cardlist[src]  = cardlist[dest];\r
-            cardlist[dest] = temp;\r
-        }\r
-}\r
-\r
-void CardStack::Reverse()\r
-{\r
-    for(int i = 0; i < nNumCards / 2; i++)\r
-    {\r
-        Card temp                   = cardlist[i];\r
-        cardlist[i]                 = cardlist[nNumCards - i - 1];\r
-        cardlist[nNumCards - i - 1] = temp;\r
-    }\r
-}\r
-\r
-void CardStack::Push(const Card card)\r
-{\r
-    if(nNumCards < MAX_CARDSTACK_SIZE)\r
-        cardlist[nNumCards++] = card;\r
-}\r
-\r
-void CardStack::Push(const CardStack &cardstack)\r
-{\r
-    if(nNumCards + cardstack.nNumCards < MAX_CARDSTACK_SIZE)\r
-    {\r
-        int num = cardstack.NumCards();\r
-        \r
-        for(int i = 0; i < num; i++)\r
-            cardlist[nNumCards++] = cardstack.cardlist[i];\r
-    }\r
-}\r
-\r
-CardStack& CardStack::operator += (Card card)\r
-{\r
-    Push(card);\r
-    return *this;\r
-}\r
-\r
-CardStack& CardStack::operator += (CardStack &cs)\r
-{\r
-    Push(cs);\r
-    return *this;\r
-}\r
-\r
-CardStack CardStack::operator +  (Card card)\r
-{\r
-    CardStack poo = *this;\r
-    poo.Push(card);\r
-    return poo;\r
-}\r
-\r
-CardStack CardStack::operator + (CardStack &cs)\r
-{\r
-    CardStack poo = *this;\r
-    poo.Push(cs);\r
-    return poo;\r
-}\r
-\r
-\r
-Card CardStack::Pop()\r
-{\r
-    if(nNumCards > 0)\r
-        return cardlist[--nNumCards];\r
-    else\r
-        return 0;\r
-}\r
-\r
-CardStack CardStack::Pop(int items)\r
-{\r
-    if(items <= nNumCards && nNumCards > 0)\r
-    {\r
-        CardStack cs(*this, nNumCards - items);\r
-\r
-        nNumCards -= items;\r
-\r
-        return cs;\r
-    }\r
-    else\r
-    {\r
-        return CardStack();\r
-    }\r
-}\r
-\r
-Card CardStack::Top()\r
-{\r
-    if(nNumCards > 0)\r
-        return cardlist[nNumCards - 1];\r
-    else\r
-        return 0;\r
-}\r
-\r
-CardStack CardStack::Top(int items)\r
-{\r
-    if(items <= nNumCards && nNumCards > 0)\r
-    {\r
-        return CardStack (*this, nNumCards - items);\r
-    }\r
-    else\r
-    {\r
-        return CardStack();\r
-    }\r
-\r
-}\r
-\r
-Card CardStack::RemoveCard(size_t index)\r
-{\r
-    if(nNumCards == 0 || index >= (size_t)nNumCards)\r
-        return 0;\r
-\r
-    //put index into reverse range..\r
-    index = nNumCards - index - 1;\r
-\r
-    Card temp = cardlist[index];\r
-\r
-    nNumCards--;\r
-\r
-    for(size_t i = index; i < (size_t)nNumCards; i++)\r
-    {\r
-        cardlist[i] = cardlist[i+1];\r
-    }\r
-\r
-    return temp;\r
-}\r
-\r
-void CardStack::InsertCard(size_t index, Card card)\r
-{\r
-    if(nNumCards == MAX_CARDSTACK_SIZE)\r
-        return;\r
-\r
-    if(index > (size_t)nNumCards)\r
-        return;\r
-\r
-    if((size_t)nNumCards == index)\r
-    {\r
-        cardlist[nNumCards] = card;\r
-        nNumCards++;\r
-        return;\r
-    }\r
-\r
-    //put index into reverse range..\r
-    index = nNumCards - index - 1;\r
-\r
-    nNumCards++;\r
-\r
-    //make room for the card\r
-    for(size_t i = nNumCards; i > index; i--)\r
-    {\r
-        cardlist[i] = cardlist[i - 1];\r
-    }\r
-\r
-    cardlist[index] = card;\r
-}\r
-\r
-\r
-void CardStack::Print()\r
-{\r
-//    for(int i = 0; i < nNumCards; i++)\r
-//        cout << cardlist[i].HiVal() << " ";\r
-}\r
-\r
-CardStack::CardStack(CardStack &copythis, size_t fromindex)\r
-{\r
-    nNumCards = copythis.nNumCards - fromindex;\r
-\r
-    for(int i = 0; i < nNumCards; i++)\r
-        cardlist[i] = copythis.cardlist[fromindex + i];\r
-}\r
-\r
+//
+//    CardLib - CardStack class
+//
+//    Freeware
+//    Copyright J Brown 2001
+//
+#include <windows.h>
+#include <stdlib.h>
+
+#include "cardstack.h"
+
+Card &CardStack::operator[] (size_t index)
+{
+    if(index >= (size_t)nNumCards) index = nNumCards - 1;
+    return cardlist[nNumCards - index - 1];
+}
+
+const Card &CardStack::operator[] (size_t index) const
+{
+    if(index >= (size_t)nNumCards) index = nNumCards - 1;
+    return cardlist[nNumCards - index - 1];
+}
+
+//    Subscripting operator for a constant sequence
+//
+/*Card CardStack::operator[] (size_t index) const
+{
+    return cardlist[index];
+}*/
+
+//
+//    Subscripting operator for a non-const sequence
+//
+/*CardStack::ref  CardStack::operator[] (size_t index)
+{
+    return ref(this, index);
+}*/
+
+void CardStack::Clear()
+{
+    nNumCards = 0;
+}
+
+void CardStack::NewDeck()
+{
+    nNumCards = 52;
+
+    for(int i = 0; i < 52; i++)
+        cardlist[i].nValue = i;
+}
+
+void CardStack::Shuffle()
+{
+    int src, dest;
+    Card temp;
+
+    //shuffle 8 times..
+    for(int i = 0; i < 8; i++)
+        for(dest = nNumCards - 1; dest > 0; dest--)
+        {
+            //want to do this:
+            //  bad:   src = rand() % (dest + 1)
+            //  good:  src = rand() / (RAND_MAX / (dest+1) + 1)
+            
+            //positions from 0 to dest
+            src = rand() / (RAND_MAX / (dest+1) + 1);
+            
+            //swap the cards
+            temp           = cardlist[src];
+            cardlist[src]  = cardlist[dest];
+            cardlist[dest] = temp;
+        }
+}
+
+void CardStack::Reverse()
+{
+    for(int i = 0; i < nNumCards / 2; i++)
+    {
+        Card temp                   = cardlist[i];
+        cardlist[i]                 = cardlist[nNumCards - i - 1];
+        cardlist[nNumCards - i - 1] = temp;
+    }
+}
+
+void CardStack::Push(const Card card)
+{
+    if(nNumCards < MAX_CARDSTACK_SIZE)
+        cardlist[nNumCards++] = card;
+}
+
+void CardStack::Push(const CardStack &cardstack)
+{
+    if(nNumCards + cardstack.nNumCards < MAX_CARDSTACK_SIZE)
+    {
+        int num = cardstack.NumCards();
+        
+        for(int i = 0; i < num; i++)
+            cardlist[nNumCards++] = cardstack.cardlist[i];
+    }
+}
+
+CardStack& CardStack::operator += (Card card)
+{
+    Push(card);
+    return *this;
+}
+
+CardStack& CardStack::operator += (CardStack &cs)
+{
+    Push(cs);
+    return *this;
+}
+
+CardStack CardStack::operator +  (Card card)
+{
+    CardStack poo = *this;
+    poo.Push(card);
+    return poo;
+}
+
+CardStack CardStack::operator + (CardStack &cs)
+{
+    CardStack poo = *this;
+    poo.Push(cs);
+    return poo;
+}
+
+
+Card CardStack::Pop()
+{
+    if(nNumCards > 0)
+        return cardlist[--nNumCards];
+    else
+        return 0;
+}
+
+CardStack CardStack::Pop(int items)
+{
+    if(items <= nNumCards && nNumCards > 0)
+    {
+        CardStack cs(*this, nNumCards - items);
+
+        nNumCards -= items;
+
+        return cs;
+    }
+    else
+    {
+        return CardStack();
+    }
+}
+
+Card CardStack::Top()
+{
+    if(nNumCards > 0)
+        return cardlist[nNumCards - 1];
+    else
+        return 0;
+}
+
+CardStack CardStack::Top(int items)
+{
+    if(items <= nNumCards && nNumCards > 0)
+    {
+        return CardStack (*this, nNumCards - items);
+    }
+    else
+    {
+        return CardStack();
+    }
+
+}
+
+Card CardStack::RemoveCard(size_t index)
+{
+    if(nNumCards == 0 || index >= (size_t)nNumCards)
+        return 0;
+
+    //put index into reverse range..
+    index = nNumCards - index - 1;
+
+    Card temp = cardlist[index];
+
+    nNumCards--;
+
+    for(size_t i = index; i < (size_t)nNumCards; i++)
+    {
+        cardlist[i] = cardlist[i+1];
+    }
+
+    return temp;
+}
+
+void CardStack::InsertCard(size_t index, Card card)
+{
+    if(nNumCards == MAX_CARDSTACK_SIZE)
+        return;
+
+    if(index > (size_t)nNumCards)
+        return;
+
+    if((size_t)nNumCards == index)
+    {
+        cardlist[nNumCards] = card;
+        nNumCards++;
+        return;
+    }
+
+    //put index into reverse range..
+    index = nNumCards - index - 1;
+
+    nNumCards++;
+
+    //make room for the card
+    for(size_t i = nNumCards; i > index; i--)
+    {
+        cardlist[i] = cardlist[i - 1];
+    }
+
+    cardlist[index] = card;
+}
+
+
+void CardStack::Print()
+{
+//    for(int i = 0; i < nNumCards; i++)
+//        cout << cardlist[i].HiVal() << " ";
+}
+
+CardStack::CardStack(CardStack &copythis, size_t fromindex)
+{
+    nNumCards = copythis.nNumCards - fromindex;
+
+    for(int i = 0; i < nNumCards; i++)
+        cardlist[i] = copythis.cardlist[fromindex + i];
+}
+
index eae8736..03d98f1 100644 (file)
@@ -1,53 +1,53 @@
-#ifndef CARDSTACK_INCLUDED\r
-#define CARDSTACK_INCLUDED\r
-\r
-#include "card.h"\r
-\r
-#define MAX_CARDSTACK_SIZE 128\r
-\r
-class CardStack\r
-{\r
-       friend class CardRegion;\r
-\r
-public:\r
-       CardStack() : nNumCards(0) { }\r
-\r
-       void            NewDeck();\r
-       int                     NumCards() const { return nNumCards; }\r
-       void            Shuffle();\r
-       void            Clear();\r
-       void            Reverse();\r
-       \r
-       void            Push(const Card card);\r
-       void            Push(const CardStack &cardstack);\r
-\r
-       Card            Pop();\r
-       CardStack       Pop(int items);\r
-\r
-       Card            Top();\r
-       CardStack       Top(int items);\r
-\r
-       void Print();\r
-\r
-       Card            RemoveCard(size_t index);\r
-       void            InsertCard(size_t index, Card card);\r
-\r
-       //subscript capability!!\r
-             Card & operator[] (size_t index);\r
-       const Card & operator[] (size_t index) const;\r
-\r
-       CardStack &operator += (Card card);\r
-       CardStack &operator += (CardStack &cs);\r
-\r
-       CardStack operator +  (Card card);\r
-       CardStack operator +  (CardStack &cs);\r
-               \r
-private:       \r
-\r
-       CardStack(CardStack &copythis, size_t fromindex);\r
-\r
-       Card cardlist[MAX_CARDSTACK_SIZE];\r
-       int  nNumCards;\r
-};\r
-\r
-#endif\r
+#ifndef CARDSTACK_INCLUDED
+#define CARDSTACK_INCLUDED
+
+#include "card.h"
+
+#define MAX_CARDSTACK_SIZE 128
+
+class CardStack
+{
+       friend class CardRegion;
+
+public:
+       CardStack() : nNumCards(0) { }
+
+       void            NewDeck();
+       int                     NumCards() const { return nNumCards; }
+       void            Shuffle();
+       void            Clear();
+       void            Reverse();
+       
+       void            Push(const Card card);
+       void            Push(const CardStack &cardstack);
+
+       Card            Pop();
+       CardStack       Pop(int items);
+
+       Card            Top();
+       CardStack       Top(int items);
+
+       void Print();
+
+       Card            RemoveCard(size_t index);
+       void            InsertCard(size_t index, Card card);
+
+       //subscript capability!!
+             Card & operator[] (size_t index);
+       const Card & operator[] (size_t index) const;
+
+       CardStack &operator += (Card card);
+       CardStack &operator += (CardStack &cs);
+
+       CardStack operator +  (Card card);
+       CardStack operator +  (CardStack &cs);
+               
+private:       
+
+       CardStack(CardStack &copythis, size_t fromindex);
+
+       Card cardlist[MAX_CARDSTACK_SIZE];
+       int  nNumCards;
+};
+
+#endif
index 4455086..1eea0bf 100644 (file)
-//\r
-//    CardLib - CardWindow class\r
-//\r
-//    Freeware\r
-//    Copyright J Brown 2001\r
-//\r
-#include <windows.h>\r
-#include <tchar.h>\r
-\r
-#include "globals.h"\r
-#include "cardlib.h"\r
-#include "cardbutton.h"\r
-#include "cardregion.h"\r
-#include "cardwindow.h"\r
-#include "cardcolor.h"\r
-\r
-extern HPALETTE __holdplacepal;\r
-\r
-HPALETTE UseNicePalette(HDC hdc, HPALETTE hPalette)\r
-{\r
-    HPALETTE hOld;\r
-\r
-    hOld = SelectPalette(hdc, hPalette, FALSE);\r
-    RealizePalette(hdc);\r
-\r
-    return hOld;\r
-}\r
-\r
-void RestorePalette(HDC hdc, HPALETTE hOldPal)\r
-{\r
-    SelectPalette(hdc, hOldPal, TRUE);\r
-}\r
-\r
-HPALETTE MakePaletteFromCols(COLORREF cols[], int nNumColours);\r
-void     PaintRect(HDC hdc, RECT *rect, COLORREF colour);\r
-HBITMAP  CreateSinkBmp(HDC hdcCompat, HDC hdc, COLORREF col, int width, int height);\r
-void     GetSinkCols(COLORREF crBase, COLORREF *fg, COLORREF *bg, COLORREF *sh1, COLORREF *sh2);\r
-\r
-void     LoadCardBitmaps();\r
-void     FreeCardBitmaps();\r
-\r
-static TCHAR szCardName[]   = _T("CardWnd32");\r
-static bool  fRegistered    = false;\r
-static LONG  uCardBitmapRef = 0;\r
-\r
-\r
-void RegisterCardWindow()\r
-{\r
-    WNDCLASSEX wc;\r
-\r
-    //Window class for the main application parent window\r
-    wc.cbSize            = sizeof(wc);\r
-    wc.style            = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;\r
-    wc.lpfnWndProc        = CardWindow::CardWndProc;\r
-    wc.cbClsExtra        = 0;\r
-    wc.cbWndExtra        = sizeof(CardWindow *);\r
-    wc.hInstance        = GetModuleHandle(0);\r
-    wc.hIcon            = 0;\r
-    wc.hCursor            = LoadCursor (NULL, IDC_ARROW);\r
-    wc.hbrBackground    = 0;\r
-    wc.lpszMenuName        = 0;\r
-    wc.lpszClassName    = szCardName;\r
-    wc.hIconSm            = 0;\r
-\r
-    RegisterClassEx(&wc);\r
-}\r
-\r
-CardWindow::CardWindow() : m_hWnd(0)\r
-{\r
-    HDC hdc = GetDC(0);\r
-\r
-    nNumButtons       = 0;\r
-    nNumCardRegions   = 0;\r
-    nNumDropZones     = 0;\r
-    nBackCardIdx      = 53;\r
-\r
-    ResizeWndCallback = 0;\r
-    hbmBackImage      = 0;\r
-    hdcBackImage      = 0;\r
-\r
-    srand((unsigned)GetTickCount());\r
-\r
-    //All colours (buttons, highlights, decks)\r
-    //are calculated off this single base colour\r
-    crBackgnd = PALETTERGB(0,80,0);//PALETTERGB(0,64,100);\r
-\r
-    // If uCardBitmapRef was previously zero, then\r
-    // load the card bitmaps\r
-    if(1 == InterlockedIncrement(&uCardBitmapRef))\r
-    {\r
-        LoadCardBitmaps();\r
-\r
-        __hPalette  = CreateCardPalette();\r
-\r
-        __hdcPlaceHolder  = CreateCompatibleDC(hdc);\r
-    \r
-        __holdplacepal  = UseNicePalette(__hdcPlaceHolder, __hPalette);\r
-\r
-        __hbmPlaceHolder  = CreateSinkBmp(hdc, __hdcPlaceHolder, crBackgnd, __cardwidth, __cardheight);\r
-\r
-    }\r
-\r
-    ReleaseDC(0, hdc);\r
-\r
-    //register the window class if necessary\r
-    if(!fRegistered)\r
-    {\r
-        fRegistered = true;\r
-        RegisterCardWindow();\r
-    }\r
-\r
-}\r
-\r
-BOOL CardWindow::Create(HWND hwndParent, DWORD dwExStyle, DWORD dwStyle, int x, int y, int width, int height)\r
-{\r
-    if(m_hWnd)\r
-        return FALSE;\r
-\r
-    //Create the window associated with this object\r
-    m_hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, szCardName, 0, \r
-        WS_CHILD | WS_VISIBLE,\r
-        0,0,100,100, \r
-        hwndParent, 0, GetModuleHandle(0), this);\r
-\r
-    return TRUE;\r
-}\r
-\r
-BOOL CardWindow::Destroy()\r
-{\r
-    DestroyWindow(m_hWnd);\r
-    m_hWnd = 0;\r
-\r
-    return TRUE;\r
-}\r
-\r
-CardWindow::~CardWindow()\r
-{\r
-    if(m_hWnd)\r
-        DestroyWindow(m_hWnd);\r
-\r
-    DeleteAll();\r
-\r
-    if(0 == InterlockedDecrement(&uCardBitmapRef))\r
-    {\r
-        FreeCardBitmaps();\r
-\r
-        DeleteObject(__hbmPlaceHolder);\r
-        DeleteDC    (__hdcPlaceHolder);\r
-\r
-        RestorePalette(__hdcPlaceHolder, __holdplacepal);\r
-\r
-        if(__hPalette)\r
-            DeleteObject(__hPalette);\r
-    }\r
-}\r
-\r
-bool CardWindow::DeleteAll()\r
-{\r
-    int i;\r
-\r
-    for(i = 0; i < nNumCardRegions; i++)\r
-    {\r
-        delete Regions[i];\r
-    }\r
-\r
-    for(i = 0; i < nNumButtons; i++)\r
-    {\r
-        delete Buttons[i];\r
-    }\r
-\r
-    for(i = 0; i < nNumDropZones; i++)\r
-    {\r
-        delete dropzone[i];\r
-    }\r
-\r
-    nNumCardRegions = nNumButtons = nNumDropZones = 0;\r
-\r
-    return true;\r
-}\r
-\r
-void CardWindow::SetBackColor(COLORREF cr)\r
-{\r
-    crBackgnd = cr;\r
-    int i;\r
-    \r
-    //\r
-    // Create the exact palette we need to render the buttons/stacks\r
-    //\r
-    RestorePalette(__hdcPlaceHolder, __holdplacepal);\r
-\r
-    if(__hPalette)\r
-        DeleteObject(__hPalette);\r
-\r
-    __hPalette = CreateCardPalette();\r
-\r
-    //\r
-    // re-create the place-holder!\r
-    HDC hdc = GetDC(m_hWnd);\r
-\r
-    DeleteObject(__hbmPlaceHolder);\r
-\r
-    __holdplacepal = UseNicePalette(__hdcPlaceHolder, __hPalette);\r
-\r
-    __hbmPlaceHolder = CreateSinkBmp(hdc, __hdcPlaceHolder, crBackgnd, __cardwidth, __cardheight);\r
-    //SelectObject(__hdcPlaceHolder, __hbmPlaceHolder);\r
-\r
-    //reset all buttons to same colour\r
-    for(i = 0; i < nNumButtons; i++)\r
-    {\r
-        if(Buttons[i]->GetStyle() & CB_PUSHBUTTON)\r
-        {\r
-            Buttons[i]->SetBackColor(ColorScaleRGB(crBackgnd, RGB(255,255,255), 0.1));\r
-        }\r
-        else\r
-        {\r
-            Buttons[i]->SetBackColor(crBackgnd);\r
-        }\r
-    }\r
-\r
-    for(i = 0; i < nNumCardRegions; i++)\r
-    {\r
-        Regions[i]->SetBackColor(crBackgnd);\r
-    }\r
-\r
-\r
-    ReleaseDC(m_hWnd, hdc);\r
-}\r
-\r
-COLORREF CardWindow::GetBackColor()\r
-{\r
-    return crBackgnd;\r
-}\r
-\r
-CardButton* CardWindow::CardButtonFromPoint(int x, int y)\r
-{\r
-    CardButton *bptr = 0;\r
-\r
-    POINT pt;\r
-    pt.x = x;\r
-    pt.y = y;\r
-\r
-    //Search BACKWARDS...to reflect the implicit Z-order that\r
-    //the button creation provided\r
-    for(int i = nNumButtons - 1; i >= 0; i--)\r
-    {\r
-        bptr = Buttons[i];\r
-        if(PtInRect(&bptr->rect, pt) && bptr->fVisible)\r
-            return bptr;\r
-    }\r
-\r
-    return 0;    \r
-}\r
-\r
-CardRegion* CardWindow::CardRegionFromPoint(int x, int y)\r
-{\r
-    POINT pt;\r
-    pt.x = x;\r
-    pt.y = y;\r
-\r
-    //Search BACKWARDS...to reflect the implicit Z-order that\r
-    //the stack creation provided\r
-    for(int i = nNumCardRegions - 1; i >= 0; i--)\r
-    {\r
-        if(Regions[i]->IsPointInStack(x, y))\r
-            return Regions[i];\r
-    }\r
-\r
-    return 0;    \r
-}\r
-\r
-//\r
-//    Forward all window messages onto the appropriate\r
-//  class instance\r
-//\r
-LRESULT CALLBACK CardWindow::CardWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)\r
-{\r
-    CardWindow *cw = (CardWindow *)GetWindowLong(hwnd, 0);\r
-    return cw->WndProc(hwnd, iMsg, wParam, lParam);\r
-}\r
-\r
-void CardWindow::Paint(HDC hdc)\r
-{\r
-    int i;\r
-    RECT rect;\r
-    HPALETTE hOldPal;\r
-\r
-    hOldPal = UseNicePalette(hdc, __hPalette);\r
-\r
-    //\r
-    //    Clip the card stacks so that they won't\r
-    //    get painted over\r
-    //\r
-    for(i = 0; i < nNumCardRegions; i++)\r
-    {\r
-        Regions[i]->Clip(hdc);\r
-    }\r
-\r
-    //\r
-    //    Clip the buttons \r
-    //\r
-    for(i = 0; i < nNumButtons; i++)\r
-    {\r
-        Buttons[i]->Clip(hdc);\r
-    }\r
-\r
-\r
-    //    Now paint the whole screen with background colour, \r
-    //\r
-    GetClientRect(m_hWnd, &rect);\r
-    \r
-    //PaintRect(hdc, &rect, MAKE_PALETTERGB(crBackgnd));\r
-    PaintCardRgn(hdc, 0, 0, rect.right, rect.bottom, 0, 0);\r
-    SelectClipRgn(hdc, NULL);\r
-\r
-    //    Don't let cards draw over buttons, so clip buttons again\r
-    //\r
-    for(i = 0; i < nNumButtons; i++)\r
-    {\r
-        But