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