windows-nt/Source/XPSP1/NT/shell/osshell/games/sol/cards.c
2020-09-26 16:20:57 +08:00

614 lines
17 KiB
C

#include "sol.h"
#ifndef DLL
VSZASSERT
#else
#ifdef DEBUG
#undef Assert
#define Assert(f) { if (!(f)) { ExitWindows(0L); } }
#endif
#endif
#define COOLCARD
#ifdef COOLCARD
void SaveCorners(HDC hdc, LONG FAR *rgRGB, INT x, INT y, INT dx, INT dy);
void RestoreCorners(HDC hdc, LONG FAR *rgRGB, INT x, INT y, INT dx, INT dy);
#endif
VOID APIENTRY cdtTerm(VOID);
VOID MyDeleteHbm(HBITMAP hbm);
static HBITMAP HbmFromCd(INT, HDC);
static BOOL FLoadBack(INT);
// we removed the older card decks that required Animation. The new
// card deck doesn't involve any animation.
#ifdef UNUSEDCODE
typedef struct
{
INT id;
DX dx;
DY dy;
} SPR;
#define isprMax 4
typedef struct
{
INT cdBase;
DX dxspr;
DY dyspr;
INT isprMac;
SPR rgspr[isprMax];
} ANI;
#define ianiMax 4
static ANI rgani[ianiMax] =
{ IDFACEDOWN12, 32, 22, 4,
{IDASLIME1, 32, 32,
IDASLIME2, 32, 32,
IDASLIME1, 32, 32,
IDFACEDOWN12, 32, 32
},
IDFACEDOWN10, 36, 12, 2,
{IDAKASTL1, 42, 12,
IDFACEDOWN10, 42, 12,
0, 0, 0,
0, 0, 0
},
IDFACEDOWN11, 14, 12, 4,
{
IDAFLIPE1, 47, 1,
IDAFLIPE2, 47, 1,
IDAFLIPE1, 47, 1,
IDFACEDOWN11, 47, 1
},
IDFACEDOWN3, 24, 7, 4,
{
IDABROBOT1, 24, 40,
IDABROBOT2, 24, 40,
IDABROBOT1, 24, 40,
IDFACEDOWN3, 24, 40
}
/* remember to inc ianiMax */
};
#endif
static HBITMAP hbmCard[52] =
{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
static HBITMAP hbmGhost = NULL;
static HBITMAP hbmBack = NULL;
static HBITMAP hbmDeckX = NULL;
static HBITMAP hbmDeckO = NULL;
static INT idback = 0;
static INT dxCard, dyCard;
static INT cInits = 0;
#ifdef DLL
HANDLE hinstApp;
#else
extern HANDLE hinstApp;
#endif
BOOL APIENTRY cdtInit(INT FAR *pdxCard, INT FAR *pdyCard)
/*
* Parameters:
* pdxCard, pdyCard
* Far pointers to ints where card size will be placed
*
* Returns:
* True when successful, False when it can't find one of the standard
* bitmaps.
*/
{
BITMAP bmCard;
HDC hdc = NULL;
HBITMAP hbmDstBitmap;
HANDLE hDstOld;
HANDLE hSrcOld;
HDC hdcDstMemory;
HDC hdcSrcMemory;
#ifdef DLL
if (cInits++ != 0)
{
*pdxCard = dxCard;
*pdyCard = dyCard;
return fTrue;
}
#endif
hbmGhost = LoadBitmap( hinstApp, MAKEINTRESOURCE(IDGHOST));
hbmDeckX = LoadBitmap( hinstApp, MAKEINTRESOURCE(IDX));
hbmDeckO = LoadBitmap( hinstApp, MAKEINTRESOURCE(IDO));
if(hbmGhost == NULL || hbmDeckX == NULL || hbmDeckO == NULL) {
goto Fail;
}
GetObject( hbmGhost, sizeof( BITMAP), (LPSTR)&bmCard);
dxCard = *pdxCard = bmCard.bmWidth;
dyCard = *pdyCard = bmCard.bmHeight;
//
// Create two compatible memory DCs for bitmap conversion.
//
hdc = GetDC(NULL);
hdcSrcMemory = CreateCompatibleDC(hdc);
hdcDstMemory = CreateCompatibleDC(hdc);
if ((hdcSrcMemory == NULL) || (hdcDstMemory == NULL)) {
goto Fail;
}
//
// Create a compatible bitmap for the conversion of the Ghost
// bitmap, blt the loaded bitmap to the compatible bitmap, and
// delete the original bitmap.
//
hbmDstBitmap = CreateCompatibleBitmap(hdc, dxCard, dyCard);
if (hbmDstBitmap == NULL) {
goto Fail;
}
hSrcOld = SelectObject(hdcSrcMemory, hbmGhost);
hDstOld = SelectObject(hdcDstMemory, hbmDstBitmap);
BitBlt(hdcDstMemory, 0, 0, dxCard, dyCard, hdcSrcMemory, 0, 0, SRCCOPY);
SelectObject(hdcSrcMemory, hSrcOld);
SelectObject(hdcDstMemory, hDstOld);
DeleteObject(hbmGhost);
hbmGhost = hbmDstBitmap;
//
// Create a compatible bitmap for the conversion of the DeckX
// bitmap, blt the loaded bitmap to the compatible bitmap, and
// delete the original bitmap.
//
hbmDstBitmap = CreateCompatibleBitmap(hdc, dxCard, dyCard);
if (hbmDstBitmap == NULL) {
goto Fail;
}
hSrcOld = SelectObject(hdcSrcMemory, hbmDeckX);
hDstOld = SelectObject(hdcDstMemory, hbmDstBitmap);
BitBlt(hdcDstMemory, 0, 0, dxCard, dyCard, hdcSrcMemory, 0, 0, SRCCOPY);
SelectObject(hdcSrcMemory, hSrcOld);
SelectObject(hdcDstMemory, hDstOld);
DeleteObject(hbmDeckX);
hbmDeckX = hbmDstBitmap;
//
// Create a compatible bitmap for the conversion of the DeckO
// bitmap, blt the loaded bitmap to the compatible bitmap, and
// delete the original bitmap.
//
hbmDstBitmap = CreateCompatibleBitmap(hdc, dxCard, dyCard);
if (hbmDstBitmap == NULL) {
}
hSrcOld = SelectObject(hdcSrcMemory, hbmDeckO);
hDstOld = SelectObject(hdcDstMemory, hbmDstBitmap);
BitBlt(hdcDstMemory, 0, 0, dxCard, dyCard, hdcSrcMemory, 0, 0, SRCCOPY);
SelectObject(hdcSrcMemory, hSrcOld);
SelectObject(hdcDstMemory, hDstOld);
DeleteObject(hbmDeckO);
hbmDeckO = hbmDstBitmap;
//
// Delete the compatible DCs.
//
DeleteDC(hdcDstMemory);
DeleteDC(hdcSrcMemory);
ReleaseDC(NULL, hdc);
return fTrue;
Fail:
if (hdc != NULL) {
ReleaseDC(NULL, hdc);
}
cdtTerm();
return fFalse;
}
BOOL APIENTRY cdtDrawExt(HDC hdc, INT x, INT y, INT dx, INT dy, INT cd, INT mode, DWORD rgbBgnd)
/*
* Parameters:
* hdc HDC to window to draw cards on
* x, y Where you'd like them
* dx,dy card extents
* cd Card to be drawn
* mode Way you want it drawn
*
* Returns:
* True if card successfully drawn, False otherwise
*/
{
HBITMAP hbmSav;
HDC hdcMemory;
DWORD dwRop;
HBRUSH hbr;
#ifdef COOLCARD
LONG rgRGB[12];
#endif
Assert(hdc != NULL);
switch (mode)
{
default:
Assert(fFalse);
break;
case FACEUP:
hbmSav = HbmFromCd(cd, hdc);
dwRop = SRCCOPY;
break;
case FACEDOWN:
if(!FLoadBack(cd))
return fFalse;
hbmSav = hbmBack;
dwRop = SRCCOPY;
break;
case REMOVE:
case GHOST:
hbr = CreateSolidBrush( rgbBgnd);
if(hbr == NULL)
return fFalse;
MUnrealizeObject( hbr);
if((hbr = SelectObject( hdc, hbr)) != NULL)
{
PatBlt(hdc, x, y, dx, dy, PATCOPY);
hbr = SelectObject( hdc, hbr);
}
DeleteObject( hbr);
if(mode == REMOVE)
return fTrue;
Assert(mode == GHOST);
/* default: fall thru */
case INVISIBLEGHOST:
hbmSav = hbmGhost;
dwRop = SRCAND;
break;
case DECKX:
hbmSav = hbmDeckX;
dwRop = SRCCOPY;
break;
case DECKO:
hbmSav = hbmDeckO;
dwRop = SRCCOPY;
break;
case HILITE:
hbmSav = HbmFromCd(cd, hdc);
dwRop = NOTSRCCOPY;
break;
}
if (hbmSav == NULL)
return fFalse;
else
{
hdcMemory = CreateCompatibleDC( hdc);
if(hdcMemory == NULL)
return fFalse;
if((hbmSav = SelectObject( hdcMemory, hbmSav)) != NULL)
{
#ifdef COOLCARD
if( !fKlondWinner )
SaveCorners(hdc, rgRGB, x, y, dx, dy);
#endif
if(dx != dxCard || dy != dyCard)
StretchBlt(hdc, x, y, dx, dy, hdcMemory, 0, 0, dxCard, dyCard, dwRop);
else
BitBlt( hdc, x, y, dxCard, dyCard, hdcMemory, 0, 0, dwRop);
SelectObject( hdcMemory, hbmSav);
/* draw the border for the red cards */
if(mode == FACEUP)
{
INT icd;
icd = RaFromCd(cd) % 13 + SuFromCd(cd) * 13+1;
if((icd >= IDADIAMONDS && icd <= IDTDIAMONDS) ||
(icd >= IDAHEARTS && icd <= IDTHEARTS))
{
PatBlt(hdc, x+2, y, dx-4, 1, BLACKNESS); /* top */
PatBlt(hdc, x+dx-1, y+2, 1, dy-4, BLACKNESS); /* right */
PatBlt(hdc, x+2, y+dy-1, dx-4, 1, BLACKNESS); /* bottom */
PatBlt(hdc, x, y+2, 1, dy-4, BLACKNESS); /* left */
SetPixel(hdc, x+1, y+1, 0L); /* top left */
SetPixel(hdc, x+dx-2, y+1, 0L); /* top right */
SetPixel(hdc, x+dx-2, y+dy-2, 0L); /* bot right */
SetPixel(hdc, x+1, y+dy-2, 0L); /* bot left */
}
}
#ifdef COOLCARD
if( !fKlondWinner )
RestoreCorners(hdc, rgRGB, x, y, dx, dy);
#endif
}
DeleteDC( hdcMemory);
return fTrue;
}
}
BOOL APIENTRY cdtDraw(HDC hdc, INT x, INT y, INT cd, INT mode, DWORD rgbBgnd)
/*
* Parameters:
* hdc HDC to window to draw cards on
* x, y Where you'd like them
* cd Card to be drawn
* mode Way you want it drawn
*
* Returns:
* True if card successfully drawn, False otherwise
*/
{
return cdtDrawExt(hdc, x, y, dxCard, dyCard, cd, mode, rgbBgnd);
}
#ifdef COOLCARD
void SaveCorners(HDC hdc, LONG FAR *rgRGB, INT x, INT y, INT dx, INT dy)
{
if(dx != dxCard || dy != dyCard)
return;
/* Upper Left */
rgRGB[0] = GetPixel(hdc, x, y);
rgRGB[1] = GetPixel(hdc, x+1, y);
rgRGB[2] = GetPixel(hdc, x, y+1);
/* Upper Right */
x += dx -1;
rgRGB[3] = GetPixel(hdc, x, y);
rgRGB[4] = GetPixel(hdc, x-1, y);
rgRGB[5] = GetPixel(hdc, x, y+1);
/* Lower Right */
y += dy-1;
rgRGB[6] = GetPixel(hdc, x, y);
rgRGB[7] = GetPixel(hdc, x, y-1);
rgRGB[8] = GetPixel(hdc, x-1, y);
/* Lower Left */
x -= dx-1;
rgRGB[9] = GetPixel(hdc, x, y);
rgRGB[10] = GetPixel(hdc, x+1, y);
rgRGB[11] = GetPixel(hdc, x, y-1);
}
void RestoreCorners(HDC hdc, LONG FAR *rgRGB, INT x, INT y, INT dx, INT dy)
{
if(dx != dxCard || dy != dyCard)
return;
/* Upper Left */
SetPixel(hdc, x, y, rgRGB[0]);
SetPixel(hdc, x+1, y, rgRGB[1]);
SetPixel(hdc, x, y+1, rgRGB[2]);
/* Upper Right */
x += dx-1;
SetPixel(hdc, x, y, rgRGB[3]);
SetPixel(hdc, x-1, y, rgRGB[4]);
SetPixel(hdc, x, y+1, rgRGB[5]);
/* Lower Right */
y += dy-1;
SetPixel(hdc, x, y, rgRGB[6]);
SetPixel(hdc, x, y-1, rgRGB[7]);
SetPixel(hdc, x-1, y, rgRGB[8]);
/* Lower Left */
x -= dx-1;
SetPixel(hdc, x, y, rgRGB[9]);
SetPixel(hdc, x+1, y, rgRGB[10]);
SetPixel(hdc, x, y-1, rgRGB[11]);
}
#endif
BOOL APIENTRY cdtAnimate(HDC hdc, INT cd, INT x, INT y, INT ispr)
{
INT iani;
ANI *pani;
SPR *pspr;
HBITMAP hbm;
HDC hdcMem;
X xSrc;
Y ySrc;
if(ispr < 0)
return fFalse;
Assert(hdc != NULL);
for(iani = 0; iani < ianiMax; iani++)
{
if(cd == rgani[iani].cdBase)
{
pani = &rgani[iani];
if(ispr < pani->isprMac)
{
pspr = &pani->rgspr[ispr];
Assert(pspr->id != 0);
if(pspr->id == cd)
{
xSrc = pspr->dx;
ySrc = pspr->dy;
}
else
xSrc = ySrc = 0;
hbm = LoadBitmap(hinstApp, MAKEINTRESOURCE(pspr->id));
if(hbm == NULL)
return fFalse;
hdcMem = CreateCompatibleDC(hdc);
if(hdcMem == NULL)
{
DeleteObject(hbm);
return fFalse;
}
if((hbm = SelectObject(hdcMem, hbm)) != NULL)
{
BitBlt(hdc, x+pspr->dx, y+pspr->dy, pani->dxspr, pani->dyspr,
hdcMem, xSrc, ySrc, SRCCOPY);
DeleteObject(SelectObject(hdcMem, hbm));
}
DeleteDC(hdcMem);
return fTrue;
}
}
}
return fFalse;
}
/* loads global bitmap hbmBack */
BOOL FLoadBack(INT idbackNew)
{
Assert(FInRange(idbackNew, IDFACEDOWNFIRST, IDFACEDOWNLAST));
if(idback != idbackNew)
{
MyDeleteHbm(hbmBack);
if((hbmBack = LoadBitmap(hinstApp, MAKEINTRESOURCE(idbackNew))) != NULL)
idback = idbackNew;
else
idback = 0;
}
return idback != 0;
}
static HBITMAP HbmFromCd(INT cd, HDC hdc)
{
INT icd;
HBITMAP hbmDstBitmap;
HANDLE hDstOld;
HANDLE hSrcOld;
HDC hdcDstMemory;
HDC hdcSrcMemory;
if (hbmCard[cd] == NULL) {
icd = RaFromCd(cd) % 13 + SuFromCd(cd) * 13;
if ((hbmCard[cd] = LoadBitmap(hinstApp,MAKEINTRESOURCE(icd+1))) == NULL) {
return NULL;
}
//
// Create two compatible memory DCs for bitmap conversion.
//
hdcSrcMemory = CreateCompatibleDC(hdc);
hdcDstMemory = CreateCompatibleDC(hdc);
if ((hdcSrcMemory == NULL) || (hdcDstMemory == NULL)) {
goto Finish;
}
//
// Create a compatible bitmap for the conversion of the card
// bitmap, blt the loaded bitmap to the compatible bitmap, and
// delete the original bitmap.
//
hbmDstBitmap = CreateCompatibleBitmap(hdc, dxCard, dyCard);
if (hbmDstBitmap == NULL) {
goto Finish;
}
hSrcOld = SelectObject(hdcSrcMemory, hbmCard[cd]);
hDstOld = SelectObject(hdcDstMemory, hbmDstBitmap);
BitBlt(hdcDstMemory, 0, 0, dxCard, dyCard, hdcSrcMemory, 0, 0, SRCCOPY);
SelectObject(hdcSrcMemory, hSrcOld);
SelectObject(hdcDstMemory, hDstOld);
DeleteObject(hbmCard[cd]);
hbmCard[cd] = hbmDstBitmap;
//
// Delete the compatible DCs.
//
DeleteDC(hdcDstMemory);
DeleteDC(hdcSrcMemory);
}
Finish:
return hbmCard[cd];
}
VOID MyDeleteHbm(HBITMAP hbm)
{
if(hbm != NULL)
DeleteObject(hbm);
}
VOID APIENTRY cdtTerm()
/*
* Free up space if it's time to do so.
*
* Parameters:
* none
*
* Returns:
* nothing
*/
{
INT i;
#ifdef DLL
if (--cInits > 0) return;
#endif
for (i = 0; i < 52; i++) {
MyDeleteHbm(hbmCard[i]);
hbmCard[i] = NULL;
}
MyDeleteHbm(hbmGhost);
MyDeleteHbm(hbmBack);
MyDeleteHbm(hbmDeckX);
MyDeleteHbm(hbmDeckO);
}