1*c2c66affSColin Finck //
2*c2c66affSColin Finck //    CardLib - CardRegion drawing support
3*c2c66affSColin Finck //
4*c2c66affSColin Finck //    Freeware
5*c2c66affSColin Finck //    Copyright J Brown 2001
6*c2c66affSColin Finck //
7*c2c66affSColin Finck 
8*c2c66affSColin Finck #include "cardlib.h"
9*c2c66affSColin Finck 
10*c2c66affSColin Finck HPALETTE UseNicePalette(HDC hdc, HPALETTE hPalette);
11*c2c66affSColin Finck void PaintRect(HDC hdc, RECT *rect, COLORREF colour);
12*c2c66affSColin Finck void CardBlt(HDC hdc, int x, int y, int nCardNum);
13*c2c66affSColin Finck void DrawCard(HDC hdc, int x, int y, HDC hdcSource, int width, int height);
14*c2c66affSColin Finck 
15*c2c66affSColin Finck //
16*c2c66affSColin Finck //    Draw specified card at position x, y
17*c2c66affSColin Finck //    xoff   - source offset from left of card
18*c2c66affSColin Finck //    yoff   - source offset from top of card
19*c2c66affSColin Finck //    width  - width to draw
20*c2c66affSColin Finck //    height - height to draw
21*c2c66affSColin Finck //
CardBlt(HDC hdc,int x,int y,int nCardNum)22*c2c66affSColin Finck void CardBlt(HDC hdc, int x, int y, int nCardNum)//, int xoff, int yoff, int width, int height)
23*c2c66affSColin Finck {
24*c2c66affSColin Finck     int sx = nCardNum * __cardwidth;
25*c2c66affSColin Finck     int sy = 0;
26*c2c66affSColin Finck     int width  = __cardwidth;
27*c2c66affSColin Finck     int height = __cardheight;
28*c2c66affSColin Finck 
29*c2c66affSColin Finck     //draw main center band
30*c2c66affSColin Finck     BitBlt(hdc, x+2, y, width - 4, height, __hdcCardBitmaps, sx+2, sy+0, SRCCOPY);
31*c2c66affSColin Finck 
32*c2c66affSColin Finck     //draw the two bits to the left
33*c2c66affSColin Finck     BitBlt(hdc, x,   y+2, 1, height - 4, __hdcCardBitmaps, sx+0, sy+2, SRCCOPY);
34*c2c66affSColin Finck     BitBlt(hdc, x+1, y+1, 1, height - 2, __hdcCardBitmaps, sx+1, sy+1, SRCCOPY);
35*c2c66affSColin Finck 
36*c2c66affSColin Finck     //draw the two bits to the right
37*c2c66affSColin Finck     BitBlt(hdc, x+width-2, y+1, 1, height - 2, __hdcCardBitmaps, sx+width-2, sy+1, SRCCOPY);
38*c2c66affSColin Finck     BitBlt(hdc, x+width-1, y+2, 1, height - 4, __hdcCardBitmaps, sx+width-1, sy+2, SRCCOPY);
39*c2c66affSColin Finck }
40*c2c66affSColin Finck 
41*c2c66affSColin Finck //
42*c2c66affSColin Finck //    Draw a shape this this:
43*c2c66affSColin Finck //
44*c2c66affSColin Finck //   ++++++++++++
45*c2c66affSColin Finck //  ++++++++++++++
46*c2c66affSColin Finck // ++            ++
47*c2c66affSColin Finck //
DrawHorzCardStrip(HDC hdc,int x,int y,int nCardNum,int height,BOOL fDrawTips)48*c2c66affSColin Finck void DrawHorzCardStrip(HDC hdc, int x, int y, int nCardNum, int height, BOOL fDrawTips)
49*c2c66affSColin Finck {
50*c2c66affSColin Finck     int sx  = nCardNum * __cardwidth;
51*c2c66affSColin Finck     int sy  = 0;
52*c2c66affSColin Finck     int one = 1;
53*c2c66affSColin Finck     int two = 2;
54*c2c66affSColin Finck     BOOL tips = fDrawTips ? FALSE : TRUE;
55*c2c66affSColin Finck 
56*c2c66affSColin Finck     if(height == 0) return;
57*c2c66affSColin Finck 
58*c2c66affSColin Finck     if(height < 0)
59*c2c66affSColin Finck     {
60*c2c66affSColin Finck         sy = sy + __cardheight;
61*c2c66affSColin Finck         y  -= height;
62*c2c66affSColin Finck         one = -one;
63*c2c66affSColin Finck         two = -two;
64*c2c66affSColin Finck     }
65*c2c66affSColin Finck 
66*c2c66affSColin Finck     // draw the main vertical band
67*c2c66affSColin Finck     //
68*c2c66affSColin Finck     BitBlt(hdc, x + 2, y, __cardwidth - 4, height, __hdcCardBitmaps, sx+2, sy, SRCCOPY);
69*c2c66affSColin Finck 
70*c2c66affSColin Finck     //if(height <= 1) return;
71*c2c66affSColin Finck 
72*c2c66affSColin Finck     // draw the "lips" at the left and right
73*c2c66affSColin Finck     BitBlt(hdc, x+1,             y+one, 1, height-one*tips, __hdcCardBitmaps, sx+1,             sy+one, SRCCOPY);
74*c2c66affSColin Finck     BitBlt(hdc, x+__cardwidth-2, y+one, 1, height-one*tips, __hdcCardBitmaps, sx+__cardwidth-2, sy+one, SRCCOPY);
75*c2c66affSColin Finck 
76*c2c66affSColin Finck     //if(height <= 2) return;
77*c2c66affSColin Finck 
78*c2c66affSColin Finck     // draw the outer-most lips
79*c2c66affSColin Finck     BitBlt(hdc, x,               y+two, 1, height-two*tips, __hdcCardBitmaps, sx,               sy+two, SRCCOPY);
80*c2c66affSColin Finck     BitBlt(hdc, x+__cardwidth-1, y+two, 1, height-two*tips, __hdcCardBitmaps, sx+__cardwidth-1, sy+two, SRCCOPY);
81*c2c66affSColin Finck }
82*c2c66affSColin Finck 
83*c2c66affSColin Finck //
84*c2c66affSColin Finck //    Draw a shape like this:
85*c2c66affSColin Finck //
86*c2c66affSColin Finck //     +++
87*c2c66affSColin Finck //      +++
88*c2c66affSColin Finck //   +++
89*c2c66affSColin Finck //   +++
90*c2c66affSColin Finck //   +++
91*c2c66affSColin Finck //   +++
92*c2c66affSColin Finck //   +++
93*c2c66affSColin Finck //   +++
94*c2c66affSColin Finck //    +++
95*c2c66affSColin Finck //     +++
96*c2c66affSColin Finck //
97*c2c66affSColin Finck //
DrawVertCardStrip(HDC hdc,int x,int y,int nCardNum,int width,BOOL fDrawTips)98*c2c66affSColin Finck void DrawVertCardStrip(HDC hdc, int x, int y, int nCardNum, int width, BOOL fDrawTips)
99*c2c66affSColin Finck {
100*c2c66affSColin Finck     int sx  = nCardNum * __cardwidth;
101*c2c66affSColin Finck     int sy  = 0;
102*c2c66affSColin Finck     int one = 1;
103*c2c66affSColin Finck     int two = 2;
104*c2c66affSColin Finck     BOOL tips = fDrawTips ? FALSE : TRUE;
105*c2c66affSColin Finck 
106*c2c66affSColin Finck     if(width == 0) return;
107*c2c66affSColin Finck 
108*c2c66affSColin Finck 
109*c2c66affSColin Finck     if(width < 0)
110*c2c66affSColin Finck     {
111*c2c66affSColin Finck         sx = sx + __cardwidth;
112*c2c66affSColin Finck         x  -= width;
113*c2c66affSColin Finck         one = -1;
114*c2c66affSColin Finck         two = -2;
115*c2c66affSColin Finck     }
116*c2c66affSColin Finck 
117*c2c66affSColin Finck     // draw the main vertical band
118*c2c66affSColin Finck     //
119*c2c66affSColin Finck     BitBlt(hdc, x, y + 2, width, __cardheight - 4, __hdcCardBitmaps, sx, sy+2, SRCCOPY);
120*c2c66affSColin Finck 
121*c2c66affSColin Finck     //if(width <= 1) return;
122*c2c66affSColin Finck 
123*c2c66affSColin Finck     // draw the "lips" at the top and bottom
124*c2c66affSColin Finck     BitBlt(hdc, x+one, y+1,              width-one*tips, 1, __hdcCardBitmaps, sx+one, sy + 1,              SRCCOPY);
125*c2c66affSColin Finck     BitBlt(hdc, x+one, y+__cardheight-2, width-one*tips, 1, __hdcCardBitmaps, sx+one, sy + __cardheight-2, SRCCOPY);
126*c2c66affSColin Finck 
127*c2c66affSColin Finck     //if(width <= 2) return;
128*c2c66affSColin Finck 
129*c2c66affSColin Finck     // draw the outer-most lips
130*c2c66affSColin Finck     BitBlt(hdc, x+two, y,                width-two*tips, 1, __hdcCardBitmaps, sx+two, sy,                  SRCCOPY);
131*c2c66affSColin Finck     BitBlt(hdc, x+two, y+__cardheight-1, width-two*tips, 1, __hdcCardBitmaps, sx+two, sy + __cardheight-1, SRCCOPY);
132*c2c66affSColin Finck }
133*c2c66affSColin Finck 
134*c2c66affSColin Finck //
135*c2c66affSColin Finck //    xdir -   <0 or >0
136*c2c66affSColin Finck //    ydir -   <0 or >0
137*c2c66affSColin Finck //
DrawCardCorner(HDC hdc,int x,int y,int cardval,int xdir,int ydir)138*c2c66affSColin Finck void DrawCardCorner(HDC hdc, int x, int y, int cardval, int xdir, int ydir)
139*c2c66affSColin Finck {
140*c2c66affSColin Finck     int sx = cardval * __cardwidth;
141*c2c66affSColin Finck     int sy = 0;
142*c2c66affSColin Finck 
143*c2c66affSColin Finck     HDC hdcSource = __hdcCardBitmaps;
144*c2c66affSColin Finck 
145*c2c66affSColin Finck     if(xdir < 0)
146*c2c66affSColin Finck     {
147*c2c66affSColin Finck         x  += __cardwidth + xdir - 1;
148*c2c66affSColin Finck         sx += __cardwidth + xdir - 1;
149*c2c66affSColin Finck     }
150*c2c66affSColin Finck     else
151*c2c66affSColin Finck     {
152*c2c66affSColin Finck         x  += xdir;
153*c2c66affSColin Finck         sx += xdir;
154*c2c66affSColin Finck     }
155*c2c66affSColin Finck 
156*c2c66affSColin Finck     if(ydir < 0)
157*c2c66affSColin Finck     {
158*c2c66affSColin Finck         y  += __cardheight + ydir - 1;
159*c2c66affSColin Finck         sy += __cardheight + ydir - 1;
160*c2c66affSColin Finck     }
161*c2c66affSColin Finck     else
162*c2c66affSColin Finck     {
163*c2c66affSColin Finck         y  += ydir;
164*c2c66affSColin Finck         sy += ydir;
165*c2c66affSColin Finck     }
166*c2c66affSColin Finck 
167*c2c66affSColin Finck     //convert x,y directions to -1, +1
168*c2c66affSColin Finck     xdir = xdir < 0 ? -1 : 1;
169*c2c66affSColin Finck     ydir = ydir < 0 ? -1 : 1;
170*c2c66affSColin Finck 
171*c2c66affSColin Finck     SetPixel(hdc, x+xdir, y ,     GetPixel(hdcSource, sx+xdir, sy));
172*c2c66affSColin Finck     SetPixel(hdc, x,      y,      GetPixel(hdcSource, sx,      sy));
173*c2c66affSColin Finck     SetPixel(hdc, x,      y+ydir, GetPixel(hdcSource, sx,      sy+ydir));
174*c2c66affSColin Finck 
175*c2c66affSColin Finck }
176*c2c66affSColin Finck 
177*c2c66affSColin Finck //
178*c2c66affSColin Finck //    Draw a card (i.e. miss out the corners)
179*c2c66affSColin Finck //
DrawCard(HDC hdc,int x,int y,HDC hdcDragCard,int width,int height)180*c2c66affSColin Finck void DrawCard(HDC hdc, int x, int y, HDC hdcDragCard, int width, int height)
181*c2c66affSColin Finck {
182*c2c66affSColin Finck     //draw main center band
183*c2c66affSColin Finck     BitBlt(hdc, x+2, y, width - 4, height, hdcDragCard, 2, 0, SRCCOPY);
184*c2c66affSColin Finck 
185*c2c66affSColin Finck     //draw the two bits to the left
186*c2c66affSColin Finck     BitBlt(hdc, x,   y+2, 1, height - 4, hdcDragCard, 0, 2, SRCCOPY);
187*c2c66affSColin Finck     BitBlt(hdc, x+1, y+1, 1, height - 2, hdcDragCard, 1, 1, SRCCOPY);
188*c2c66affSColin Finck 
189*c2c66affSColin Finck     //draw the two bits to the right
190*c2c66affSColin Finck     BitBlt(hdc, x+width-2, y+1, 1, height - 2, hdcDragCard, width-2, 1, SRCCOPY);
191*c2c66affSColin Finck     BitBlt(hdc, x+width-1, y+2, 1, height - 4, hdcDragCard, width-1, 2, SRCCOPY);
192*c2c66affSColin Finck }
193*c2c66affSColin Finck 
194*c2c66affSColin Finck //
195*c2c66affSColin Finck //    Clip a card SHAPE - basically any rectangle
196*c2c66affSColin Finck //  with rounded corners
197*c2c66affSColin Finck //
ClipCard(HDC hdc,int x,int y,int width,int height)198*c2c66affSColin Finck int ClipCard(HDC hdc, int x, int y, int width, int height)
199*c2c66affSColin Finck {
200*c2c66affSColin Finck     ExcludeClipRect(hdc, x+2,        y,     x+2+width-4, y+  height);
201*c2c66affSColin Finck     ExcludeClipRect(hdc, x,            y+2, x+1,          y+2+height-4);
202*c2c66affSColin Finck     ExcludeClipRect(hdc, x+1,        y+1, x+2,          y+1+height-2);
203*c2c66affSColin Finck     ExcludeClipRect(hdc, x+width-2, y+1, x+width-2+1, y+1+height-2);
204*c2c66affSColin Finck     ExcludeClipRect(hdc, x+width-1, y+2, x+width-1+1, y+2+height-4);
205*c2c66affSColin Finck     return 0;
206*c2c66affSColin Finck }
207*c2c66affSColin Finck 
Clip(HDC hdc)208*c2c66affSColin Finck void CardRegion::Clip(HDC hdc)
209*c2c66affSColin Finck {
210*c2c66affSColin Finck     int numtoclip;
211*c2c66affSColin Finck 
212*c2c66affSColin Finck     if(fVisible == false)
213*c2c66affSColin Finck         return;
214*c2c66affSColin Finck 
215*c2c66affSColin Finck     Update();                //Update this stack's size+card count
216*c2c66affSColin Finck     numtoclip = nNumApparentCards;
217*c2c66affSColin Finck 
218*c2c66affSColin Finck     //if we are making this stack flash on/off, then only
219*c2c66affSColin Finck     //clip the stack for drawing if the flash is in its ON state
220*c2c66affSColin Finck     if(nFlashCount != 0)
221*c2c66affSColin Finck     {
222*c2c66affSColin Finck         if(fFlashVisible == FALSE)
223*c2c66affSColin Finck             numtoclip = 0;
224*c2c66affSColin Finck     }
225*c2c66affSColin Finck 
226*c2c66affSColin Finck     //if offset along a diagonal
227*c2c66affSColin Finck     if(xoffset != 0 && yoffset != 0 && cardstack.NumCards() != 0)
228*c2c66affSColin Finck     {
229*c2c66affSColin Finck         for(int j = 0; j < numtoclip; j ++)
230*c2c66affSColin Finck         {
231*c2c66affSColin Finck             ClipCard(hdc, xpos + xoffset * j, ypos + yoffset * j, __cardwidth, __cardheight);
232*c2c66affSColin Finck         }
233*c2c66affSColin Finck     }
234*c2c66affSColin Finck     //otherwise if just offset along a horizontal/vertical axis
235*c2c66affSColin Finck     else
236*c2c66affSColin Finck     {
237*c2c66affSColin Finck         if(yoffset < 0 && numtoclip > 0)
238*c2c66affSColin Finck         {
239*c2c66affSColin Finck             ClipCard(hdc, xpos, ypos-((numtoclip-1)*-yoffset), width, height);
240*c2c66affSColin Finck         }
241*c2c66affSColin Finck         else if(xoffset < 0 && numtoclip > 0)
242*c2c66affSColin Finck         {
243*c2c66affSColin Finck             ClipCard(hdc, xpos-((numtoclip-1)*-xoffset), ypos, width, height);
244*c2c66affSColin Finck         }
245*c2c66affSColin Finck         else
246*c2c66affSColin Finck         {
247*c2c66affSColin Finck             ClipCard(hdc, xpos, ypos, width, height);
248*c2c66affSColin Finck         }
249*c2c66affSColin Finck     }
250*c2c66affSColin Finck 
251*c2c66affSColin Finck }
252*c2c66affSColin Finck 
Render(HDC hdc)253*c2c66affSColin Finck void CardRegion::Render(HDC hdc)
254*c2c66affSColin Finck {
255*c2c66affSColin Finck     int cardnum = 0;
256*c2c66affSColin Finck     int numtodraw;
257*c2c66affSColin Finck     BOOL fDrawTips;
258*c2c66affSColin Finck 
259*c2c66affSColin Finck     Update();            //Update this stack's card count + size
260*c2c66affSColin Finck 
261*c2c66affSColin Finck     numtodraw = nNumApparentCards;
262*c2c66affSColin Finck 
263*c2c66affSColin Finck     if(nFlashCount != 0)
264*c2c66affSColin Finck     {
265*c2c66affSColin Finck         if(fFlashVisible == false)
266*c2c66affSColin Finck             numtodraw = 0;
267*c2c66affSColin Finck     }
268*c2c66affSColin Finck 
269*c2c66affSColin Finck     if(fVisible == 0) return;
270*c2c66affSColin Finck 
271*c2c66affSColin Finck     cardnum = cardstack.NumCards() - numtodraw;
272*c2c66affSColin Finck     int counter;
273*c2c66affSColin Finck 
274*c2c66affSColin Finck     for(counter = 0; counter < numtodraw; counter++)
275*c2c66affSColin Finck     {
276*c2c66affSColin Finck         int cardval;
277*c2c66affSColin Finck 
278*c2c66affSColin Finck         int x = xoffset * counter + xpos;
279*c2c66affSColin Finck         int y = yoffset * counter + ypos;
280*c2c66affSColin Finck 
281*c2c66affSColin Finck         //if about to draw last card, then actually draw the top card
282*c2c66affSColin Finck         if(counter == numtodraw - 1) cardnum = cardstack.NumCards() - 1;
283*c2c66affSColin Finck 
284*c2c66affSColin Finck         Card card = cardstack.cardlist[cardnum];
285*c2c66affSColin Finck         cardval = card.Idx();
286*c2c66affSColin Finck 
287*c2c66affSColin Finck         if(card.FaceDown())
288*c2c66affSColin Finck             cardval = nBackCardIdx;    //card-back
289*c2c66affSColin Finck 
290*c2c66affSColin Finck         //only draw the visible part of the card
291*c2c66affSColin Finck         if(counter < numtodraw - 1)
292*c2c66affSColin Finck         {
293*c2c66affSColin Finck             if(yoffset != 0 && xoffset != 0)
294*c2c66affSColin Finck                 fDrawTips = FALSE;
295*c2c66affSColin Finck             else
296*c2c66affSColin Finck                 fDrawTips = TRUE;
297*c2c66affSColin Finck 
298*c2c66affSColin Finck             if((yoffset != 0 && abs(xoffset) == 1) || (xoffset != 0 && abs(yoffset) == 1))
299*c2c66affSColin Finck                 fDrawTips = TRUE;
300*c2c66affSColin Finck 
301*c2c66affSColin Finck             //draw horizontal strips
302*c2c66affSColin Finck             if(yoffset > 0)
303*c2c66affSColin Finck             {
304*c2c66affSColin Finck                 DrawHorzCardStrip(hdc, x, y, cardval, yoffset, fDrawTips);
305*c2c66affSColin Finck             }
306*c2c66affSColin Finck             else if(yoffset < 0)
307*c2c66affSColin Finck             {
308*c2c66affSColin Finck                 DrawHorzCardStrip(hdc, x, y+__cardheight+yoffset, cardval, yoffset, fDrawTips);
309*c2c66affSColin Finck             }
310*c2c66affSColin Finck 
311*c2c66affSColin Finck             //draw some vertical bars
312*c2c66affSColin Finck             if(xoffset > 0)
313*c2c66affSColin Finck             {
314*c2c66affSColin Finck                 DrawVertCardStrip(hdc, x, y, cardval, xoffset, fDrawTips);
315*c2c66affSColin Finck             }
316*c2c66affSColin Finck             else if(xoffset < 0)
317*c2c66affSColin Finck             {
318*c2c66affSColin Finck                 DrawVertCardStrip(hdc, x+__cardwidth+xoffset, y, cardval, xoffset, fDrawTips);
319*c2c66affSColin Finck             }
320*c2c66affSColin Finck 
321*c2c66affSColin Finck             if(yoffset != 0 && xoffset != 0)//fDrawTips == FALSE)
322*c2c66affSColin Finck             {
323*c2c66affSColin Finck                 //if we didn't draw any tips, then this is a 2-dim stack
324*c2c66affSColin Finck                 //(i.e, it goes at a diagonal).
325*c2c66affSColin Finck                 //in this case, we need to fill in the small triangle in
326*c2c66affSColin Finck                 //each corner!
327*c2c66affSColin Finck                 DrawCardCorner(hdc, x, y, cardval, xoffset, yoffset);
328*c2c66affSColin Finck             }
329*c2c66affSColin Finck         }
330*c2c66affSColin Finck         //if the top card, draw the whole thing
331*c2c66affSColin Finck         else
332*c2c66affSColin Finck         {
333*c2c66affSColin Finck             CardBlt(hdc, x, y, cardval);
334*c2c66affSColin Finck         }
335*c2c66affSColin Finck 
336*c2c66affSColin Finck         cardnum ++;
337*c2c66affSColin Finck 
338*c2c66affSColin Finck     } //end of index
339*c2c66affSColin Finck 
340*c2c66affSColin Finck     if(counter == 0)    //if the cardstack is empty, then draw it that way
341*c2c66affSColin Finck     {
342*c2c66affSColin Finck         int x = xpos;
343*c2c66affSColin Finck         int y = ypos;
344*c2c66affSColin Finck 
345*c2c66affSColin Finck         switch(uEmptyImage)
346*c2c66affSColin Finck         {
347*c2c66affSColin Finck         default:
348*c2c66affSColin Finck         case CS_EI_NONE:
349*c2c66affSColin Finck             //this wipes the RECT variable, so watch out!
350*c2c66affSColin Finck             //SetRect(&rect, x, y, x+__cardwidth, y+__cardheight);
351*c2c66affSColin Finck             //PaintRect(hdc, &rect, MAKE_PALETTERGB(crBackgnd));
352*c2c66affSColin Finck             parentWnd.PaintCardRgn(hdc, x, y, __cardwidth, __cardheight, x, y);
353*c2c66affSColin Finck             break;
354*c2c66affSColin Finck 
355*c2c66affSColin Finck         case CS_EI_SUNK:
356*c2c66affSColin Finck             DrawCard(hdc, x, y, __hdcPlaceHolder, __cardwidth, __cardheight);
357*c2c66affSColin Finck             break;
358*c2c66affSColin Finck 
359*c2c66affSColin Finck         case CS_EI_CIRC:
360*c2c66affSColin Finck         case CS_EI_X:
361*c2c66affSColin Finck             CardBlt(hdc, x, y, uEmptyImage);
362*c2c66affSColin Finck             break;
363*c2c66affSColin Finck         }
364*c2c66affSColin Finck 
365*c2c66affSColin Finck     }
366*c2c66affSColin Finck 
367*c2c66affSColin Finck     return;
368*c2c66affSColin Finck }
369*c2c66affSColin Finck 
calc_offset(int offset,int numcards,int numtodrag,int realvisible)370*c2c66affSColin Finck int calc_offset(int offset, int numcards, int numtodrag, int realvisible)
371*c2c66affSColin Finck {
372*c2c66affSColin Finck     if(offset >= 0)
373*c2c66affSColin Finck         return -offset * numcards;
374*c2c66affSColin Finck     else
375*c2c66affSColin Finck         return -offset * (numtodrag)       +
376*c2c66affSColin Finck                -offset * (realvisible - 1);
377*c2c66affSColin Finck }
378*c2c66affSColin Finck 
PrepareDragBitmaps(int numtodrag)379*c2c66affSColin Finck void CardRegion::PrepareDragBitmaps(int numtodrag)
380*c2c66affSColin Finck {
381*c2c66affSColin Finck     RECT rect;
382*c2c66affSColin Finck     HDC hdc;
383*c2c66affSColin Finck     int icard;
384*c2c66affSColin Finck     int numcards = cardstack.NumCards();
385*c2c66affSColin Finck     int xoff, yoff;
386*c2c66affSColin Finck 
387*c2c66affSColin Finck     if(nThreedCount > 1)
388*c2c66affSColin Finck     {
389*c2c66affSColin Finck         PrepareDragBitmapsThreed(numtodrag);
390*c2c66affSColin Finck         return;
391*c2c66affSColin Finck     }
392*c2c66affSColin Finck 
393*c2c66affSColin Finck     //work out how big the bitmaps need to be
394*c2c66affSColin Finck     nDragCardWidth  = (numtodrag - 1) * abs(xoffset) + __cardwidth;
395*c2c66affSColin Finck     nDragCardHeight = (numtodrag - 1) * abs(yoffset) + __cardheight;
396*c2c66affSColin Finck 
397*c2c66affSColin Finck     //Create bitmap for the back-buffer
398*c2c66affSColin Finck     hdc = GetDC(NULL);
399*c2c66affSColin Finck     hdcBackGnd = CreateCompatibleDC(hdc);
400*c2c66affSColin Finck     hbmBackGnd = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight);
401*c2c66affSColin Finck     SelectObject(hdcBackGnd, hbmBackGnd);
402*c2c66affSColin Finck 
403*c2c66affSColin Finck     //Create bitmap for the drag-image
404*c2c66affSColin Finck     hdcDragCard = CreateCompatibleDC(hdc);
405*c2c66affSColin Finck     hbmDragCard = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight);
406*c2c66affSColin Finck     SelectObject(hdcDragCard, hbmDragCard);
407*c2c66affSColin Finck     ReleaseDC(NULL, hdc);
408*c2c66affSColin Finck 
409*c2c66affSColin Finck     UseNicePalette(hdcBackGnd,  __hPalette);
410*c2c66affSColin Finck     UseNicePalette(hdcDragCard, __hPalette);
411*c2c66affSColin Finck 
412*c2c66affSColin Finck     int realvisible = numcards / nThreedCount;
413*c2c66affSColin Finck 
414*c2c66affSColin Finck     //if(numcards > 0 && realvisible == 0) realvisible = 1;
415*c2c66affSColin Finck     int iwhichcard = numcards - 1;
416*c2c66affSColin Finck     if(nThreedCount == 1) iwhichcard = 0;
417*c2c66affSColin Finck 
418*c2c66affSColin Finck     //grab the first bit of background so we can prep the back buffer; do this by
419*c2c66affSColin Finck     //rendering the card stack (minus the card we are dragging) to the temporary
420*c2c66affSColin Finck     //background buffer, so it appears if we have lifted the card from the stack
421*c2c66affSColin Finck     //PaintRect(hdcBackGnd, &rect, crBackgnd);
422*c2c66affSColin Finck     SetRect(&rect, 0, 0, nDragCardWidth, nDragCardHeight);
423*c2c66affSColin Finck 
424*c2c66affSColin Finck     xoff = calc_offset(xoffset, numcards, numtodrag, realvisible);
425*c2c66affSColin Finck     yoff = calc_offset(yoffset, numcards, numtodrag, realvisible);
426*c2c66affSColin Finck 
427*c2c66affSColin Finck     parentWnd.PaintCardRgn(hdcBackGnd, 0, 0, nDragCardWidth, nDragCardHeight, xpos - xoff,    ypos - yoff);
428*c2c66affSColin Finck 
429*c2c66affSColin Finck     //
430*c2c66affSColin Finck     //    Render the cardstack into the back-buffer. The stack
431*c2c66affSColin Finck     //    has already had the dragcards removed, so just draw
432*c2c66affSColin Finck     //    what is left
433*c2c66affSColin Finck     //
434*c2c66affSColin Finck     for(icard = 0; icard < realvisible; icard++)
435*c2c66affSColin Finck     {
436*c2c66affSColin Finck         Card card = cardstack.cardlist[iwhichcard];
437*c2c66affSColin Finck         int nCardVal;
438*c2c66affSColin Finck 
439*c2c66affSColin Finck         nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx;
440*c2c66affSColin Finck 
441*c2c66affSColin Finck         xoff = xoffset * icard + calc_offset(xoffset, numcards, numtodrag, realvisible);//- xoffset * ((numcards+numtodrag) / nThreedCount - numtodrag);
442*c2c66affSColin Finck         yoff = yoffset * icard + calc_offset(yoffset, numcards, numtodrag, realvisible);//- yoffset * ((numcards+numtodrag) / nThreedCount - numtodrag);
443*c2c66affSColin Finck 
444*c2c66affSColin Finck         CardBlt(hdcBackGnd, xoff, yoff, nCardVal);
445*c2c66affSColin Finck         iwhichcard++;
446*c2c66affSColin Finck     }
447*c2c66affSColin Finck 
448*c2c66affSColin Finck     //
449*c2c66affSColin Finck     // If there are no cards under this one, just draw the place holder
450*c2c66affSColin Finck     //
451*c2c66affSColin Finck     if(numcards == 0)
452*c2c66affSColin Finck     {
453*c2c66affSColin Finck         int xoff = 0, yoff = 0;
454*c2c66affSColin Finck 
455*c2c66affSColin Finck         if(xoffset < 0)    xoff = nDragCardWidth  -  __cardwidth;
456*c2c66affSColin Finck         if(yoffset < 0)    yoff = nDragCardHeight -  __cardheight;
457*c2c66affSColin Finck 
458*c2c66affSColin Finck         switch(uEmptyImage)
459*c2c66affSColin Finck         {
460*c2c66affSColin Finck         case CS_EI_NONE:
461*c2c66affSColin Finck             //No need to draw anything: We already cleared the
462*c2c66affSColin Finck             //back-buffer before the main loop..
463*c2c66affSColin Finck 
464*c2c66affSColin Finck             //SetRect(&rc, xoff, yoff, xoff+ __cardwidth, yoff + __cardheight);
465*c2c66affSColin Finck             //PaintRect(hdcBackGnd, &rc, MAKE_PALETTERGB(crBackgnd));
466*c2c66affSColin Finck             //parentWnd.PaintCardRgn(hdcBackGnd, xoff, yoff, __cardwidth, __cardheight, xpos, ypos);// + xoff, ypos + yoff);
467*c2c66affSColin Finck             break;
468*c2c66affSColin Finck 
469*c2c66affSColin Finck         case CS_EI_SUNK:
470*c2c66affSColin Finck             DrawCard(hdcBackGnd, xoff, yoff, __hdcPlaceHolder, __cardwidth, __cardheight);
471*c2c66affSColin Finck             break;
472*c2c66affSColin Finck 
473*c2c66affSColin Finck         case CS_EI_CIRC:
474*c2c66affSColin Finck         case CS_EI_X:
475*c2c66affSColin Finck             CardBlt(hdc, xoff, yoff, uEmptyImage);
476*c2c66affSColin Finck             break;
477*c2c66affSColin Finck         }
478*c2c66affSColin Finck     }
479*c2c66affSColin Finck 
480*c2c66affSColin Finck     //
481*c2c66affSColin Finck     //    now render the drag-cards into the dragcard image
482*c2c66affSColin Finck     //
483*c2c66affSColin Finck     PaintRect(hdcDragCard, &rect, crBackgnd);
484*c2c66affSColin Finck 
485*c2c66affSColin Finck     for(icard = 0; icard < numtodrag; icard++)
486*c2c66affSColin Finck     {
487*c2c66affSColin Finck         int nCardVal;
488*c2c66affSColin Finck 
489*c2c66affSColin Finck         if(xoffset >= 0) xoff =  xoffset * icard;
490*c2c66affSColin Finck         else              xoff = -xoffset * (numtodrag - icard - 1);
491*c2c66affSColin Finck 
492*c2c66affSColin Finck         if(yoffset >= 0) yoff =  yoffset * icard;
493*c2c66affSColin Finck         else             yoff = -yoffset * (numtodrag - icard - 1);
494*c2c66affSColin Finck 
495*c2c66affSColin Finck         Card card = dragstack.cardlist[icard];
496*c2c66affSColin Finck 
497*c2c66affSColin Finck         nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx;
498*c2c66affSColin Finck 
499*c2c66affSColin Finck         CardBlt(hdcDragCard, xoff, yoff, nCardVal);
500*c2c66affSColin Finck     }
501*c2c66affSColin Finck }
502*c2c66affSColin Finck 
PrepareDragBitmapsThreed(int numtodrag)503*c2c66affSColin Finck void CardRegion::PrepareDragBitmapsThreed(int numtodrag)
504*c2c66affSColin Finck {
505*c2c66affSColin Finck     RECT rect;
506*c2c66affSColin Finck     HDC hdc;
507*c2c66affSColin Finck     int icard;
508*c2c66affSColin Finck     int numunder = 0;
509*c2c66affSColin Finck     int iwhichcard;
510*c2c66affSColin Finck 
511*c2c66affSColin Finck     int numcards = cardstack.NumCards();
512*c2c66affSColin Finck 
513*c2c66affSColin Finck     //work out how big the bitmaps need to be
514*c2c66affSColin Finck     nDragCardWidth  = (numtodrag - 1) * abs(xoffset) + __cardwidth;
515*c2c66affSColin Finck     nDragCardHeight = (numtodrag - 1) * abs(yoffset) + __cardheight;
516*c2c66affSColin Finck 
517*c2c66affSColin Finck     //Create bitmap for the back-buffer
518*c2c66affSColin Finck     hdc = GetDC(NULL);
519*c2c66affSColin Finck     hdcBackGnd = CreateCompatibleDC(hdc);
520*c2c66affSColin Finck     hbmBackGnd = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight);
521*c2c66affSColin Finck     SelectObject(hdcBackGnd, hbmBackGnd);
522*c2c66affSColin Finck 
523*c2c66affSColin Finck     //create bitmap for the drag-image
524*c2c66affSColin Finck     hdcDragCard = CreateCompatibleDC(hdc);
525*c2c66affSColin Finck     hbmDragCard = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight);
526*c2c66affSColin Finck     SelectObject(hdcDragCard, hbmDragCard);
527*c2c66affSColin Finck     ReleaseDC(NULL, hdc);
528*c2c66affSColin Finck 
529*c2c66affSColin Finck     UseNicePalette(hdcBackGnd,  __hPalette);
530*c2c66affSColin Finck     UseNicePalette(hdcDragCard, __hPalette);
531*c2c66affSColin Finck 
532*c2c66affSColin Finck     //grab the first bit of background so we can prep the back buffer; do this by
533*c2c66affSColin Finck     //rendering the card stack (minus the card we are dragging) to the temporary
534*c2c66affSColin Finck     //background buffer, so it appears if we have lifted the card from the stack
535*c2c66affSColin Finck     //--SetRect(&rect, 0, 0, nDragCardWidth, nDragCardHeight);
536*c2c66affSColin Finck     //--PaintRect(hdcBackGnd, &rect, crBackgnd);
537*c2c66affSColin Finck 
538*c2c66affSColin Finck     int threedadjust = numcards  % nThreedCount == 0;
539*c2c66affSColin Finck 
540*c2c66affSColin Finck     numunder = CalcApparentCards(numcards);
541*c2c66affSColin Finck     iwhichcard = (numcards+numtodrag) - numunder - 1;
542*c2c66affSColin Finck     if(nThreedCount == 1) iwhichcard = 0;
543*c2c66affSColin Finck 
544*c2c66affSColin Finck     int xoff = calc_offset(xoffset, numunder, numtodrag, numunder);
545*c2c66affSColin Finck     int yoff = calc_offset(yoffset, numunder, numtodrag, numunder);
546*c2c66affSColin Finck 
547*c2c66affSColin Finck     parentWnd.PaintCardRgn(hdcBackGnd, 0,0,    nDragCardWidth,nDragCardHeight,    xpos - xoff,ypos - yoff);
548*c2c66affSColin Finck 
549*c2c66affSColin Finck     //
550*c2c66affSColin Finck     //    Render the cardstack into the back-buffer. The stack
551*c2c66affSColin Finck     //    has already had the dragcards removed, so just draw
552*c2c66affSColin Finck     //    what is left
553*c2c66affSColin Finck     //
554*c2c66affSColin Finck     for(icard = 0; icard < numunder; icard++)
555*c2c66affSColin Finck     {
556*c2c66affSColin Finck         Card card = cardstack.cardlist[iwhichcard];
557*c2c66affSColin Finck         int nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx;
558*c2c66affSColin Finck 
559*c2c66affSColin Finck         CardBlt(hdcBackGnd,
560*c2c66affSColin Finck                 xoffset * icard - xoffset*(numunder-numtodrag+threedadjust),
561*c2c66affSColin Finck                 yoffset * icard - yoffset*(numunder-numtodrag+threedadjust),
562*c2c66affSColin Finck                 nCardVal);
563*c2c66affSColin Finck 
564*c2c66affSColin Finck         iwhichcard++;
565*c2c66affSColin Finck     }
566*c2c66affSColin Finck 
567*c2c66affSColin Finck     //
568*c2c66affSColin Finck     // If there are no cards under this one, just draw the place holder
569*c2c66affSColin Finck     //
570*c2c66affSColin Finck     if(numcards == 0)
571*c2c66affSColin Finck     {
572*c2c66affSColin Finck         switch(uEmptyImage)
573*c2c66affSColin Finck         {
574*c2c66affSColin Finck         case CS_EI_NONE:
575*c2c66affSColin Finck             //no need! we've already cleared the whole
576*c2c66affSColin Finck             //back-buffer before the main loop!
577*c2c66affSColin Finck             //SetRect(&rect, 0, 0, __cardwidth, __cardheight);
578*c2c66affSColin Finck             //PaintRect(hdcBackGnd, &rect, MAKE_PALETTERGB(crBackgnd));
579*c2c66affSColin Finck             break;
580*c2c66affSColin Finck 
581*c2c66affSColin Finck         case CS_EI_SUNK:
582*c2c66affSColin Finck             DrawCard(hdcBackGnd, 0, 0, __hdcPlaceHolder, __cardwidth, __cardheight);
583*c2c66affSColin Finck             break;
584*c2c66affSColin Finck 
585*c2c66affSColin Finck         case CS_EI_CIRC:
586*c2c66affSColin Finck         case CS_EI_X:
587*c2c66affSColin Finck             CardBlt(hdc, 0, 0, uEmptyImage);
588*c2c66affSColin Finck             break;
589*c2c66affSColin Finck         }
590*c2c66affSColin Finck     }
591*c2c66affSColin Finck 
592*c2c66affSColin Finck     //
593*c2c66affSColin Finck     //    now render the drag-cards into the dragcard image
594*c2c66affSColin Finck     //
595*c2c66affSColin Finck     PaintRect(hdcDragCard, &rect, crBackgnd);
596*c2c66affSColin Finck 
597*c2c66affSColin Finck     for(icard = 0; icard < numtodrag; icard++)
598*c2c66affSColin Finck     {
599*c2c66affSColin Finck         Card card = dragstack.cardlist[icard];
600*c2c66affSColin Finck         int nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx;
601*c2c66affSColin Finck 
602*c2c66affSColin Finck         CardBlt(hdcDragCard, xoffset * icard, yoffset * icard, nCardVal);
603*c2c66affSColin Finck     }
604*c2c66affSColin Finck }
605*c2c66affSColin Finck 
ReleaseDragBitmaps(void)606*c2c66affSColin Finck void CardRegion::ReleaseDragBitmaps(void)
607*c2c66affSColin Finck {
608*c2c66affSColin Finck     //SelectObject(hdcBackGnd, hOld1);
609*c2c66affSColin Finck     DeleteObject(hbmBackGnd);
610*c2c66affSColin Finck     DeleteDC(hdcBackGnd);
611*c2c66affSColin Finck 
612*c2c66affSColin Finck     //SelectObject(hdcDragCard, hOld2);
613*c2c66affSColin Finck     DeleteObject(hbmDragCard);
614*c2c66affSColin Finck     DeleteDC(hdcDragCard);
615*c2c66affSColin Finck }
616*c2c66affSColin Finck 
617*c2c66affSColin Finck 
Redraw()618*c2c66affSColin Finck void CardRegion::Redraw()
619*c2c66affSColin Finck {
620*c2c66affSColin Finck     HDC hdc = GetDC((HWND)parentWnd);
621*c2c66affSColin Finck 
622*c2c66affSColin Finck     Update();
623*c2c66affSColin Finck     Render(hdc);
624*c2c66affSColin Finck 
625*c2c66affSColin Finck     ReleaseDC((HWND)parentWnd, hdc);
626*c2c66affSColin Finck }
627