#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); }