Removed tabs.
[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::~Card() |
138 //+-------------------------------------------------------------+
139 //| Description: |
140 //| Destructor - nothing to do at present. |
141 //+-------------------------------------------------------------+
142 Card::~Card()
143 {
144 }
145
146
147 //+-------------------------------------------------------------+
148 //| Card::Erase() |
149 //+-------------------------------------------------------------+
150 //| Description: |
151 //| Erase the card at (x, y) by drawing a rectangle in the |
152 //| background colour. |
153 //+-------------------------------------------------------------+
154 void Card::Erase(wxDC& dc, int x, int y)
155 {
156 wxPen* pen = wxThePenList->FindOrCreatePen(
157 FortyApp::BackgroundColour(),
158 1,
159 wxSOLID
160 );
161 dc.SetPen(* pen);
162 dc.SetBrush(FortyApp::BackgroundBrush());
163 dc.DrawRectangle(x, y, m_width, m_height);
164 } // Card::Erase()
165
166
167 //+-------------------------------------------------------------+
168 //| Card::Draw() |
169 //+-------------------------------------------------------------+
170 //| Description: |
171 //| Draw the card at (x, y). |
172 //| If the card is facedown draw the back of the card. |
173 //| If the card is faceup draw the front of the card. |
174 //| Cards are not held in bitmaps, instead they are drawn |
175 //| from their constituent parts when required. |
176 //| hbmap_symbols contains large and small suit symbols and |
177 //| pip values. These are copied to the appropriate part of |
178 //| the card. Picture cards use the pictures defined in |
179 //| hbmap_pictures. Note that only one picture is defined |
180 //| for the Jack, Queen and King, unlike a real pack where |
181 //| each suit is different. |
182 //| |
183 //| WARNING: |
184 //| The locations of these symbols is 'hard-wired' into the |
185 //| code. Editing the bitmaps or the numbers below will |
186 //| result in the wrong symbols being displayed. |
187 //+-------------------------------------------------------------+
188 void Card::Draw(wxDC& dc, int x, int y)
189 {
190 wxBrush backgroundBrush( dc.GetBackground() );
191 dc.SetBrush(* wxWHITE_BRUSH);
192 dc.SetPen(* wxBLACK_PEN);
193 dc.DrawRoundedRectangle(x, y, m_width, m_height, 4);
194 if (m_wayUp == facedown)
195 {
196 dc.SetBackground(* wxRED_BRUSH);
197 dc.SetBackgroundMode(wxSOLID);
198 wxBrush* brush = wxTheBrushList->FindOrCreateBrush(
199 _T("BLACK"), wxCROSSDIAG_HATCH
200 );
201 dc.SetBrush(* brush);
202
203 dc.DrawRoundedRectangle(
204 x + 4, y + 4,
205 m_width - 8, m_height - 8,
206 2
207 );
208 }
209 else
210 {
211 wxMemoryDC memoryDC;
212
213 memoryDC.SelectObject(*m_symbolBmap);
214
215 // dc.SetBackgroundMode(wxTRANSPARENT);
216
217 dc.SetTextBackground(*wxWHITE);
218 switch (m_suit)
219 {
220 case spades:
221 case clubs:
222 dc.SetTextForeground(*wxBLACK);
223 break;
224 case diamonds:
225 case hearts:
226 dc.SetTextForeground(*wxRED);
227 break;
228 }
229
230 int symsize = 11;
231 int sympos = 14;
232 int sympos2 = 25;
233 int symdist = 5;
234 int symdist2 = 6;
235
236 int pipsize,pippos,valueheight,valuewidth;
237 int valuepos;
238 if (m_scale > 1.2)
239 {
240 pipsize = symsize;
241 pippos = sympos;
242 valueheight = 10;
243 valuewidth = 9;
244 valuepos = 50;
245 }
246 else
247 {
248 pipsize = 7;
249 pippos = 0;
250 valueheight = 7;
251 valuewidth = 6;
252 valuepos = 36;
253 }
254
255 // Draw the value
256 dc.Blit((wxCoord)(x + m_scale*3),
257 (wxCoord)(y + m_scale*3),
258 valuewidth,
259 valueheight,
260 &memoryDC,
261 valuewidth * (m_pipValue - 1),
262 valuepos,
263 wxCOPY);
264 dc.Blit((wxCoord)(x + m_width - m_scale*3 - valuewidth),
265 (wxCoord)(y + m_height - valueheight - m_scale*3),
266 valuewidth,
267 valueheight,
268 &memoryDC,
269 valuewidth * (m_pipValue - 1),
270 valuepos+valueheight,
271 wxCOPY);
272
273 // Draw the pips
274 dc.Blit((wxCoord)(x + m_scale*3 + valuewidth+2),
275 (wxCoord)(y + m_scale*3),
276 pipsize,
277 pipsize,
278 &memoryDC,
279 pipsize * m_suit,
280 pippos,
281 wxCOPY);
282 dc.Blit((wxCoord)(x + m_width - m_scale*3-valuewidth-pipsize-2),
283 (wxCoord)(y + m_height - pipsize - m_scale*3),
284 pipsize,
285 pipsize,
286 &memoryDC,
287 pipsize * m_suit,
288 pipsize+pippos,
289 wxCOPY);
290
291 switch (m_pipValue)
292 {
293 case 1:
294 dc.Blit((wxCoord)(x - symdist + m_width / 2),
295 (wxCoord)(y - m_scale*5 + m_height / 2),
296 symsize,
297 symsize,
298 &memoryDC,
299 symsize * m_suit,
300 sympos,
301 wxCOPY);
302 break;
303
304 case 3:
305 dc.Blit((wxCoord)(x - symdist + m_width / 2),
306 (wxCoord)(y - symdist + m_height / 2),
307 symsize,
308 symsize,
309 &memoryDC,
310 symsize * m_suit,
311 sympos,
312 wxCOPY);
313 case 2:
314 dc.Blit((wxCoord)(x - symdist + m_width / 2),
315 (wxCoord)(y - symdist + m_height / 4),
316 symsize,
317 symsize,
318 &memoryDC,
319 symsize * m_suit,
320 sympos,
321 wxCOPY);
322 dc.Blit((wxCoord)(x - symdist + m_width / 2),
323 (wxCoord)(y - symdist + 3 * m_height / 4),
324 symsize,
325 symsize,
326 &memoryDC,
327 symsize * m_suit,
328 sympos2,
329 wxCOPY);
330 break;
331
332 case 5:
333 dc.Blit((wxCoord)(x - symdist + m_width / 2),
334 (wxCoord)(y - symdist + m_height / 2),
335 symsize,
336 symsize,
337 &memoryDC,
338 symsize * m_suit,
339 sympos,
340 wxCOPY);
341 case 4:
342 dc.Blit((wxCoord)(x - symdist + 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 + 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 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
359 (wxCoord)(y - symdist + m_height / 4),
360 symsize,
361 symsize,
362 &memoryDC,
363 symsize * m_suit,
364 sympos,
365 wxCOPY);
366 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
367 (wxCoord)(y - symdist + 3 * m_height / 4),
368 symsize,
369 symsize,
370 &memoryDC,
371 symsize * m_suit,
372 sympos2,
373 wxCOPY);
374 break;
375
376 case 8:
377 dc.Blit((wxCoord)(x - symdist + 5 * m_width / 10),
378 (wxCoord)(y - symdist + 5 * m_height / 8),
379 symsize,
380 symsize,
381 &memoryDC,
382 symsize * m_suit,
383 sympos2,
384 wxCOPY);
385 case 7:
386 dc.Blit((wxCoord)(x - symdist + 5 * m_width / 10),
387 (wxCoord)(y - symdist + 3 * m_height / 8),
388 symsize,
389 symsize,
390 &memoryDC,
391 symsize * m_suit,
392 sympos,
393 wxCOPY);
394 case 6:
395 dc.Blit((wxCoord)(x - symdist + m_width / 4),
396 (wxCoord)(y - symdist + m_height / 4),
397 symsize,
398 symsize,
399 &memoryDC, symsize * m_suit, sympos, wxCOPY);
400 dc.Blit((wxCoord)(x - symdist + m_width / 4),
401 (wxCoord)(y - symdist + m_height / 2),
402 symsize,
403 symsize,
404 &memoryDC,
405 symsize * m_suit,
406 sympos,
407 wxCOPY);
408 dc.Blit((wxCoord)(x - symdist + m_width / 4),
409 (wxCoord)(y - symdist + 3 * m_height / 4),
410 symsize,
411 symsize,
412 &memoryDC,
413 symsize * m_suit,
414 sympos2,
415 wxCOPY);
416 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
417 (wxCoord)(y - symdist + m_height / 4),
418 symsize,
419 symsize,
420 &memoryDC,
421 symsize * m_suit,
422 sympos,
423 wxCOPY);
424 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
425 (wxCoord)(y - symdist + m_height / 2),
426 symsize,
427 symsize,
428 &memoryDC,
429 symsize * m_suit,
430 sympos,
431 wxCOPY);
432 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
433 (wxCoord)(y - symdist + 3 * m_height / 4),
434 symsize,
435 symsize,
436 &memoryDC,
437 symsize * m_suit,
438 sympos2,
439 wxCOPY);
440 break;
441
442 case 10:
443 dc.Blit((wxCoord)(x - symdist + m_width / 2),
444 (wxCoord)(y - symdist + 2 * m_height / 3),
445 symsize,
446 symsize,
447 &memoryDC,
448 symsize * m_suit,
449 sympos2,
450 wxCOPY);
451 case 9:
452 dc.Blit((wxCoord)(x - symdist + m_width / 4),
453 (wxCoord)(y - symdist2 + m_height / 4),
454 symsize,
455 symsize,
456 &memoryDC,
457 symsize * m_suit,
458 sympos,
459 wxCOPY);
460 dc.Blit((wxCoord)(x - symdist + m_width / 4),
461 (wxCoord)(y - symdist2 + 5 * m_height / 12),
462 symsize,
463 symsize,
464 &memoryDC,
465 symsize * m_suit,
466 sympos,
467 wxCOPY);
468 dc.Blit((wxCoord)(x - symdist + m_width / 4),
469 (wxCoord)(y - symdist + 7 * m_height / 12),
470 symsize,
471 symsize,
472 &memoryDC,
473 symsize * m_suit,
474 sympos2,
475 wxCOPY);
476 dc.Blit((wxCoord)(x - symdist + m_width / 4),
477 (wxCoord)(y - symdist + 3 * m_height / 4),
478 symsize,
479 symsize,
480 &memoryDC,
481 symsize * m_suit,
482 sympos2,
483 wxCOPY);
484
485 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
486 (wxCoord)(y - symdist2 + m_height / 4),
487 symsize,
488 symsize,
489 &memoryDC,
490 symsize * m_suit,
491 sympos,
492 wxCOPY);
493 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
494 (wxCoord)(y - symdist2 + 5 * m_height / 12),
495 symsize,
496 symsize,
497 &memoryDC,
498 symsize * m_suit,
499 sympos,
500 wxCOPY);
501 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
502 (wxCoord)(y - symdist + 7 * m_height / 12),
503 symsize,
504 symsize,
505 &memoryDC,
506 symsize * m_suit,
507 sympos2,
508 wxCOPY);
509 dc.Blit((wxCoord)(x - symdist + 3 * m_width / 4),
510 (wxCoord)(y - symdist + 3 * m_height / 4),
511 symsize,
512 symsize,
513 &memoryDC,
514 symsize * m_suit,
515 sympos2,
516 wxCOPY);
517 dc.Blit((wxCoord)(x - symdist + m_width / 2),
518 (wxCoord)(y - symdist + m_height / 3),
519 symsize,
520 symsize,
521 &memoryDC,
522 symsize * m_suit,
523 sympos,
524 wxCOPY);
525 break;
526 case 11:
527 case 12:
528 case 13:
529 memoryDC.SelectObject(*m_pictureBmap);
530 int picwidth = 40,picheight = 45;
531 dc.Blit((wxCoord)(x + (m_width-picwidth)/2),
532 (wxCoord)(y - picheight/2 + m_height/2),
533 picwidth,
534 picheight,
535 &memoryDC,
536 picwidth * (m_pipValue - 11),
537 0,
538 wxCOPY);
539
540 memoryDC.SelectObject(*m_symbolBmap);
541 dc.Blit((wxCoord)(x + m_width-(m_width-picwidth)/2-symsize-3),
542 (wxCoord)(y - picheight/2+m_height/2+1),
543 symsize,
544 symsize,
545 &memoryDC,
546 symsize * m_suit,
547 sympos,
548 wxCOPY);
549 dc.Blit((wxCoord)(x + (m_width-picwidth)/2+2),
550 (wxCoord)(y + picheight/2 + m_height/2-symsize),
551 symsize,
552 symsize,
553 &memoryDC,
554 symsize * m_suit,
555 sympos2,
556 wxCOPY);
557 break;
558 }
559
560 }
561 dc.SetBackground( backgroundBrush );
562 } // Card:Draw()
563
564
565 //+-------------------------------------------------------------+
566 //| Card::DrawNullCard() |
567 //+-------------------------------------------------------------+
568 //| Description: |
569 //| Draws the outline of a card at (x, y). |
570 //| Used to draw place holders for empty piles of cards. |
571 //+-------------------------------------------------------------+
572 void Card::DrawNullCard(wxDC& dc, int x, int y)
573 {
574 wxPen* pen = wxThePenList->FindOrCreatePen(FortyApp::TextColour(), 1, wxSOLID);
575 dc.SetBrush(FortyApp::BackgroundBrush());
576 dc.SetPen(*pen);
577 dc.DrawRoundedRectangle(x, y, m_width, m_height, 4);
578 } // Card::DrawNullCard()
579
580