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