]> git.saurik.com Git - wxWidgets.git/blob - demos/forty/card.cpp
Elliptic arc fix for getting bounds
[wxWidgets.git] / demos / forty / card.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: card.cpp
3 // Purpose: Forty Thieves patience game
4 // Author: Chris Breeze
5 // Modified by:
6 // Created: 21/07/97
7 // RCS-ID: $Id$
8 // Copyright: (c) 1993-1998 Chris Breeze
9 // Licence: wxWindows licence
10 //---------------------------------------------------------------------------
11 // Last modified: 22nd July 1998 - ported to wxWidgets 2.0
12 /////////////////////////////////////////////////////////////////////////////
13 //+-------------------------------------------------------------+
14 //| Description
15 //| A class for drawing playing cards.
16 //| Currently assumes that the card symbols have been
17 //| loaded into hbmap_symbols and the pictures for the
18 //| Jack, Queen and King have been loaded into
19 //| hbmap_pictures.
20 //+-------------------------------------------------------------+
21
22 #ifdef __GNUG__
23 #pragma implementation
24 #pragma interface
25 #endif
26
27 // For compilers that support precompilation, includes "wx/wx.h".
28 #include "wx/wxprec.h"
29
30 #ifdef __BORLANDC__
31 #pragma hdrstop
32 #endif
33
34 #ifndef WX_PRECOMP
35 #include "wx/wx.h"
36 #endif
37
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include "forty.h"
42 #include "card.h"
43
44 #if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXX11__)
45 #include "pictures.xpm"
46 #include "symbols.xbm"
47 #endif
48
49 wxBitmap* Card::m_pictureBmap = 0;
50 wxBitmap* Card::m_symbolBmap = 0;
51
52 double Card::m_scale = 1.0;
53 int Card::m_width = 50;
54 int Card::m_height = 70;
55
56 //+-------------------------------------------------------------+
57 //| Card::Card() |
58 //+-------------------------------------------------------------+
59 //| Description: |
60 //| Constructor for a playing card. |
61 //| Checks that the value is in the range 1..52 and then |
62 //| initialises the suit, colour, pipValue and wayUp. |
63 //+-------------------------------------------------------------+
64 Card::Card(int value, WayUp way_up) :
65 m_wayUp(way_up)
66 {
67 if (!m_symbolBmap)
68 {
69 #ifdef __WXMSW__
70 m_symbolBmap = new wxBitmap(_T("CardSymbols"), wxBITMAP_TYPE_BMP_RESOURCE);
71 #else
72 m_symbolBmap = new wxBitmap(Symbols_bits, Symbols_width, Symbols_height);
73 #endif
74 if (!m_symbolBmap->Ok())
75 {
76 ::wxMessageBox(_T("Failed to load bitmap CardSymbols"), _T("Error"));
77 }
78 }
79 if (!m_pictureBmap)
80 {
81 #ifdef __WXMSW__
82 m_pictureBmap = new wxBitmap(_T("CardPictures"), wxBITMAP_TYPE_BMP_RESOURCE);
83 #else
84 m_pictureBmap = new wxBitmap(Pictures);
85 #endif
86 if (!m_pictureBmap->Ok())
87 {
88 ::wxMessageBox(_T("Failed to load bitmap CardPictures"), _T("Error"));
89 }
90 }
91
92 if (value >= 1 && value <= PackSize)
93 {
94 switch ((value - 1) / 13)
95 {
96 case 0:
97 m_suit = clubs;
98 m_colour = black;
99 break;
100 case 1:
101 m_suit = diamonds;
102 m_colour = red;
103 break;
104 case 2:
105 m_suit = hearts;
106 m_colour = red;
107 break;
108 case 3:
109 m_suit = spades;
110 m_colour = black;
111 break;
112 }
113 m_pipValue = 1 + (value - 1) % 13;
114 m_status = true;
115 }
116 else
117 {
118 m_status = false;
119 }
120 } // Card::Card()
121
122
123 //+-------------------------------------------------------------+
124 //| Card::SetScale() |
125 //+-------------------------------------------------------------+
126 //| Description: |
127 //| Scales the cards |
128 //+-------------------------------------------------------------+
129 void Card::SetScale(double scale)
130 {
131 m_scale = scale;
132 m_width = int(50*scale);
133 m_height = int(70*scale);
134 }
135
136 //+-------------------------------------------------------------+
137 //| Card::Erase() |
138 //+-------------------------------------------------------------+
139 //| Description: |
140 //| Erase the card at (x, y) by drawing a rectangle in the |
141 //| background colour. |
142 //+-------------------------------------------------------------+
143 void Card::Erase(wxDC& dc, int x, int y)
144 {
145 wxPen* pen = wxThePenList->FindOrCreatePen(
146 FortyApp::BackgroundColour(),
147 1,
148 wxSOLID
149 );
150 dc.SetPen(* pen);
151 dc.SetBrush(FortyApp::BackgroundBrush());
152 dc.DrawRectangle(x, y, m_width, m_height);
153 } // Card::Erase()
154
155
156 //+-------------------------------------------------------------+
157 //| Card::Draw() |
158 //+-------------------------------------------------------------+
159 //| Description: |
160 //| Draw the card at (x, y). |
161 //| If the card is facedown draw the back of the card. |
162 //| If the card is faceup draw the front of the card. |
163 //| Cards are not held in bitmaps, instead they are drawn |
164 //| from their constituent parts when required. |
165 //| hbmap_symbols contains large and small suit symbols and |
166 //| pip values. These are copied to the appropriate part of |
167 //| the card. Picture cards use the pictures defined in |
168 //| hbmap_pictures. Note that only one picture is defined |
169 //| for the Jack, Queen and King, unlike a real pack where |
170 //| each suit is different. |
171 //| |
172 //| WARNING: |
173 //| The locations of these symbols is 'hard-wired' into the |
174 //| code. Editing the bitmaps or the numbers below will |
175 //| result in the wrong symbols being displayed. |
176 //+-------------------------------------------------------------+
177 void Card::Draw(wxDC& dc, int x, int y)
178 {
179 wxBrush backgroundBrush( dc.GetBackground() );
180 dc.SetBrush(* wxWHITE_BRUSH);
181 dc.SetPen(* wxBLACK_PEN);
182 dc.DrawRoundedRectangle(x, y, m_width, m_height, 4);
183 if (m_wayUp == facedown)
184 {
185 dc.SetBackground(* wxRED_BRUSH);
186 dc.SetBackgroundMode(wxSOLID);
187 wxBrush* brush = wxTheBrushList->FindOrCreateBrush(
188 _T("BLACK"), wxCROSSDIAG_HATCH
189 );
190 dc.SetBrush(* brush);
191
192 dc.DrawRoundedRectangle(
193 x + 4, y + 4,
194 m_width - 8, m_height - 8,
195 2
196 );
197 }
198 else
199 {
200 wxMemoryDC memoryDC;
201
202 memoryDC.SelectObject(*m_symbolBmap);
203
204 // dc.SetBackgroundMode(wxTRANSPARENT);
205
206 dc.SetTextBackground(*wxWHITE);
207 switch (m_suit)
208 {
209 case spades:
210 case clubs:
211 dc.SetTextForeground(*wxBLACK);
212 break;
213 case diamonds:
214 case hearts:
215 dc.SetTextForeground(*wxRED);
216 break;
217 }
218
219 int symsize = 11;
220 int sympos = 14;
221 int sympos2 = 25;
222 int symdist = 5;
223 int symdist2 = 6;
224
225 int pipsize,pippos,valueheight,valuewidth;
226 int valuepos;
227 if (m_scale > 1.2)
228 {
229 pipsize = symsize;
230 pippos = sympos;
231 valueheight = 10;
232 valuewidth = 9;
233 valuepos = 50;
234 }
235 else
236 {
237 pipsize = 7;
238 pippos = 0;
239 valueheight = 7;
240 valuewidth = 6;
241 valuepos = 36;
242 }
243
244 // Draw the value
245 dc.Blit((wxCoord)(x + m_scale*3),
246 (wxCoord)(y + m_scale*3),
247 valuewidth,
248 valueheight,
249 &memoryDC,
250 valuewidth * (m_pipValue - 1),
251 valuepos,
252 wxCOPY);
253 dc.Blit((wxCoord)(x + m_width - m_scale*3 - valuewidth),
254 (wxCoord)(y + m_height - valueheight - m_scale*3),
255 valuewidth,
256 valueheight,
257 &memoryDC,
258 valuewidth * (m_pipValue - 1),
259 valuepos+valueheight,
260 wxCOPY);
261
262 // Draw the pips
263 dc.Blit((wxCoord)(x + m_scale*3 + valuewidth+2),
264 (wxCoord)(y + m_scale*3),
265 pipsize,
266 pipsize,
267 &memoryDC,
268 pipsize * m_suit,
269 pippos,
270 wxCOPY);
271 dc.Blit((wxCoord)(x + m_width - m_scale*3-valuewidth-pipsize-2),
272 (wxCoord)(y + m_height - pipsize - m_scale*3),
273 pipsize,
274 pipsize,
275 &memoryDC,
276 pipsize * m_suit,
277 pipsize+pippos,
278 wxCOPY);
279
280 switch (m_pipValue)
281 {
282 case 1:
283 dc.Blit((wxCoord)(x - symdist + m_width / 2),
284 (wxCoord)(y - m_scale*5 + m_height / 2),
285 symsize,
286 symsize,
287 &memoryDC,
288 symsize * m_suit,
289 sympos,
290 wxCOPY);
291 break;
292
293 case 3:
294 dc.Blit((wxCoord)(x - symdist + m_width / 2),
295 (wxCoord)(y - symdist + m_height / 2),
296 symsize,
297 symsize,
298 &memoryDC,
299 symsize * m_suit,
300 sympos,
301 wxCOPY);
302 case 2:
303 dc.Blit((wxCoord)(x - symdist + m_width / 2),
304 (wxCoord)(y - symdist + m_height / 4),
305 symsize,
306 symsize,
307 &memoryDC,
308 symsize * m_suit,
309 sympos,
310 wxCOPY);
311 dc.Blit((wxCoord)(x - symdist + m_width / 2),
312 (wxCoord)(y - symdist + 3 * m_height / 4),
313 symsize,
314 symsize,
315 &memoryDC,
316 symsize * m_suit,
317 sympos2,
318 wxCOPY);
319 break;
320
321 case 5:
322 dc.Blit((wxCoord)(x - symdist + m_width / 2),
323 (wxCoord)(y - symdist + m_height / 2),
324 symsize,
325 symsize,
326 &memoryDC,
327 symsize * m_suit,
328 sympos,
329 wxCOPY);
330 case 4:
331 dc.Blit((wxCoord)(x - symdist + m_width / 4),
332 (wxCoord)(y - symdist + m_height / 4),
333 symsize,
334 symsize,
335 &memoryDC,
336 symsize * m_suit,
337 sympos,
338 wxCOPY);
339 dc.Blit((wxCoord)(x - symdist + m_width / 4),
340 (wxCoord)(y - symdist + 3 * m_height / 4),
341 symsize,
342 symsize,
343 &memoryDC,
344 symsize * m_suit,
345 sympos2,
346 wxCOPY);
347 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
348 (wxCoord)(y - symdist + m_height / 4),
349 symsize,
350 symsize,
351 &memoryDC,
352 symsize * m_suit,
353 sympos,
354 wxCOPY);
355 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
356 (wxCoord)(y - symdist + 3 * m_height / 4),
357 symsize,
358 symsize,
359 &memoryDC,
360 symsize * m_suit,
361 sympos2,
362 wxCOPY);
363 break;
364
365 case 8:
366 dc.Blit((wxCoord)(x - symdist + 5 * m_width / 10),
367 (wxCoord)(y - symdist + 5 * m_height / 8),
368 symsize,
369 symsize,
370 &memoryDC,
371 symsize * m_suit,
372 sympos2,
373 wxCOPY);
374 case 7:
375 dc.Blit((wxCoord)(x - symdist + 5 * m_width / 10),
376 (wxCoord)(y - symdist + 3 * m_height / 8),
377 symsize,
378 symsize,
379 &memoryDC,
380 symsize * m_suit,
381 sympos,
382 wxCOPY);
383 case 6:
384 dc.Blit((wxCoord)(x - symdist + m_width / 4),
385 (wxCoord)(y - symdist + m_height / 4),
386 symsize,
387 symsize,
388 &memoryDC, symsize * m_suit, sympos, wxCOPY);
389 dc.Blit((wxCoord)(x - symdist + m_width / 4),
390 (wxCoord)(y - symdist + m_height / 2),
391 symsize,
392 symsize,
393 &memoryDC,
394 symsize * m_suit,
395 sympos,
396 wxCOPY);
397 dc.Blit((wxCoord)(x - symdist + m_width / 4),
398 (wxCoord)(y - symdist + 3 * m_height / 4),
399 symsize,
400 symsize,
401 &memoryDC,
402 symsize * m_suit,
403 sympos2,
404 wxCOPY);
405 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
406 (wxCoord)(y - symdist + m_height / 4),
407 symsize,
408 symsize,
409 &memoryDC,
410 symsize * m_suit,
411 sympos,
412 wxCOPY);
413 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
414 (wxCoord)(y - symdist + m_height / 2),
415 symsize,
416 symsize,
417 &memoryDC,
418 symsize * m_suit,
419 sympos,
420 wxCOPY);
421 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
422 (wxCoord)(y - symdist + 3 * m_height / 4),
423 symsize,
424 symsize,
425 &memoryDC,
426 symsize * m_suit,
427 sympos2,
428 wxCOPY);
429 break;
430
431 case 10:
432 dc.Blit((wxCoord)(x - symdist + m_width / 2),
433 (wxCoord)(y - symdist + 2 * m_height / 3),
434 symsize,
435 symsize,
436 &memoryDC,
437 symsize * m_suit,
438 sympos2,
439 wxCOPY);
440 case 9:
441 dc.Blit((wxCoord)(x - symdist + m_width / 4),
442 (wxCoord)(y - symdist2 + m_height / 4),
443 symsize,
444 symsize,
445 &memoryDC,
446 symsize * m_suit,
447 sympos,
448 wxCOPY);
449 dc.Blit((wxCoord)(x - symdist + m_width / 4),
450 (wxCoord)(y - symdist2 + 5 * m_height / 12),
451 symsize,
452 symsize,
453 &memoryDC,
454 symsize * m_suit,
455 sympos,
456 wxCOPY);
457 dc.Blit((wxCoord)(x - symdist + m_width / 4),
458 (wxCoord)(y - symdist + 7 * m_height / 12),
459 symsize,
460 symsize,
461 &memoryDC,
462 symsize * m_suit,
463 sympos2,
464 wxCOPY);
465 dc.Blit((wxCoord)(x - symdist + m_width / 4),
466 (wxCoord)(y - symdist + 3 * m_height / 4),
467 symsize,
468 symsize,
469 &memoryDC,
470 symsize * m_suit,
471 sympos2,
472 wxCOPY);
473
474 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
475 (wxCoord)(y - symdist2 + m_height / 4),
476 symsize,
477 symsize,
478 &memoryDC,
479 symsize * m_suit,
480 sympos,
481 wxCOPY);
482 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
483 (wxCoord)(y - symdist2 + 5 * m_height / 12),
484 symsize,
485 symsize,
486 &memoryDC,
487 symsize * m_suit,
488 sympos,
489 wxCOPY);
490 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
491 (wxCoord)(y - symdist + 7 * m_height / 12),
492 symsize,
493 symsize,
494 &memoryDC,
495 symsize * m_suit,
496 sympos2,
497 wxCOPY);
498 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
499 (wxCoord)(y - symdist + 3 * m_height / 4),
500 symsize,
501 symsize,
502 &memoryDC,
503 symsize * m_suit,
504 sympos2,
505 wxCOPY);
506 dc.Blit((wxCoord)(x - symdist + m_width / 2),
507 (wxCoord)(y - symdist + m_height / 3),
508 symsize,
509 symsize,
510 &memoryDC,
511 symsize * m_suit,
512 sympos,
513 wxCOPY);
514 break;
515 case 11:
516 case 12:
517 case 13:
518 memoryDC.SelectObject(*m_pictureBmap);
519 int picwidth = 40,picheight = 45;
520 dc.Blit((wxCoord)(x + (m_width-picwidth)/2),
521 (wxCoord)(y - picheight/2 + m_height/2),
522 picwidth,
523 picheight,
524 &memoryDC,
525 picwidth * (m_pipValue - 11),
526 0,
527 wxCOPY);
528
529 memoryDC.SelectObject(*m_symbolBmap);
530 dc.Blit((wxCoord)(x + m_width-(m_width-picwidth)/2-symsize-3),
531 (wxCoord)(y - picheight/2+m_height/2+1),
532 symsize,
533 symsize,
534 &memoryDC,
535 symsize * m_suit,
536 sympos,
537 wxCOPY);
538 dc.Blit((wxCoord)(x + (m_width-picwidth)/2+2),
539 (wxCoord)(y + picheight/2 + m_height/2-symsize),
540 symsize,
541 symsize,
542 &memoryDC,
543 symsize * m_suit,
544 sympos2,
545 wxCOPY);
546 break;
547 }
548
549 }
550 dc.SetBackground( backgroundBrush );
551 } // Card:Draw()
552
553
554 //+-------------------------------------------------------------+
555 //| Card::DrawNullCard() |
556 //+-------------------------------------------------------------+
557 //| Description: |
558 //| Draws the outline of a card at (x, y). |
559 //| Used to draw place holders for empty piles of cards. |
560 //+-------------------------------------------------------------+
561 void Card::DrawNullCard(wxDC& dc, int x, int y)
562 {
563 wxPen* pen = wxThePenList->FindOrCreatePen(FortyApp::TextColour(), 1, wxSOLID);
564 dc.SetBrush(FortyApp::BackgroundBrush());
565 dc.SetPen(*pen);
566 dc.DrawRoundedRectangle(x, y, m_width, m_height, 4);
567 } // Card::DrawNullCard()
568
569