mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 00:54:40 +00:00
imported catch-22 sol clone with authors permission
svn path=/trunk/; revision=13904
This commit is contained in:
parent
59b8be68dc
commit
e415037205
32 changed files with 7127 additions and 0 deletions
22
rosapps/games/solitaire/ReadMe.txt
Normal file
22
rosapps/games/solitaire/ReadMe.txt
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
Solitaire for ReactOS
|
||||||
|
|
||||||
|
/*****************************************
|
||||||
|
A complete working example of the CardLib
|
||||||
|
card-game library.
|
||||||
|
|
||||||
|
Freeware
|
||||||
|
Copyright J Brown 2001
|
||||||
|
|
||||||
|
Updates at http://www.catch22.net
|
||||||
|
|
||||||
|
******************************************/
|
||||||
|
|
||||||
|
The author has given permission to use these sources
|
||||||
|
under Public Domain. Do what thou will but please give
|
||||||
|
credit where credit is due.
|
||||||
|
|
||||||
|
If you wish to use cardlib to write another card game
|
||||||
|
for ReactOS please make cardlib a static lib.
|
||||||
|
|
||||||
|
-sedwards
|
||||||
|
|
105
rosapps/games/solitaire/cardlib/card.h
Normal file
105
rosapps/games/solitaire/cardlib/card.h
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
//
|
||||||
|
// 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
|
281
rosapps/games/solitaire/cardlib/cardbitmaps.cpp
Normal file
281
rosapps/games/solitaire/cardlib/cardbitmaps.cpp
Normal file
|
@ -0,0 +1,281 @@
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
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;
|
||||||
|
}
|
489
rosapps/games/solitaire/cardlib/cardbutton.cpp
Normal file
489
rosapps/games/solitaire/cardlib/cardbutton.cpp
Normal file
|
@ -0,0 +1,489 @@
|
||||||
|
//
|
||||||
|
// 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), fVisible(visible), uStyle(Style), 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;
|
||||||
|
}
|
489
rosapps/games/solitaire/cardlib/cardbutton.cpp.bak
Normal file
489
rosapps/games/solitaire/cardlib/cardbutton.cpp.bak
Normal file
|
@ -0,0 +1,489 @@
|
||||||
|
//
|
||||||
|
// 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), fVisible(visible), uStyle(Style), 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;
|
||||||
|
}
|
101
rosapps/games/solitaire/cardlib/cardbutton.h
Normal file
101
rosapps/games/solitaire/cardlib/cardbutton.h
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
#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
|
353
rosapps/games/solitaire/cardlib/cardcolor.cpp
Normal file
353
rosapps/games/solitaire/cardlib/cardcolor.cpp
Normal file
|
@ -0,0 +1,353 @@
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
static double Hue, Lum, Sat;
|
||||||
|
|
||||||
|
//RGBtoHLS(col, &Hue, &Lum, &Sat);
|
||||||
|
|
||||||
|
//col = HLStoRGB(Hue, fMax(0.0,Lum-ratio), Sat);
|
||||||
|
|
||||||
|
return ColorScaleHSL(col, RGB(0,0,0), ratio);
|
||||||
|
|
||||||
|
//return col;
|
||||||
|
}
|
||||||
|
|
||||||
|
COLORREF ColorLighter(COLORREF col, double ratio)
|
||||||
|
{
|
||||||
|
static double Hue, Lum, Sat;
|
||||||
|
|
||||||
|
//RGBtoHLS(col, &Hue, &Lum, &Sat);
|
||||||
|
|
||||||
|
//col = HLStoRGB(Hue, fMin(1.0,Lum+ratio), Sat);
|
||||||
|
|
||||||
|
return ColorScaleHSL(col, RGB(255,255,255), ratio);
|
||||||
|
|
||||||
|
//return col;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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
|
16
rosapps/games/solitaire/cardlib/cardcolor.h
Normal file
16
rosapps/games/solitaire/cardlib/cardcolor.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
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)
|
90
rosapps/games/solitaire/cardlib/cardcount.cpp
Normal file
90
rosapps/games/solitaire/cardlib/cardcount.cpp
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
//
|
||||||
|
// 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]--;
|
||||||
|
}
|
31
rosapps/games/solitaire/cardlib/cardcount.h
Normal file
31
rosapps/games/solitaire/cardlib/cardcount.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#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
|
122
rosapps/games/solitaire/cardlib/cardlib.cpp
Normal file
122
rosapps/games/solitaire/cardlib/cardlib.cpp
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
//
|
||||||
|
// 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);
|
||||||
|
}
|
101
rosapps/games/solitaire/cardlib/cardlib.h
Normal file
101
rosapps/games/solitaire/cardlib/cardlib.h
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
#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;
|
||||||
|
|
||||||
|
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
|
658
rosapps/games/solitaire/cardlib/cardregion.cpp
Normal file
658
rosapps/games/solitaire/cardlib/cardregion.cpp
Normal file
|
@ -0,0 +1,658 @@
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
: parentWnd(parent), id(Id), fVisible(visible), xpos(x), ypos(y), xoffset(xOffset), yoffset(yOffset)
|
||||||
|
{
|
||||||
|
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 = -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 != -1)
|
||||||
|
{
|
||||||
|
KillTimer((HWND)parentWnd, uFlashTimer);
|
||||||
|
nFlashCount = 0;
|
||||||
|
uFlashTimer = -1;
|
||||||
|
fFlashVisible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardRegion::DoFlash()
|
||||||
|
{
|
||||||
|
if(uFlashTimer != -1)
|
||||||
|
{
|
||||||
|
fFlashVisible = !fFlashVisible;
|
||||||
|
|
||||||
|
if(--nFlashCount == 0)
|
||||||
|
{
|
||||||
|
KillTimer((HWND)parentWnd, uFlashTimer);
|
||||||
|
uFlashTimer = -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;
|
||||||
|
}
|
216
rosapps/games/solitaire/cardlib/cardregion.h
Normal file
216
rosapps/games/solitaire/cardlib/cardregion.h
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
#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 xoffset; //direction that cards take
|
||||||
|
int yoffset;
|
||||||
|
|
||||||
|
int xpos; //coordinates of stack
|
||||||
|
int ypos;
|
||||||
|
|
||||||
|
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
|
||||||
|
|
613
rosapps/games/solitaire/cardlib/cardrgndraw.cpp
Normal file
613
rosapps/games/solitaire/cardlib/cardrgndraw.cpp
Normal file
|
@ -0,0 +1,613 @@
|
||||||
|
//
|
||||||
|
// 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);
|
||||||
|
}
|
618
rosapps/games/solitaire/cardlib/cardrgnmouse.cpp
Normal file
618
rosapps/games/solitaire/cardlib/cardrgnmouse.cpp
Normal file
|
@ -0,0 +1,618 @@
|
||||||
|
//
|
||||||
|
// CardLib - CardRegion mouse-related stuff
|
||||||
|
//
|
||||||
|
// Freeware
|
||||||
|
// Copyright J Brown 2001
|
||||||
|
//
|
||||||
|
#include <windows.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "cardlib.h"
|
||||||
|
#include "cardwindow.h"
|
||||||
|
#include "cardregion.h"
|
||||||
|
|
||||||
|
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
|
||||||
|
//
|
||||||
|
if(pDestStack && pDestStack->CanDropCards(dragstack))
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Otherwise, let the cards snap back onto this stack
|
||||||
|
//
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
hdc = GetDC((HWND)parentWnd);
|
||||||
|
ZoomCard(hdc, x - mousexoffset, y - mouseyoffset, this);
|
||||||
|
cardstack += dragstack;
|
||||||
|
ReleaseDC((HWND)parentWnd, hdc);
|
||||||
|
|
||||||
|
Update(); //Update this stack's card count + size
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseDragBitmaps();
|
||||||
|
ReleaseCapture();
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
618
rosapps/games/solitaire/cardlib/cardrgnmouse.cpp.bak
Normal file
618
rosapps/games/solitaire/cardlib/cardrgnmouse.cpp.bak
Normal file
|
@ -0,0 +1,618 @@
|
||||||
|
//
|
||||||
|
// CardLib - CardRegion mouse-related stuff
|
||||||
|
//
|
||||||
|
// Freeware
|
||||||
|
// Copyright J Brown 2001
|
||||||
|
//
|
||||||
|
#include <windows.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "cardlib.h"
|
||||||
|
#include "cardwindow.h"
|
||||||
|
#include "cardregion.h"
|
||||||
|
|
||||||
|
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
|
||||||
|
//
|
||||||
|
if(pDestStack && pDestStack->CanDropCards(dragstack))
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Otherwise, let the cards snap back onto this stack
|
||||||
|
//
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
hdc = GetDC((HWND)parentWnd);
|
||||||
|
ZoomCard(hdc, x - mousexoffset, y - mouseyoffset, this);
|
||||||
|
cardstack += dragstack;
|
||||||
|
ReleaseDC((HWND)parentWnd, hdc);
|
||||||
|
|
||||||
|
Update(); //Update this stack's card count + size
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseDragBitmaps();
|
||||||
|
ReleaseCapture();
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
237
rosapps/games/solitaire/cardlib/cardstack.cpp
Normal file
237
rosapps/games/solitaire/cardlib/cardstack.cpp
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
//
|
||||||
|
// 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 ©this, size_t fromindex)
|
||||||
|
{
|
||||||
|
nNumCards = copythis.nNumCards - fromindex;
|
||||||
|
|
||||||
|
for(int i = 0; i < nNumCards; i++)
|
||||||
|
cardlist[i] = copythis.cardlist[fromindex + i];
|
||||||
|
}
|
||||||
|
|
53
rosapps/games/solitaire/cardlib/cardstack.h
Normal file
53
rosapps/games/solitaire/cardlib/cardstack.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#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 ©this, size_t fromindex);
|
||||||
|
|
||||||
|
Card cardlist[MAX_CARDSTACK_SIZE];
|
||||||
|
int nNumCards;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
812
rosapps/games/solitaire/cardlib/cardwindow.cpp
Normal file
812
rosapps/games/solitaire/cardlib/cardwindow.cpp
Normal file
|
@ -0,0 +1,812 @@
|
||||||
|
//
|
||||||
|
// CardLib - CardWindow class
|
||||||
|
//
|
||||||
|
// Freeware
|
||||||
|
// Copyright J Brown 2001
|
||||||
|
//
|
||||||
|
#include <windows.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
|
#include "cardlib.h"
|
||||||
|
#include "cardbutton.h"
|
||||||
|
#include "cardregion.h"
|
||||||
|
#include "cardwindow.h"
|
||||||
|
#include "cardcolor.h"
|
||||||
|
|
||||||
|
extern HPALETTE __holdplacepal;
|
||||||
|
|
||||||
|
HPALETTE UseNicePalette(HDC hdc, HPALETTE hPalette)
|
||||||
|
{
|
||||||
|
HPALETTE hOld;
|
||||||
|
|
||||||
|
hOld = SelectPalette(hdc, hPalette, FALSE);
|
||||||
|
RealizePalette(hdc);
|
||||||
|
|
||||||
|
return hOld;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RestorePalette(HDC hdc, HPALETTE hOldPal)
|
||||||
|
{
|
||||||
|
SelectPalette(hdc, hOldPal, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
HPALETTE MakePaletteFromCols(COLORREF cols[], int nNumColours);
|
||||||
|
void PaintRect(HDC hdc, RECT *rect, COLORREF colour);
|
||||||
|
HBITMAP CreateSinkBmp(HDC hdcCompat, HDC hdc, COLORREF col, int width, int height);
|
||||||
|
void GetSinkCols(COLORREF crBase, COLORREF *fg, COLORREF *bg, COLORREF *sh1, COLORREF *sh2);
|
||||||
|
|
||||||
|
void LoadCardBitmaps();
|
||||||
|
void FreeCardBitmaps();
|
||||||
|
|
||||||
|
static TCHAR szCardName[] = _T("CardWnd32");
|
||||||
|
static bool fRegistered = false;
|
||||||
|
static LONG uCardBitmapRef = 0;
|
||||||
|
|
||||||
|
|
||||||
|
void RegisterCardWindow()
|
||||||
|
{
|
||||||
|
WNDCLASSEX wc;
|
||||||
|
|
||||||
|
//Window class for the main application parent window
|
||||||
|
wc.cbSize = sizeof(wc);
|
||||||
|
wc.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
|
||||||
|
wc.lpfnWndProc = CardWindow::CardWndProc;
|
||||||
|
wc.cbClsExtra = 0;
|
||||||
|
wc.cbWndExtra = sizeof(CardWindow *);
|
||||||
|
wc.hInstance = GetModuleHandle(0);
|
||||||
|
wc.hIcon = 0;
|
||||||
|
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
|
||||||
|
wc.hbrBackground = 0;
|
||||||
|
wc.lpszMenuName = 0;
|
||||||
|
wc.lpszClassName = szCardName;
|
||||||
|
wc.hIconSm = 0;
|
||||||
|
|
||||||
|
RegisterClassEx(&wc);
|
||||||
|
}
|
||||||
|
|
||||||
|
CardWindow::CardWindow() : m_hWnd(0)
|
||||||
|
{
|
||||||
|
HDC hdc = GetDC(0);
|
||||||
|
|
||||||
|
nNumButtons = 0;
|
||||||
|
nNumCardRegions = 0;
|
||||||
|
nNumDropZones = 0;
|
||||||
|
nBackCardIdx = 53;
|
||||||
|
|
||||||
|
ResizeWndCallback = 0;
|
||||||
|
hbmBackImage = 0;
|
||||||
|
hdcBackImage = 0;
|
||||||
|
|
||||||
|
srand((unsigned)GetTickCount());
|
||||||
|
|
||||||
|
//All colours (buttons, highlights, decks)
|
||||||
|
//are calculated off this single base colour
|
||||||
|
crBackgnd = PALETTERGB(0,80,0);//PALETTERGB(0,64,100);
|
||||||
|
|
||||||
|
// If uCardBitmapRef was previously zero, then
|
||||||
|
// load the card bitmaps
|
||||||
|
if(1 == InterlockedIncrement(&uCardBitmapRef))
|
||||||
|
{
|
||||||
|
LoadCardBitmaps();
|
||||||
|
|
||||||
|
__hPalette = CreateCardPalette();
|
||||||
|
|
||||||
|
__hdcPlaceHolder = CreateCompatibleDC(hdc);
|
||||||
|
|
||||||
|
__holdplacepal = UseNicePalette(__hdcPlaceHolder, __hPalette);
|
||||||
|
|
||||||
|
__hbmPlaceHolder = CreateSinkBmp(hdc, __hdcPlaceHolder, crBackgnd, __cardwidth, __cardheight);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseDC(0, hdc);
|
||||||
|
|
||||||
|
//register the window class if necessary
|
||||||
|
if(!fRegistered)
|
||||||
|
{
|
||||||
|
fRegistered = true;
|
||||||
|
RegisterCardWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CardWindow::Create(HWND hwndParent, DWORD dwExStyle, DWORD dwStyle, int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
if(m_hWnd)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
//Create the window associated with this object
|
||||||
|
m_hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, szCardName, 0,
|
||||||
|
WS_CHILD | WS_VISIBLE,
|
||||||
|
0,0,100,100,
|
||||||
|
hwndParent, 0, GetModuleHandle(0), this);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CardWindow::Destroy()
|
||||||
|
{
|
||||||
|
DestroyWindow(m_hWnd);
|
||||||
|
m_hWnd = 0;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CardWindow::~CardWindow()
|
||||||
|
{
|
||||||
|
if(m_hWnd)
|
||||||
|
DestroyWindow(m_hWnd);
|
||||||
|
|
||||||
|
DeleteAll();
|
||||||
|
|
||||||
|
if(0 == InterlockedDecrement(&uCardBitmapRef))
|
||||||
|
{
|
||||||
|
FreeCardBitmaps();
|
||||||
|
|
||||||
|
DeleteObject(__hbmPlaceHolder);
|
||||||
|
DeleteDC (__hdcPlaceHolder);
|
||||||
|
|
||||||
|
RestorePalette(__hdcPlaceHolder, __holdplacepal);
|
||||||
|
|
||||||
|
if(__hPalette)
|
||||||
|
DeleteObject(__hPalette);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CardWindow::DeleteAll()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < nNumCardRegions; i++)
|
||||||
|
{
|
||||||
|
delete Regions[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < nNumButtons; i++)
|
||||||
|
{
|
||||||
|
delete Buttons[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < nNumDropZones; i++)
|
||||||
|
{
|
||||||
|
delete dropzone[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
nNumCardRegions = nNumButtons = nNumDropZones = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardWindow::SetBackColor(COLORREF cr)
|
||||||
|
{
|
||||||
|
crBackgnd = cr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the exact palette we need to render the buttons/stacks
|
||||||
|
//
|
||||||
|
RestorePalette(__hdcPlaceHolder, __holdplacepal);
|
||||||
|
|
||||||
|
if(__hPalette)
|
||||||
|
DeleteObject(__hPalette);
|
||||||
|
|
||||||
|
__hPalette = CreateCardPalette();
|
||||||
|
|
||||||
|
//
|
||||||
|
// re-create the place-holder!
|
||||||
|
HDC hdc = GetDC(m_hWnd);
|
||||||
|
|
||||||
|
DeleteObject(__hbmPlaceHolder);
|
||||||
|
|
||||||
|
__holdplacepal = UseNicePalette(__hdcPlaceHolder, __hPalette);
|
||||||
|
|
||||||
|
__hbmPlaceHolder = CreateSinkBmp(hdc, __hdcPlaceHolder, crBackgnd, __cardwidth, __cardheight);
|
||||||
|
//SelectObject(__hdcPlaceHolder, __hbmPlaceHolder);
|
||||||
|
|
||||||
|
//reset all buttons to same colour
|
||||||
|
for(i = 0; i < nNumButtons; i++)
|
||||||
|
{
|
||||||
|
if(Buttons[i]->GetStyle() & CB_PUSHBUTTON)
|
||||||
|
{
|
||||||
|
Buttons[i]->SetBackColor(ColorScaleRGB(crBackgnd, RGB(255,255,255), 0.1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Buttons[i]->SetBackColor(crBackgnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < nNumCardRegions; i++)
|
||||||
|
{
|
||||||
|
Regions[i]->SetBackColor(crBackgnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ReleaseDC(m_hWnd, hdc);
|
||||||
|
}
|
||||||
|
|
||||||
|
COLORREF CardWindow::GetBackColor()
|
||||||
|
{
|
||||||
|
return crBackgnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
CardButton* CardWindow::CardButtonFromPoint(int x, int y)
|
||||||
|
{
|
||||||
|
CardButton *bptr = 0;
|
||||||
|
|
||||||
|
POINT pt;
|
||||||
|
pt.x = x;
|
||||||
|
pt.y = y;
|
||||||
|
|
||||||
|
//Search BACKWARDS...to reflect the implicit Z-order that
|
||||||
|
//the button creation provided
|
||||||
|
for(int i = nNumButtons - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
bptr = Buttons[i];
|
||||||
|
if(PtInRect(&bptr->rect, pt) && bptr->fVisible)
|
||||||
|
return bptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CardRegion* CardWindow::CardRegionFromPoint(int x, int y)
|
||||||
|
{
|
||||||
|
POINT pt;
|
||||||
|
pt.x = x;
|
||||||
|
pt.y = y;
|
||||||
|
|
||||||
|
//Search BACKWARDS...to reflect the implicit Z-order that
|
||||||
|
//the stack creation provided
|
||||||
|
for(int i = nNumCardRegions - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if(Regions[i]->IsPointInStack(x, y))
|
||||||
|
return Regions[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Forward all window messages onto the appropriate
|
||||||
|
// class instance
|
||||||
|
//
|
||||||
|
LRESULT CALLBACK CardWindow::CardWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
CardWindow *cw = (CardWindow *)GetWindowLong(hwnd, 0);
|
||||||
|
return cw->WndProc(hwnd, iMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardWindow::Paint(HDC hdc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
RECT rect;
|
||||||
|
int xpos = 10;
|
||||||
|
HPALETTE hOldPal;
|
||||||
|
|
||||||
|
hOldPal = UseNicePalette(hdc, __hPalette);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clip the card stacks so that they won't
|
||||||
|
// get painted over
|
||||||
|
//
|
||||||
|
for(i = 0; i < nNumCardRegions; i++)
|
||||||
|
{
|
||||||
|
Regions[i]->Clip(hdc);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clip the buttons
|
||||||
|
//
|
||||||
|
for(i = 0; i < nNumButtons; i++)
|
||||||
|
{
|
||||||
|
Buttons[i]->Clip(hdc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Now paint the whole screen with background colour,
|
||||||
|
//
|
||||||
|
GetClientRect(m_hWnd, &rect);
|
||||||
|
|
||||||
|
//PaintRect(hdc, &rect, MAKE_PALETTERGB(crBackgnd));
|
||||||
|
PaintCardRgn(hdc, 0, 0, rect.right, rect.bottom, 0, 0);
|
||||||
|
SelectClipRgn(hdc, NULL);
|
||||||
|
|
||||||
|
// Don't let cards draw over buttons, so clip buttons again
|
||||||
|
//
|
||||||
|
for(i = 0; i < nNumButtons; i++)
|
||||||
|
{
|
||||||
|
Buttons[i]->Clip(hdc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paint each card stack in turn
|
||||||
|
//
|
||||||
|
for(i = 0; i < nNumCardRegions; i++)
|
||||||
|
{
|
||||||
|
Regions[i]->Render(hdc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paint each button now
|
||||||
|
//
|
||||||
|
SelectClipRgn(hdc, NULL);
|
||||||
|
|
||||||
|
for(i = 0; i < nNumButtons; i++)
|
||||||
|
{
|
||||||
|
Buttons[i]->Redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
RestorePalette(hdc, hOldPal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LRESULT CALLBACK CardWindow::WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
HDC hdc;
|
||||||
|
PAINTSTRUCT ps;
|
||||||
|
|
||||||
|
CREATESTRUCT *cs;
|
||||||
|
|
||||||
|
static CardButton *buttonptr = 0;
|
||||||
|
static CardRegion *stackptr = 0;
|
||||||
|
|
||||||
|
int x, y, i;
|
||||||
|
|
||||||
|
switch(iMsg)
|
||||||
|
{
|
||||||
|
case WM_NCCREATE:
|
||||||
|
|
||||||
|
// When we created this window, we passed in the
|
||||||
|
// pointer to the class object (CardWindow *) in the
|
||||||
|
// call to CreateWindow.
|
||||||
|
cs = (CREATESTRUCT *)lParam;
|
||||||
|
|
||||||
|
//
|
||||||
|
// associate this class with the window
|
||||||
|
//
|
||||||
|
SetWindowLong(hwnd, 0, (LONG)cs->lpCreateParams);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case WM_NCDESTROY:
|
||||||
|
// Don't delete anything here..
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_SIZE:
|
||||||
|
nWidth = LOWORD(lParam);
|
||||||
|
nHeight = HIWORD(lParam);
|
||||||
|
|
||||||
|
//
|
||||||
|
// reposition all the stacks and buttons
|
||||||
|
// in case any of them are centered, right-justified etc
|
||||||
|
//
|
||||||
|
for(i = 0; i < nNumCardRegions; i++)
|
||||||
|
{
|
||||||
|
Regions[i]->AdjustPosition(nWidth, nHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < nNumButtons; i++)
|
||||||
|
{
|
||||||
|
Buttons[i]->AdjustPosition(nWidth, nHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Call the user-defined resize proc AFTER all the stacks
|
||||||
|
// have been positioned
|
||||||
|
//
|
||||||
|
if(ResizeWndCallback)
|
||||||
|
ResizeWndCallback(nWidth, nHeight);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_PAINT:
|
||||||
|
|
||||||
|
hdc = BeginPaint(hwnd, &ps);
|
||||||
|
|
||||||
|
Paint(hdc);
|
||||||
|
|
||||||
|
EndPaint(hwnd, &ps);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_TIMER:
|
||||||
|
|
||||||
|
//find the timer object in the registered funcs
|
||||||
|
/*if(wParam >= 0x10000)
|
||||||
|
{
|
||||||
|
for(i = 0; i < nRegFuncs; i++)
|
||||||
|
{
|
||||||
|
if(RegFuncs[i].id == wParam)
|
||||||
|
{
|
||||||
|
KillTimer(hwnd, wParam);
|
||||||
|
|
||||||
|
//call the registered function!!
|
||||||
|
RegFuncs[i].func(RegFuncs[i].dwParam);
|
||||||
|
|
||||||
|
RegFuncs[i] = RegFuncs[nRegFuncs-1];
|
||||||
|
nRegFuncs--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else*/
|
||||||
|
{
|
||||||
|
//find the cardstack
|
||||||
|
CardRegion *stackobj = (CardRegion *)wParam;//CardStackFromId(wParam);
|
||||||
|
stackobj->DoFlash();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_LBUTTONDBLCLK:
|
||||||
|
|
||||||
|
x = (short)LOWORD(lParam);
|
||||||
|
y = (short)HIWORD(lParam);
|
||||||
|
|
||||||
|
if((buttonptr = CardButtonFromPoint(x, y)) != 0)
|
||||||
|
{
|
||||||
|
buttonptr->OnLButtonDown(hwnd, x, y);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((stackptr = CardRegionFromPoint(x, y)) != 0)
|
||||||
|
{
|
||||||
|
stackptr->OnLButtonDblClk(x, y);
|
||||||
|
stackptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_LBUTTONDOWN:
|
||||||
|
|
||||||
|
x = (short)LOWORD(lParam);
|
||||||
|
y = (short)HIWORD(lParam);
|
||||||
|
|
||||||
|
//if clicked on a button
|
||||||
|
if((buttonptr = CardButtonFromPoint(x, y)) != 0)
|
||||||
|
{
|
||||||
|
if(buttonptr->OnLButtonDown(hwnd, x, y) == 0)
|
||||||
|
buttonptr = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((stackptr = CardRegionFromPoint(x, y)) != 0)
|
||||||
|
{
|
||||||
|
if(!stackptr->OnLButtonDown(x, y))
|
||||||
|
stackptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_LBUTTONUP:
|
||||||
|
|
||||||
|
x = (short)LOWORD(lParam);
|
||||||
|
y = (short)HIWORD(lParam);
|
||||||
|
|
||||||
|
//
|
||||||
|
// if we were clicking a button
|
||||||
|
//
|
||||||
|
if(buttonptr != 0)
|
||||||
|
{
|
||||||
|
buttonptr->OnLButtonUp(hwnd, x, y);
|
||||||
|
buttonptr = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stackptr != 0)
|
||||||
|
{
|
||||||
|
stackptr->OnLButtonUp(x, y);
|
||||||
|
stackptr = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_MOUSEMOVE:
|
||||||
|
|
||||||
|
x = (short)LOWORD(lParam);
|
||||||
|
y = (short)HIWORD(lParam);
|
||||||
|
|
||||||
|
// if we were clicking a button
|
||||||
|
if(buttonptr != 0)
|
||||||
|
{
|
||||||
|
buttonptr->OnMouseMove(hwnd, x, y);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stackptr != 0)
|
||||||
|
{
|
||||||
|
return stackptr->OnMouseMove(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefWindowProc (hwnd, iMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CardRegion* CardWindow::CardRegionFromId(int id)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < nNumCardRegions; i++)
|
||||||
|
{
|
||||||
|
if(Regions[i]->id == id)
|
||||||
|
return Regions[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CardButton* CardWindow::CardButtonFromId(int id)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < nNumButtons; i++)
|
||||||
|
{
|
||||||
|
if(Buttons[i]->id == id)
|
||||||
|
return Buttons[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardWindow::Redraw()
|
||||||
|
{
|
||||||
|
InvalidateRect(m_hWnd, 0, 0);
|
||||||
|
UpdateWindow(m_hWnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CardWindow::DeleteButton(CardButton *pButton)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < nNumButtons; i++)
|
||||||
|
{
|
||||||
|
if(Buttons[i] == pButton)
|
||||||
|
{
|
||||||
|
CardButton *cb = Buttons[i];
|
||||||
|
|
||||||
|
//shift any after this one backwards
|
||||||
|
for(int j = i; j < nNumButtons - 1; j++)
|
||||||
|
{
|
||||||
|
Buttons[j] = Buttons[j + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
delete cb;
|
||||||
|
nNumButtons--;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CardWindow::DeleteRegion(CardRegion *pRegion)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < nNumCardRegions; i++)
|
||||||
|
{
|
||||||
|
if(Regions[i] == pRegion)
|
||||||
|
{
|
||||||
|
CardRegion *cr = Regions[i];
|
||||||
|
|
||||||
|
//shift any after this one backwards
|
||||||
|
for(int j = i; j < nNumCardRegions - 1; j++)
|
||||||
|
{
|
||||||
|
Regions[j] = Regions[j + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
delete cr;
|
||||||
|
nNumCardRegions--;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardWindow::EmptyStacks(void)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < nNumCardRegions; i++)
|
||||||
|
{
|
||||||
|
Regions[i]->Clear();
|
||||||
|
Regions[i]->Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
Redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CardWindow::DistributeStacks(int nIdFrom, int nNumStacks, UINT xJustify, int xSpacing, int nStartX)
|
||||||
|
{
|
||||||
|
int numvisiblestacks = 0;
|
||||||
|
int curx = nStartX;
|
||||||
|
int startindex = -1;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
//find the stack which starts with our ID
|
||||||
|
for(i = 0; i < nNumCardRegions; i++)
|
||||||
|
{
|
||||||
|
if(Regions[i]->Id() == nIdFrom)
|
||||||
|
{
|
||||||
|
startindex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if didn't find, return
|
||||||
|
if(i == nNumCardRegions) return false;
|
||||||
|
|
||||||
|
//count the stacks that are visible
|
||||||
|
for(i = startindex; i < startindex + nNumStacks; i++)
|
||||||
|
{
|
||||||
|
if(Regions[i]->IsVisible())
|
||||||
|
numvisiblestacks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(xJustify == CS_XJUST_CENTER)
|
||||||
|
{
|
||||||
|
//startx -= ((numvisiblestacks + spacing) * cardwidth - spacing) / 2;
|
||||||
|
int viswidth;
|
||||||
|
viswidth = numvisiblestacks * __cardwidth;
|
||||||
|
viswidth += xSpacing * (numvisiblestacks - 1);
|
||||||
|
curx = -(viswidth - __cardwidth) / 2;
|
||||||
|
|
||||||
|
for(i = startindex; i < startindex + nNumStacks; i++)
|
||||||
|
{
|
||||||
|
if(Regions[i]->IsVisible())
|
||||||
|
{
|
||||||
|
Regions[i]->xadjust = curx;
|
||||||
|
Regions[i]->xjustify = CS_XJUST_CENTER;
|
||||||
|
curx += Regions[i]->width + xSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(xJustify == CS_XJUST_RIGHT)
|
||||||
|
{
|
||||||
|
nStartX -= ((numvisiblestacks + xSpacing) * __cardwidth - xSpacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(xJustify == CS_XJUST_NONE)
|
||||||
|
{
|
||||||
|
for(i = startindex; i < startindex + nNumStacks; i++)
|
||||||
|
{
|
||||||
|
if(Regions[i]->IsVisible())
|
||||||
|
{
|
||||||
|
Regions[i]->xpos = curx;
|
||||||
|
curx += Regions[i]->width + xSpacing;
|
||||||
|
Regions[i]->UpdateSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardWindow::Update()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < nNumCardRegions; i++)
|
||||||
|
{
|
||||||
|
Regions[i]->AdjustPosition(nWidth, nHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CardWindow::SetResizeProc(pResizeWndProc proc)
|
||||||
|
{
|
||||||
|
ResizeWndCallback = proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HPALETTE CardWindow::CreateCardPalette()
|
||||||
|
{
|
||||||
|
COLORREF cols[10];
|
||||||
|
int nNumCols;
|
||||||
|
|
||||||
|
|
||||||
|
//include button text colours
|
||||||
|
cols[0] = RGB(0, 0, 0);
|
||||||
|
cols[1] = RGB(255, 255, 255);
|
||||||
|
|
||||||
|
//include the base background colour
|
||||||
|
cols[1] = crBackgnd;
|
||||||
|
|
||||||
|
//include the standard button colours...
|
||||||
|
cols[3] = CardButton::GetHighlight(crBackgnd);
|
||||||
|
cols[4] = CardButton::GetShadow(crBackgnd);
|
||||||
|
cols[5] = CardButton::GetFace(crBackgnd);
|
||||||
|
|
||||||
|
//include the sunken image bitmap colours...
|
||||||
|
GetSinkCols(crBackgnd, &cols[6], &cols[7], &cols[8], &cols[9]);
|
||||||
|
|
||||||
|
nNumCols = 10;
|
||||||
|
|
||||||
|
return MakePaletteFromCols(cols, nNumCols);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardWindow::SetBackCardIdx(UINT uBackIdx)
|
||||||
|
{
|
||||||
|
if(uBackIdx >= 52 && uBackIdx <= 68)
|
||||||
|
nBackCardIdx = uBackIdx;
|
||||||
|
|
||||||
|
for(int i = 0; i < nNumCardRegions; i++)
|
||||||
|
Regions[i]->SetBackCardIdx(uBackIdx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardWindow::PaintCardRgn(HDC hdc, int dx, int dy, int width, int height, int sx, int sy)
|
||||||
|
{
|
||||||
|
RECT rect;
|
||||||
|
|
||||||
|
//if just a solid background colour
|
||||||
|
if(hbmBackImage == 0)
|
||||||
|
{
|
||||||
|
SetRect(&rect, dx, dy, dx+width, dy+height);
|
||||||
|
|
||||||
|
/*if(GetVersion() < 0x80000000)
|
||||||
|
{
|
||||||
|
PaintRect(hdc, &rect, MAKE_PALETTERGB(crBackgnd));
|
||||||
|
}
|
||||||
|
else*/
|
||||||
|
{
|
||||||
|
HBRUSH hbr = CreateSolidBrush(MAKE_PALETTERGB(crBackgnd));
|
||||||
|
FillRect(hdc, &rect, hbr);
|
||||||
|
DeleteObject(hbr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//otherwise, paint using the bitmap
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Draw whatever part of background we can
|
||||||
|
BitBlt(hdc, dx, dy, width, height, hdcBackImage, sx, sy, SRCCOPY);
|
||||||
|
|
||||||
|
// Now we need to paint any area outside the bitmap,
|
||||||
|
// just in case the bitmap is too small to fill whole window
|
||||||
|
if(0)//sx + width > bm.bmWidth || sy + height > bm.bmHeight)
|
||||||
|
{
|
||||||
|
// Find out size of bitmap
|
||||||
|
BITMAP bm;
|
||||||
|
GetObject(hbmBackImage, sizeof(bm), &bm);
|
||||||
|
|
||||||
|
HRGN hr1 = CreateRectRgn(sx, sy, sx+width, sy+height);
|
||||||
|
HRGN hr2 = CreateRectRgn(0, 0, bm.bmWidth, bm.bmHeight);
|
||||||
|
HRGN hr3 = CreateRectRgn(0,0, 1, 1);
|
||||||
|
HRGN hr4 = CreateRectRgn(0,0, 1, 1);
|
||||||
|
|
||||||
|
CombineRgn(hr3, hr1, hr2, RGN_DIFF);
|
||||||
|
|
||||||
|
GetClipRgn(hdc, hr4);
|
||||||
|
|
||||||
|
CombineRgn(hr3, hr4, hr3, RGN_AND);
|
||||||
|
SelectClipRgn(hdc, hr3);
|
||||||
|
|
||||||
|
// Fill remaining space not filled with bitmap
|
||||||
|
HBRUSH hbr = CreateSolidBrush(crBackgnd);
|
||||||
|
FillRgn(hdc, hr3, hbr);
|
||||||
|
DeleteObject(hbr);
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
SelectClipRgn(hdc, hr4);
|
||||||
|
|
||||||
|
DeleteObject(hr1);
|
||||||
|
DeleteObject(hr2);
|
||||||
|
DeleteObject(hr3);
|
||||||
|
DeleteObject(hr4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardWindow::SetBackImage(HBITMAP hBitmap)
|
||||||
|
{
|
||||||
|
//delete current image?? NO!
|
||||||
|
if(hdcBackImage == 0)
|
||||||
|
{
|
||||||
|
hdcBackImage = CreateCompatibleDC(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
hbmBackImage = hBitmap;
|
||||||
|
|
||||||
|
if(hBitmap)
|
||||||
|
SelectObject(hdcBackImage, hBitmap);
|
||||||
|
}
|
119
rosapps/games/solitaire/cardlib/cardwindow.h
Normal file
119
rosapps/games/solitaire/cardlib/cardwindow.h
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
#ifndef CARDBOARD_INCLUDED
|
||||||
|
#define CARDBOARD_INCLUDED
|
||||||
|
|
||||||
|
#define MAXBUTTONS 32
|
||||||
|
#define MAXCARDSTACKS 32
|
||||||
|
#define MAXDROPZONES 8
|
||||||
|
|
||||||
|
#include "dropzone.h"
|
||||||
|
#include "cardlib.h"
|
||||||
|
|
||||||
|
class CardRegion;
|
||||||
|
class CardButton;
|
||||||
|
|
||||||
|
LRESULT CALLBACK CardWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
class CardWindow
|
||||||
|
{
|
||||||
|
friend class CardRegion;
|
||||||
|
friend class CardButton;
|
||||||
|
|
||||||
|
friend void RegisterCardWindow();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CardWindow();
|
||||||
|
~CardWindow();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Basic windowing support
|
||||||
|
//
|
||||||
|
BOOL Create(HWND hwndParent, DWORD dwExStyle, DWORD dwStyle, int x, int y, int width, int height);
|
||||||
|
BOOL Destroy();
|
||||||
|
|
||||||
|
operator HWND() { return m_hWnd; }
|
||||||
|
|
||||||
|
CardButton *CreateButton (int id, TCHAR *szText, UINT uStyle, bool fVisible, int x, int y, int width, int height);
|
||||||
|
CardRegion *CreateRegion (int id, bool fVisible, int x, int y, int xoffset, int yoffset);
|
||||||
|
|
||||||
|
CardButton *CardButtonFromId(int id);
|
||||||
|
CardRegion *CardRegionFromId(int id);
|
||||||
|
|
||||||
|
bool DeleteButton(CardButton *pButton);
|
||||||
|
bool DeleteRegion(CardRegion *pRegion);
|
||||||
|
bool DeleteAll();
|
||||||
|
|
||||||
|
void SetBackColor(COLORREF cr);
|
||||||
|
COLORREF GetBackColor();
|
||||||
|
void SetBackCardIdx(UINT uBackIdx);
|
||||||
|
void SetBackImage(HBITMAP hBitmap);
|
||||||
|
|
||||||
|
void EmptyStacks(void);
|
||||||
|
void Redraw(void);
|
||||||
|
void Update(void);
|
||||||
|
|
||||||
|
bool DistributeStacks(int nIdFrom, int nNumStacks, UINT xJustify, int xSpacing, int nStartX);
|
||||||
|
void SetResizeProc(pResizeWndProc proc);
|
||||||
|
int GetWidth() { return nWidth; }
|
||||||
|
int GetHeight() { return nHeight; }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Dropzone support
|
||||||
|
//
|
||||||
|
bool RegisterDropZone(int id, RECT *rect, pDropZoneProc proc);
|
||||||
|
bool DeleteDropZone(int id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int GetNumDropZones() { return nNumDropZones; }
|
||||||
|
DropZone* GetDropZoneFromRect(RECT *rect);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Window procedure - don't call
|
||||||
|
//
|
||||||
|
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
static LRESULT CALLBACK CardWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Private functions
|
||||||
|
//
|
||||||
|
void Paint(HDC hdc);
|
||||||
|
void PaintCardRgn(HDC hdc, int dx, int dy, int width, int height, int sx, int sy);
|
||||||
|
|
||||||
|
HPALETTE CreateCardPalette();
|
||||||
|
|
||||||
|
CardButton *CardButtonFromPoint(int x, int y);
|
||||||
|
CardRegion *CardRegionFromPoint(int x, int y);
|
||||||
|
CardRegion *GetBestStack(int x, int y, int w, int h);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Private members
|
||||||
|
//
|
||||||
|
|
||||||
|
HWND m_hWnd; //window handle!
|
||||||
|
int nWidth, nHeight;
|
||||||
|
|
||||||
|
UINT nBackCardIdx; //all stacks share this card index by default
|
||||||
|
|
||||||
|
HBITMAP hbmBackImage;
|
||||||
|
HDC hdcBackImage;
|
||||||
|
|
||||||
|
|
||||||
|
CardButton * Buttons[MAXBUTTONS];
|
||||||
|
int nNumButtons;
|
||||||
|
|
||||||
|
CardRegion * Regions[MAXCARDSTACKS];
|
||||||
|
int nNumCardRegions;
|
||||||
|
|
||||||
|
DropZone * dropzone[MAXDROPZONES];
|
||||||
|
int nNumDropZones;
|
||||||
|
|
||||||
|
COLORREF crBackgnd;
|
||||||
|
|
||||||
|
pResizeWndProc ResizeWndCallback;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
69
rosapps/games/solitaire/cardlib/dropzone.cpp
Normal file
69
rosapps/games/solitaire/cardlib/dropzone.cpp
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
//
|
||||||
|
// CardLib - DropZone class
|
||||||
|
//
|
||||||
|
// Freeware
|
||||||
|
// Copyright J Brown 2001
|
||||||
|
//
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "cardlib.h"
|
||||||
|
#include "cardwindow.h"
|
||||||
|
#include "dropzone.h"
|
||||||
|
|
||||||
|
bool CardWindow::RegisterDropZone(int id, RECT *rect, pDropZoneProc proc)
|
||||||
|
{
|
||||||
|
if(nNumDropZones == MAXDROPZONES)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DropZone *dz = new DropZone(id, rect, proc);
|
||||||
|
|
||||||
|
dropzone[nNumDropZones++] = dz;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DropZone *CardWindow::GetDropZoneFromRect(RECT *rect)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < nNumDropZones; i++)
|
||||||
|
{
|
||||||
|
RECT inter;
|
||||||
|
RECT zone;
|
||||||
|
|
||||||
|
//if any part of the drag rectangle falls within a drop zone,
|
||||||
|
//let that take priority over any other card stack.
|
||||||
|
dropzone[i]->GetZone(&zone);
|
||||||
|
|
||||||
|
if(IntersectRect(&inter, rect, &zone))
|
||||||
|
{
|
||||||
|
//see if the callback wants us to drop a card on
|
||||||
|
//a particular stack
|
||||||
|
return dropzone[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CardWindow::DeleteDropZone(int id)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < nNumDropZones; i++)
|
||||||
|
{
|
||||||
|
if(dropzone[i]->id == id)
|
||||||
|
{
|
||||||
|
DropZone *dz = dropzone[i];
|
||||||
|
|
||||||
|
//shift any after this one backwards
|
||||||
|
for(int j = i; j < nNumDropZones - 1; j++)
|
||||||
|
{
|
||||||
|
dropzone[j] = dropzone[j + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
delete dz;
|
||||||
|
nNumDropZones--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
39
rosapps/games/solitaire/cardlib/dropzone.h
Normal file
39
rosapps/games/solitaire/cardlib/dropzone.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef DROPZONE_INCLUDED
|
||||||
|
#define DROPZONE_INCLUDED
|
||||||
|
|
||||||
|
//
|
||||||
|
// define a drop-zone, which can be used to over-ride
|
||||||
|
// drop-behaviour for any card stacks which fall under it
|
||||||
|
//
|
||||||
|
|
||||||
|
class CardStack;
|
||||||
|
|
||||||
|
class DropZone
|
||||||
|
{
|
||||||
|
friend class CardWindow;
|
||||||
|
|
||||||
|
DropZone(int Id, RECT *rect, pDropZoneProc proc) :
|
||||||
|
id(Id), DropZoneCallback(proc) { CopyRect(&zone, rect); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void SetZone(RECT *rect) { CopyRect(&zone, rect); }
|
||||||
|
void GetZone(RECT *rect) { CopyRect(rect, &zone); }
|
||||||
|
void SetCallback(pDropZoneProc callback) { DropZoneCallback = callback; }
|
||||||
|
|
||||||
|
int DropCards(CardStack &cardstack)
|
||||||
|
{
|
||||||
|
if(DropZoneCallback)
|
||||||
|
return DropZoneCallback(id, cardstack);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int id;
|
||||||
|
RECT zone;
|
||||||
|
pDropZoneProc DropZoneCallback;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
15
rosapps/games/solitaire/cardlib/globals.h
Normal file
15
rosapps/games/solitaire/cardlib/globals.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef GLOBALS_INCLUDED
|
||||||
|
#define GLOBALS_INCLUDED
|
||||||
|
|
||||||
|
extern int __cardwidth;
|
||||||
|
extern int __cardheight;
|
||||||
|
|
||||||
|
extern HDC __hdcCardBitmaps;
|
||||||
|
extern HBITMAP __hbmCardBitmaps;
|
||||||
|
|
||||||
|
extern HDC __hdcPlaceHolder;
|
||||||
|
extern HBITMAP __hbmPlaceHolder;
|
||||||
|
|
||||||
|
extern HPALETTE __hPalette;
|
||||||
|
|
||||||
|
#endif
|
BIN
rosapps/games/solitaire/icon1.ico
Normal file
BIN
rosapps/games/solitaire/icon1.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
42
rosapps/games/solitaire/makefile
Normal file
42
rosapps/games/solitaire/makefile
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
PATH_TO_TOP = ../../../reactos
|
||||||
|
|
||||||
|
TARGET_TYPE = program
|
||||||
|
|
||||||
|
TARGET_APPTYPE = windows
|
||||||
|
|
||||||
|
TARGET_INSTALLDIR = system32
|
||||||
|
|
||||||
|
TARGET_NAME = sol
|
||||||
|
|
||||||
|
TARGET_SDKLIBS = kernel32.a user32.a gdi32.a cards.a comctl32.a
|
||||||
|
|
||||||
|
TARGET_GCCLIBS = stdc++
|
||||||
|
|
||||||
|
TARGET_OBJECTS = $(SOL_OBJECTS) $(CARDLIB_OBJECTS)
|
||||||
|
|
||||||
|
SOL_OBJECTS = \
|
||||||
|
solcreate.o \
|
||||||
|
solgame.o \
|
||||||
|
solitaire.o
|
||||||
|
|
||||||
|
CARDLIB_OBJECTS = \
|
||||||
|
cardlib/cardbitmaps.o \
|
||||||
|
cardlib/cardbutton.o \
|
||||||
|
cardlib/cardcolor.o \
|
||||||
|
cardlib/cardcount.o \
|
||||||
|
cardlib/cardlib.o \
|
||||||
|
cardlib/cardregion.o \
|
||||||
|
cardlib/cardrgndraw.o \
|
||||||
|
cardlib/cardrgnmouse.o \
|
||||||
|
cardlib/cardstack.o \
|
||||||
|
cardlib/cardwindow.o \
|
||||||
|
cardlib/dropzone.o
|
||||||
|
|
||||||
|
TARGET_CPPFLAGS = -Icardlib -Wall -D__USE_W32API -D_WIN32_IE=0x0501 -D_WIN32_WINNT=0x0501 -D__REACTOS__
|
||||||
|
|
||||||
|
include $(PATH_TO_TOP)/rules.mak
|
||||||
|
|
||||||
|
include $(TOOLS_PATH)/helper.mk
|
||||||
|
|
||||||
|
# EOF
|
25
rosapps/games/solitaire/resource.h
Normal file
25
rosapps/games/solitaire/resource.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
//{{NO_DEPENDENCIES}}
|
||||||
|
// Microsoft Developer Studio generated include file.
|
||||||
|
// Used by Solitaire.rc
|
||||||
|
//
|
||||||
|
#define IDD_DIALOG1 101
|
||||||
|
#define IDR_MENU1 102
|
||||||
|
#define IDR_ACCELERATOR1 103
|
||||||
|
#define IDI_ICON1 104
|
||||||
|
#define IDM_GAME_NEW 40001
|
||||||
|
#define IDM_GAME_DECK 40002
|
||||||
|
#define IDM_GAME_OPTIONS 40003
|
||||||
|
#define IDM_GAME_EXIT 40004
|
||||||
|
#define IDM_HELP_CONTENTS 40005
|
||||||
|
#define IDM_HELP_ABOUT 40006
|
||||||
|
|
||||||
|
// Next default values for new objects
|
||||||
|
//
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
#define _APS_NEXT_RESOURCE_VALUE 105
|
||||||
|
#define _APS_NEXT_COMMAND_VALUE 40007
|
||||||
|
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||||
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
|
#endif
|
||||||
|
#endif
|
144
rosapps/games/solitaire/sol.rc
Normal file
144
rosapps/games/solitaire/sol.rc
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
//Microsoft Developer Studio generated resource script.
|
||||||
|
//
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
|
#define APSTUDIO_READONLY_SYMBOLS
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Generated from the TEXTINCLUDE 2 resource.
|
||||||
|
//
|
||||||
|
/* winemaker: #include "afxres.h" */
|
||||||
|
/* winemaker:warning: 'afxres.h' is an MFC specific header. Replacing it with 'winres.h' */
|
||||||
|
#include "winres.h"
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// English (U.K.) resources
|
||||||
|
|
||||||
|
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
|
||||||
|
#ifdef _WIN32
|
||||||
|
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
|
||||||
|
#pragma code_page(1252)
|
||||||
|
#endif //_WIN32
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Dialog
|
||||||
|
//
|
||||||
|
|
||||||
|
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95
|
||||||
|
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
|
CAPTION "Dialog"
|
||||||
|
FONT 8, "MS Sans Serif"
|
||||||
|
BEGIN
|
||||||
|
DEFPUSHBUTTON "OK",IDOK,129,7,50,14
|
||||||
|
PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14
|
||||||
|
END
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// DESIGNINFO
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
GUIDELINES DESIGNINFO DISCARDABLE
|
||||||
|
BEGIN
|
||||||
|
IDD_DIALOG1, DIALOG
|
||||||
|
BEGIN
|
||||||
|
LEFTMARGIN, 7
|
||||||
|
RIGHTMARGIN, 179
|
||||||
|
TOPMARGIN, 7
|
||||||
|
BOTTOMMARGIN, 88
|
||||||
|
END
|
||||||
|
END
|
||||||
|
#endif // APSTUDIO_INVOKED
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// TEXTINCLUDE
|
||||||
|
//
|
||||||
|
|
||||||
|
1 TEXTINCLUDE DISCARDABLE
|
||||||
|
BEGIN
|
||||||
|
"resource.h\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
2 TEXTINCLUDE DISCARDABLE
|
||||||
|
BEGIN
|
||||||
|
"#include ""winres.h""\r\n"
|
||||||
|
"\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
3 TEXTINCLUDE DISCARDABLE
|
||||||
|
BEGIN
|
||||||
|
"\r\n"
|
||||||
|
"\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
#endif // APSTUDIO_INVOKED
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Menu
|
||||||
|
//
|
||||||
|
|
||||||
|
IDR_MENU1 MENU DISCARDABLE
|
||||||
|
BEGIN
|
||||||
|
POPUP "&Game"
|
||||||
|
BEGIN
|
||||||
|
MENUITEM "&Deal\tF2", IDM_GAME_NEW
|
||||||
|
MENUITEM SEPARATOR
|
||||||
|
MENUITEM "De&ck...", IDM_GAME_DECK
|
||||||
|
MENUITEM "&Options...", IDM_GAME_OPTIONS
|
||||||
|
MENUITEM SEPARATOR
|
||||||
|
MENUITEM "&Exit", IDM_GAME_EXIT
|
||||||
|
END
|
||||||
|
POPUP "&Help"
|
||||||
|
BEGIN
|
||||||
|
MENUITEM "&Contents\tF1", IDM_HELP_CONTENTS
|
||||||
|
MENUITEM "&About", IDM_HELP_ABOUT
|
||||||
|
END
|
||||||
|
END
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Accelerator
|
||||||
|
//
|
||||||
|
|
||||||
|
IDR_ACCELERATOR1 ACCELERATORS DISCARDABLE
|
||||||
|
BEGIN
|
||||||
|
VK_F1, IDM_HELP_CONTENTS, VIRTKEY, NOINVERT
|
||||||
|
VK_F2, IDM_GAME_NEW, VIRTKEY, NOINVERT
|
||||||
|
END
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Icon
|
||||||
|
//
|
||||||
|
|
||||||
|
// Icon with lowest ID value placed first to ensure application icon
|
||||||
|
// remains consistent on all systems.
|
||||||
|
IDI_ICON1 ICON DISCARDABLE "icon1.ico"
|
||||||
|
#endif // English (U.K.) resources
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef APSTUDIO_INVOKED
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Generated from the TEXTINCLUDE 3 resource.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // not APSTUDIO_INVOKED
|
||||||
|
|
87
rosapps/games/solitaire/solcreate.cpp
Normal file
87
rosapps/games/solitaire/solcreate.cpp
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
#include <windows.h>
|
||||||
|
#include <commctrl.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include "resource.h"
|
||||||
|
#include "cardlib/cardlib.h"
|
||||||
|
|
||||||
|
#include "solitaire.h"
|
||||||
|
|
||||||
|
const int yBorder = 20;
|
||||||
|
const int xBorder = 20;
|
||||||
|
const int yRowStacks = yBorder + 128;
|
||||||
|
|
||||||
|
CardRegion *pDeck;
|
||||||
|
CardRegion *pPile;
|
||||||
|
CardRegion *pSuitStack[4];
|
||||||
|
CardRegion *pRowStack[NUM_ROW_STACKS];
|
||||||
|
|
||||||
|
extern CardStack activepile;
|
||||||
|
|
||||||
|
HBITMAP hbmBitmap;
|
||||||
|
HDC hdcBitmap;
|
||||||
|
|
||||||
|
void CreateSol()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// hbmBitmap = (HBITMAP)LoadImage(0,"test.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
|
||||||
|
// SolWnd.SetBackImage(hbmBitmap);
|
||||||
|
|
||||||
|
activepile.Clear();
|
||||||
|
|
||||||
|
|
||||||
|
pDeck = SolWnd.CreateRegion(DECK_ID, true, xBorder, yBorder, 2, 1);
|
||||||
|
pDeck->SetEmptyImage(CS_EI_SUNK);
|
||||||
|
pDeck->SetThreedCount(6);
|
||||||
|
pDeck->SetDragRule(CS_DRAG_NONE, 0);
|
||||||
|
pDeck->SetDropRule(CS_DROP_NONE, 0);
|
||||||
|
pDeck->SetClickProc(DeckClickProc);
|
||||||
|
pDeck->SetDblClickProc(DeckClickProc);
|
||||||
|
pDeck->SetFaceDirection(CS_FACE_DOWN, 0);
|
||||||
|
|
||||||
|
pPile = SolWnd.CreateRegion(PILE_ID, true, 110, yBorder, CS_DEFXOFF, 1);
|
||||||
|
pPile->SetEmptyImage(CS_EI_NONE);
|
||||||
|
pPile->SetDragRule(CS_DRAG_TOP, 0);
|
||||||
|
pPile->SetDropRule(CS_DROP_NONE, 0);
|
||||||
|
pPile->SetDblClickProc(PileDblClickProc);
|
||||||
|
pPile->SetRemoveCardProc(PileRemoveProc);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the suit stacks
|
||||||
|
//
|
||||||
|
for(i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
pSuitStack[i] = SolWnd.CreateRegion(SUIT_ID+i, true, 0, yBorder, 0, 0);
|
||||||
|
pSuitStack[i]->SetEmptyImage(CS_EI_SUNK);
|
||||||
|
//pSuitStack[i]->SetPlacement(CS_XJUST_RIGHT, 0, -i * (__cardwidth + 4) - xBorder, 0);
|
||||||
|
pSuitStack[i]->SetPlacement(CS_XJUST_CENTER, 0, i * (__cardwidth + 10) , 0);
|
||||||
|
|
||||||
|
pSuitStack[i]->SetDropRule(CS_DROP_CALLBACK, SuitStackDropProc);
|
||||||
|
pSuitStack[i]->SetDragRule(CS_DRAG_TOP);
|
||||||
|
|
||||||
|
pSuitStack[i]->SetAddCardProc(SuitStackAddProc);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the row stacks
|
||||||
|
//
|
||||||
|
for(i = 0; i < NUM_ROW_STACKS; i++)
|
||||||
|
{
|
||||||
|
pRowStack[i] = SolWnd.CreateRegion(ROW_ID+i, true, 0, yRowStacks, 0, 14);
|
||||||
|
pRowStack[i]->SetEmptyImage(CS_EI_SUNK);
|
||||||
|
pRowStack[i]->SetFaceDirection(CS_FACE_DOWNUP, i);
|
||||||
|
|
||||||
|
pRowStack[i]->SetPlacement(CS_XJUST_CENTER, 0,
|
||||||
|
(i - NUM_ROW_STACKS/2) * (__cardwidth + 10), 0);
|
||||||
|
|
||||||
|
pRowStack[i]->SetEmptyImage(CS_EI_NONE);
|
||||||
|
|
||||||
|
pRowStack[i]->SetDragRule(CS_DRAG_CALLBACK, RowStackDragProc);
|
||||||
|
pRowStack[i]->SetDropRule(CS_DROP_CALLBACK, RowStackDropProc);
|
||||||
|
pRowStack[i]->SetClickProc(RowStackClickProc);
|
||||||
|
pRowStack[i]->SetDblClickProc(RowStackDblClickProc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
308
rosapps/games/solitaire/solgame.cpp
Normal file
308
rosapps/games/solitaire/solgame.cpp
Normal file
|
@ -0,0 +1,308 @@
|
||||||
|
#include <windows.h>
|
||||||
|
#include <commctrl.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include "resource.h"
|
||||||
|
#include "cardlib/cardlib.h"
|
||||||
|
//#include "../catch22lib/trace.h"
|
||||||
|
#include "solitaire.h"
|
||||||
|
|
||||||
|
CardStack activepile;
|
||||||
|
bool fGameStarted = false;
|
||||||
|
|
||||||
|
void NewGame(void)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
SolWnd.EmptyStacks();
|
||||||
|
|
||||||
|
//create a new card-stack
|
||||||
|
CardStack deck;
|
||||||
|
deck.NewDeck();
|
||||||
|
deck.Shuffle();
|
||||||
|
activepile.Clear();
|
||||||
|
|
||||||
|
//deal to each row stack..
|
||||||
|
for(i = 0; i < NUM_ROW_STACKS; i++)
|
||||||
|
{
|
||||||
|
CardStack temp;
|
||||||
|
temp.Clear();
|
||||||
|
|
||||||
|
pRowStack[i]->SetFaceDirection(CS_FACE_DOWNUP, i);
|
||||||
|
|
||||||
|
for(j = 0; j <= i; j++)
|
||||||
|
{
|
||||||
|
temp.Push(deck.Pop());
|
||||||
|
}
|
||||||
|
|
||||||
|
pRowStack[i]->SetCardStack(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
//put the other cards onto the deck
|
||||||
|
pDeck->SetCardStack(deck);
|
||||||
|
pDeck->Update();
|
||||||
|
|
||||||
|
SolWnd.Redraw();
|
||||||
|
|
||||||
|
fGameStarted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Now follow the stack callback functions. This is where we
|
||||||
|
// provide the game functionality and rules
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Can only drag face-up cards
|
||||||
|
//
|
||||||
|
bool CARDLIBPROC RowStackDragProc(CardRegion &stackobj, int iNumDragCards)
|
||||||
|
{
|
||||||
|
int numfacedown;
|
||||||
|
int numcards;
|
||||||
|
|
||||||
|
stackobj.GetFaceDirection(&numfacedown);
|
||||||
|
|
||||||
|
numcards = stackobj.NumCards();
|
||||||
|
|
||||||
|
if(iNumDragCards <= numcards-numfacedown)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Row a row-stack, we can only drop cards
|
||||||
|
// that are lower / different colour
|
||||||
|
//
|
||||||
|
bool CARDLIBPROC RowStackDropProc(CardRegion &stackobj, const CardStack &dragcards)
|
||||||
|
{
|
||||||
|
Card dragcard = dragcards[dragcards.NumCards() - 1];
|
||||||
|
|
||||||
|
//if we are empty, can only drop a stack with a King at bottom
|
||||||
|
if(stackobj.NumCards() == 0)
|
||||||
|
{
|
||||||
|
if(dragcard.LoVal() != 13)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const CardStack &mystack = stackobj.GetCardStack();
|
||||||
|
|
||||||
|
//can only drop if card is 1 less
|
||||||
|
if(mystack[0].LoVal() != dragcard.LoVal() + 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//can only drop if card is different colour
|
||||||
|
if( mystack[0].IsBlack() && !dragcard.IsRed() ||
|
||||||
|
!mystack[0].IsBlack() && dragcard.IsRed() )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Can only drop a card onto a suit-stack if the
|
||||||
|
// card is 1 higher, and is the same suit
|
||||||
|
//
|
||||||
|
bool CanDrop(CardRegion &stackobj, Card card)
|
||||||
|
{
|
||||||
|
int topval;
|
||||||
|
|
||||||
|
const CardStack &cardstack = stackobj.GetCardStack();
|
||||||
|
|
||||||
|
if(cardstack.NumCards() > 0)
|
||||||
|
{
|
||||||
|
if(card.Suit() != cardstack[0].Suit())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
topval = cardstack[0].LoVal();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
topval = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//make sure 1 higher
|
||||||
|
if(card.LoVal() != (topval + 1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Can only drop a card onto suit stack if it is same suit, and 1 higher
|
||||||
|
//
|
||||||
|
bool CARDLIBPROC SuitStackDropProc(CardRegion &stackobj, const CardStack &dragcards)
|
||||||
|
{
|
||||||
|
int topval = 0;
|
||||||
|
|
||||||
|
//only drop 1 card at a time
|
||||||
|
if(dragcards.NumCards() != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return CanDrop(stackobj, dragcards[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Single-click on one of the row-stacks
|
||||||
|
// Turn the top-card over if they are all face-down
|
||||||
|
//
|
||||||
|
void CARDLIBPROC RowStackClickProc(CardRegion &stackobj, int iNumClicked)
|
||||||
|
{
|
||||||
|
int numfacedown;
|
||||||
|
|
||||||
|
stackobj.GetFaceDirection(&numfacedown);
|
||||||
|
|
||||||
|
//if all face-down, then make top card face-up
|
||||||
|
if(stackobj.NumCards() == numfacedown)
|
||||||
|
{
|
||||||
|
if(numfacedown > 0) numfacedown--;
|
||||||
|
stackobj.SetFaceDirection(CS_FACE_DOWNUP, numfacedown);
|
||||||
|
stackobj.Redraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find the suit-stack that can accept the specified card
|
||||||
|
//
|
||||||
|
CardRegion *FindSuitStackFromCard(Card card)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if(CanDrop(*pSuitStack[i], card))
|
||||||
|
return pSuitStack[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// What happens when we add a card to one of the suit stacks?
|
||||||
|
// Well, nothing (it is already added), but we need to
|
||||||
|
// check all four stacks (not just this one) to see if
|
||||||
|
// the game has finished.
|
||||||
|
//
|
||||||
|
void CARDLIBPROC SuitStackAddProc(CardRegion &stackobj, const CardStack &added)
|
||||||
|
{
|
||||||
|
bool fGameOver = true;
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if(pSuitStack[i]->NumCards() != 13)
|
||||||
|
{
|
||||||
|
fGameOver = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fGameOver)
|
||||||
|
{
|
||||||
|
MessageBox(SolWnd, _T("Congratulations, you win!!"), szAppName, MB_OK | MB_ICONINFORMATION);
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
pSuitStack[i]->Flash(11, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Double-click on one of the row stacks
|
||||||
|
// The aim is to find a suit-stack to move the
|
||||||
|
// double-clicked card to.
|
||||||
|
//
|
||||||
|
void CARDLIBPROC RowStackDblClickProc(CardRegion &stackobj, int iNumClicked)
|
||||||
|
{
|
||||||
|
//can only move 1 card at a time
|
||||||
|
if(iNumClicked != 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//find a suit-stack to move the card to...
|
||||||
|
const CardStack &cardstack = stackobj.GetCardStack();
|
||||||
|
CardRegion *pDest = FindSuitStackFromCard(cardstack[0]);
|
||||||
|
|
||||||
|
if(pDest != 0)
|
||||||
|
{
|
||||||
|
//stackobj.MoveCards(pDest, 1, true);
|
||||||
|
//use the SimulateDrag funcion, because we get the
|
||||||
|
//AddProc callbacks called for us on the destination stacks...
|
||||||
|
stackobj.SimulateDrag(pDest, 1, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Face-up pile double-click
|
||||||
|
//
|
||||||
|
void CARDLIBPROC PileDblClickProc(CardRegion &stackobj, int iNumClicked)
|
||||||
|
{
|
||||||
|
RowStackDblClickProc(stackobj, iNumClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// What happens when a card is removed from face-up pile?
|
||||||
|
//
|
||||||
|
void CARDLIBPROC PileRemoveProc(CardRegion &stackobj, int iItems)
|
||||||
|
{
|
||||||
|
//modify our "virtual" pile by removing the same card
|
||||||
|
//that was removed from the physical card stack
|
||||||
|
activepile.Pop(iItems);
|
||||||
|
|
||||||
|
//if there is just 1 card left, then modify the
|
||||||
|
//stack to contain ALL the face-up cards..the effect
|
||||||
|
//will be, the next time a card is dragged, all the
|
||||||
|
//previous card-triplets will be available underneath
|
||||||
|
if(stackobj.NumCards() == 1)
|
||||||
|
{
|
||||||
|
stackobj.SetOffsets(0,0);
|
||||||
|
stackobj.SetCardStack(activepile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Double-click on the deck
|
||||||
|
// Move 3 cards to the face-up pile
|
||||||
|
//
|
||||||
|
void CARDLIBPROC DeckClickProc(CardRegion &stackobj, int iNumClicked)
|
||||||
|
{
|
||||||
|
CardStack cardstack = stackobj.GetCardStack();
|
||||||
|
CardStack pile = pPile->GetCardStack();
|
||||||
|
|
||||||
|
fGameStarted = true;
|
||||||
|
|
||||||
|
//reset the face-up pile to represent 3 cards
|
||||||
|
pPile->SetOffsets(CS_DEFXOFF, 1);
|
||||||
|
|
||||||
|
if(cardstack.NumCards() == 0)
|
||||||
|
{
|
||||||
|
pile.Clear();
|
||||||
|
|
||||||
|
activepile.Reverse();
|
||||||
|
cardstack.Push(activepile);
|
||||||
|
activepile.Clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int numcards = min(3, cardstack.NumCards());
|
||||||
|
|
||||||
|
//make a "visible" copy of these cards
|
||||||
|
CardStack temp;
|
||||||
|
temp = cardstack.Pop(numcards);
|
||||||
|
temp.Reverse();
|
||||||
|
|
||||||
|
pile.Clear();
|
||||||
|
pile.Push(temp);
|
||||||
|
|
||||||
|
//remove the top 3 from deck
|
||||||
|
activepile.Push(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
activepile.Print();
|
||||||
|
|
||||||
|
pDeck->SetCardStack(cardstack);
|
||||||
|
pPile->SetCardStack(pile);
|
||||||
|
|
||||||
|
SolWnd.Redraw();
|
||||||
|
}
|
217
rosapps/games/solitaire/solitaire.cpp
Normal file
217
rosapps/games/solitaire/solitaire.cpp
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
#include <windows.h>
|
||||||
|
#include <commctrl.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include "resource.h"
|
||||||
|
#include "cardlib/cardlib.h"
|
||||||
|
|
||||||
|
#include "solitaire.h"
|
||||||
|
|
||||||
|
TCHAR szHelpPath[MAX_PATH];
|
||||||
|
|
||||||
|
DWORD dwAppStartTime;
|
||||||
|
HWND hwndMain;
|
||||||
|
HWND hwndStatus;
|
||||||
|
HINSTANCE hInstance;
|
||||||
|
|
||||||
|
TCHAR szAppName[] = _T("Solitaire");
|
||||||
|
|
||||||
|
CardWindow SolWnd;
|
||||||
|
|
||||||
|
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
void MakePath(TCHAR *szDest, UINT nDestLen, TCHAR *szExt)
|
||||||
|
{
|
||||||
|
TCHAR *ptr;
|
||||||
|
|
||||||
|
ptr = szDest + GetModuleFileName(GetModuleHandle(0), szDest, nDestLen) - 1;
|
||||||
|
while(*ptr-- != '.');
|
||||||
|
lstrcpy(ptr + 1, szExt);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Main entry point
|
||||||
|
//
|
||||||
|
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrev, PSTR szCmdLine, int iCmdShow)
|
||||||
|
{
|
||||||
|
HWND hwnd;
|
||||||
|
MSG msg;
|
||||||
|
WNDCLASSEX wndclass;
|
||||||
|
INITCOMMONCONTROLSEX ice;
|
||||||
|
HACCEL hAccelTable;
|
||||||
|
|
||||||
|
hInstance = hInst;
|
||||||
|
|
||||||
|
//Window class for the main application parent window
|
||||||
|
wndclass.cbSize = sizeof(wndclass);
|
||||||
|
wndclass.style = 0;//CS_HREDRAW | CS_VREDRAW;
|
||||||
|
wndclass.lpfnWndProc = WndProc;
|
||||||
|
wndclass.cbClsExtra = 0;
|
||||||
|
wndclass.cbWndExtra = 0;
|
||||||
|
wndclass.hInstance = hInst;
|
||||||
|
wndclass.hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IDI_ICON1));
|
||||||
|
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
|
||||||
|
wndclass.hbrBackground = (HBRUSH)NULL;
|
||||||
|
wndclass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
|
||||||
|
wndclass.lpszClassName = szAppName;
|
||||||
|
wndclass.hIconSm = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, 0);
|
||||||
|
|
||||||
|
RegisterClassEx(&wndclass);
|
||||||
|
|
||||||
|
ice.dwSize = sizeof(ice);
|
||||||
|
ice.dwICC = ICC_BAR_CLASSES;
|
||||||
|
InitCommonControlsEx(&ice);
|
||||||
|
|
||||||
|
srand((unsigned)GetTickCount());//timeGetTime());
|
||||||
|
|
||||||
|
// InitCardLib();
|
||||||
|
|
||||||
|
// LoadSettings();
|
||||||
|
|
||||||
|
//Construct the path to our help file
|
||||||
|
MakePath(szHelpPath, MAX_PATH, _T(".hlp"));
|
||||||
|
|
||||||
|
hwnd = CreateWindow(szAppName, // window class name
|
||||||
|
szAppName, // window caption
|
||||||
|
WS_OVERLAPPEDWINDOW
|
||||||
|
,//|WS_CLIPCHILDREN, // window style
|
||||||
|
CW_USEDEFAULT, // initial x position
|
||||||
|
CW_USEDEFAULT, // initial y position
|
||||||
|
CW_USEDEFAULT, // initial x size
|
||||||
|
CW_USEDEFAULT, // initial y size
|
||||||
|
NULL, // parent window handle
|
||||||
|
NULL, // use window class menu
|
||||||
|
hInst, // program instance handle
|
||||||
|
NULL); // creation parameters
|
||||||
|
|
||||||
|
hwndMain = hwnd;
|
||||||
|
|
||||||
|
ShowWindow(hwnd, iCmdShow);
|
||||||
|
UpdateWindow(hwnd);
|
||||||
|
|
||||||
|
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));
|
||||||
|
|
||||||
|
while(GetMessage(&msg, NULL,0,0))
|
||||||
|
{
|
||||||
|
if(!TranslateAccelerator(hwnd, hAccelTable, &msg))
|
||||||
|
{
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveSettings();
|
||||||
|
|
||||||
|
return msg.wParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
static int nWidth, nHeight;
|
||||||
|
int nStatusHeight = 0;//20;
|
||||||
|
int parts[] = { 100, -1 };
|
||||||
|
UINT ret;
|
||||||
|
|
||||||
|
MINMAXINFO *mmi;
|
||||||
|
|
||||||
|
switch(iMsg)
|
||||||
|
{
|
||||||
|
case WM_CREATE:
|
||||||
|
hwndStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP, "Ready", hwnd, 0);
|
||||||
|
|
||||||
|
//SendMessage(hwndStatus, SB_SIMPLE, (WPARAM)TRUE, 0);
|
||||||
|
|
||||||
|
SendMessage(hwndStatus, SB_SETPARTS, 2, (LPARAM)parts);
|
||||||
|
SendMessage(hwndStatus, SB_SETTEXT, 0 | SBT_NOBORDERS, (LPARAM)"");
|
||||||
|
|
||||||
|
ShowWindow(hwndStatus, SW_HIDE);
|
||||||
|
|
||||||
|
SolWnd.Create(hwnd, WS_EX_CLIENTEDGE, WS_CHILD|WS_VISIBLE, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
CreateSol();
|
||||||
|
|
||||||
|
NewGame();
|
||||||
|
|
||||||
|
dwAppStartTime = GetTickCount();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_DESTROY:
|
||||||
|
PostQuitMessage(0);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_SIZE:
|
||||||
|
nWidth = LOWORD(lParam);
|
||||||
|
nHeight = HIWORD(lParam);
|
||||||
|
|
||||||
|
MoveWindow(SolWnd, 0, 0, nWidth, nHeight-nStatusHeight, TRUE);
|
||||||
|
//MoveWindow(hwndStatus, 0, nHeight-nStatusHeight, nWidth, nHeight, TRUE);
|
||||||
|
//parts[0] = nWidth - 256;
|
||||||
|
//SendMessage(hwndStatus, SB_SETPARTS, 2, (LPARAM)parts);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_GETMINMAXINFO:
|
||||||
|
mmi = (MINMAXINFO *)lParam;
|
||||||
|
mmi->ptMinTrackSize.x = 600;
|
||||||
|
mmi->ptMinTrackSize.y = 400;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_COMMAND:
|
||||||
|
|
||||||
|
switch(LOWORD(wParam))
|
||||||
|
{
|
||||||
|
case IDM_GAME_NEW:
|
||||||
|
//simulate a button click on the new button..
|
||||||
|
NewGame();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case IDM_GAME_DECK:
|
||||||
|
//ShowDeckOptionsDlg(hwnd);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case IDM_GAME_OPTIONS:
|
||||||
|
//ShowGameOptionsDlg(hwnd);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case IDM_HELP_CONTENTS:
|
||||||
|
|
||||||
|
WinHelp(hwnd, szHelpPath, HELP_CONTENTS, 0);//HELP_KEY, (DWORD)"How to play");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case IDM_HELP_ABOUT:
|
||||||
|
MessageBox(hwnd, _T("Solitare by J Brown\r\n\r\nCardLib version 1.0."), szAppName, MB_OK|MB_ICONINFORMATION);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case IDM_GAME_EXIT:
|
||||||
|
PostMessage(hwnd, WM_CLOSE, 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_CLOSE:
|
||||||
|
|
||||||
|
ret = IDOK;
|
||||||
|
|
||||||
|
if(fGameStarted)
|
||||||
|
{
|
||||||
|
ret = MessageBox(hwnd, _T("Quit the current game?"), szAppName, MB_OKCANCEL|MB_ICONQUESTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ret == IDOK)
|
||||||
|
{
|
||||||
|
WinHelp(hwnd, szHelpPath, HELP_QUIT, 0);
|
||||||
|
DestroyWindow(hwnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefWindowProc (hwnd, iMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
37
rosapps/games/solitaire/solitaire.h
Normal file
37
rosapps/games/solitaire/solitaire.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef SOLITAIRE_INCLUDED
|
||||||
|
#define SOLITAIRE_INCLUDED
|
||||||
|
|
||||||
|
extern CardWindow SolWnd;
|
||||||
|
extern TCHAR szAppName[];
|
||||||
|
extern bool fGameStarted;
|
||||||
|
|
||||||
|
void CreateSol();
|
||||||
|
void NewGame(void);
|
||||||
|
|
||||||
|
#define NUM_ROW_STACKS 7
|
||||||
|
#define DECK_ID 1
|
||||||
|
#define PILE_ID 2
|
||||||
|
#define SUIT_ID 4
|
||||||
|
#define ROW_ID 10
|
||||||
|
|
||||||
|
extern CardRegion *pDeck;
|
||||||
|
extern CardRegion *pPile;
|
||||||
|
extern CardRegion *pSuitStack[];
|
||||||
|
extern CardRegion *pRowStack[];
|
||||||
|
|
||||||
|
|
||||||
|
bool CARDLIBPROC RowStackDragProc(CardRegion &stackobj, int iNumCards);
|
||||||
|
bool CARDLIBPROC RowStackDropProc(CardRegion &stackobj, const CardStack &dragcards);
|
||||||
|
|
||||||
|
bool CARDLIBPROC SuitStackDropProc(CardRegion &stackobj, const CardStack &dragcards);
|
||||||
|
void CARDLIBPROC SuitStackAddProc(CardRegion &stackobj, const CardStack &added);
|
||||||
|
|
||||||
|
void CARDLIBPROC RowStackClickProc(CardRegion &stackobj, int iNumClicked);
|
||||||
|
void CARDLIBPROC RowStackDblClickProc(CardRegion &stackobj, int iNumClicked);
|
||||||
|
|
||||||
|
void CARDLIBPROC DeckClickProc(CardRegion &stackobj, int iNumClicked);
|
||||||
|
void CARDLIBPROC PileDblClickProc(CardRegion &stackobj, int iNumClicked);
|
||||||
|
|
||||||
|
void CARDLIBPROC PileRemoveProc(CardRegion &stackobj, int iRemoved);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue