Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627//// CardLib - CardRegion drawing support//// Freeware// Copyright J Brown 2001//
#include "cardlib.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: DrawCard(hdc, x, y, __hdcPlaceHolder, __cardwidth, __cardheight); break;
case CS_EI_CIRC: case CS_EI_X: CardBlt(hdc, x, y, uEmptyImage); 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;
case CS_EI_CIRC: case CS_EI_X: CardBlt(hdc, xoff, yoff, uEmptyImage); 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;
case CS_EI_CIRC: case CS_EI_X: CardBlt(hdc, 0, 0, uEmptyImage); 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);}