]> git.saurik.com Git - wxWidgets.git/blob - demos/forty/card.cpp
94df4387328be7ae4de57d507c7ba7f7b0adb5c6
[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 wxWindows 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(x + m_scale*3, y + m_scale*3, valuewidth, valueheight,
257 &memoryDC, valuewidth * (m_pipValue - 1), valuepos, wxCOPY);
258 dc.Blit(x + m_width - m_scale*3 - valuewidth, y + m_height - valueheight - m_scale*3,
259 valuewidth, valueheight,
260 &memoryDC, valuewidth * (m_pipValue - 1), valuepos+valueheight, wxCOPY);
261
262 // Draw the pips
263 dc.Blit(x + m_scale*3 + valuewidth+2, y + m_scale*3, pipsize, pipsize,
264 &memoryDC, pipsize * m_suit, pippos, wxCOPY);
265 dc.Blit(x + m_width - m_scale*3-valuewidth-pipsize-2, y + m_height - pipsize - m_scale*3,
266 pipsize, pipsize,
267 &memoryDC, pipsize * m_suit, pipsize+pippos, wxCOPY);
268
269 switch (m_pipValue)
270 {
271 case 1:
272 dc.Blit(x - symdist + m_width / 2, y - m_scale*5 + m_height / 2, symsize, symsize,
273 &memoryDC, symsize * m_suit, sympos, wxCOPY);
274 break;
275
276 case 3:
277 dc.Blit(x - symdist + m_width / 2, y - symdist + m_height / 2, symsize, symsize,
278 &memoryDC, symsize * m_suit, sympos, wxCOPY);
279 case 2:
280 dc.Blit(x - symdist + m_width / 2,
281 y - symdist + m_height / 4, symsize, symsize,
282 &memoryDC, symsize * m_suit, sympos, wxCOPY);
283 dc.Blit(x - symdist + m_width / 2,
284 y - symdist + 3 * m_height / 4, symsize, symsize,
285 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
286 break;
287
288 case 5:
289 dc.Blit(x - symdist + m_width / 2, y - symdist + m_height / 2, symsize, symsize,
290 &memoryDC, symsize * m_suit, sympos, wxCOPY);
291 case 4:
292 dc.Blit(x - symdist + m_width / 4,
293 y - symdist + m_height / 4, symsize, symsize,
294 &memoryDC, symsize * m_suit, sympos, wxCOPY);
295 dc.Blit(x - symdist + m_width / 4,
296 y - symdist + 3 * m_height / 4, symsize, symsize,
297 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
298 dc.Blit(x - symdist + 3 * m_width / 4,
299 y - symdist + m_height / 4, symsize, symsize,
300 &memoryDC, symsize * m_suit, sympos, wxCOPY);
301 dc.Blit(x - symdist + 3 * m_width / 4,
302 y - symdist + 3 * m_height / 4, symsize, symsize,
303 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
304 break;
305
306 case 8:
307 dc.Blit(x - symdist + 5 * m_width / 10,
308 y - symdist + 5 * m_height / 8, symsize, symsize,
309 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
310 case 7:
311 dc.Blit(x - symdist + 5 * m_width / 10,
312 y - symdist + 3 * m_height / 8, symsize, symsize,
313 &memoryDC, symsize * m_suit, sympos, wxCOPY);
314 case 6:
315 dc.Blit(x - symdist + m_width / 4,
316 y - symdist + m_height / 4, symsize, symsize,
317 &memoryDC, symsize * m_suit, sympos, wxCOPY);
318 dc.Blit(x - symdist + m_width / 4,
319 y - symdist + m_height / 2, symsize, symsize,
320 &memoryDC, symsize * m_suit, sympos, wxCOPY);
321 dc.Blit(x - symdist + m_width / 4,
322 y - symdist + 3 * m_height / 4, symsize, symsize,
323 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
324 dc.Blit(x - symdist + 3 * m_width / 4,
325 y - symdist + m_height / 4, symsize, symsize,
326 &memoryDC, symsize * m_suit, sympos, wxCOPY);
327 dc.Blit(x - symdist + 3 * m_width / 4,
328 y - symdist + m_height / 2, symsize, symsize,
329 &memoryDC, symsize * m_suit, sympos, wxCOPY);
330 dc.Blit(x - symdist + 3 * m_width / 4,
331 y - symdist + 3 * m_height / 4, symsize, symsize,
332 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
333 break;
334
335 case 10:
336 dc.Blit(x - symdist + m_width / 2,
337 y - symdist + 2 * m_height / 3, symsize, symsize,
338 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
339 case 9:
340 dc.Blit(x - symdist + m_width / 4,
341 y - symdist2 + m_height / 4, symsize, symsize,
342 &memoryDC, symsize * m_suit, sympos, wxCOPY);
343 dc.Blit(x - symdist + m_width / 4,
344 y - symdist2 + 5 * m_height / 12, symsize, symsize,
345 &memoryDC, symsize * m_suit, sympos, wxCOPY);
346 dc.Blit(x - symdist + m_width / 4,
347 y - symdist + 7 * m_height / 12, symsize, symsize,
348 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
349 dc.Blit(x - symdist + m_width / 4,
350 y - symdist + 3 * m_height / 4, symsize, symsize,
351 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
352
353 dc.Blit(x - symdist + 3 * m_width / 4,
354 y - symdist2 + m_height / 4, symsize, symsize,
355 &memoryDC, symsize * m_suit, sympos, wxCOPY);
356 dc.Blit(x - symdist + 3 * m_width / 4,
357 y - symdist2 + 5 * m_height / 12, symsize, symsize,
358 &memoryDC, symsize * m_suit, sympos, wxCOPY);
359 dc.Blit(x - symdist + 3 * m_width / 4,
360 y - symdist + 7 * m_height / 12, symsize, symsize,
361 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
362 dc.Blit(x - symdist + 3 * m_width / 4,
363 y - symdist + 3 * m_height / 4, symsize, symsize,
364 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
365 dc.Blit(x - symdist + m_width / 2,
366 y - symdist + m_height / 3, symsize, symsize,
367 &memoryDC, symsize * m_suit, sympos, wxCOPY);
368 break;
369 case 11:
370 case 12:
371 case 13:
372 memoryDC.SelectObject(*m_pictureBmap);
373 int picwidth = 40,picheight = 45;
374 dc.Blit(x + (m_width-picwidth)/2, y - picheight/2 + m_height/2,
375 picwidth, picheight,
376 &memoryDC, picwidth * (m_pipValue - 11), 0, wxCOPY);
377
378 memoryDC.SelectObject(*m_symbolBmap);
379 dc.Blit(x + m_width-(m_width-picwidth)/2-symsize-3,y - picheight/2+m_height/2+1, symsize, symsize,
380 &memoryDC, symsize * m_suit, sympos, wxCOPY);
381 dc.Blit(x + (m_width-picwidth)/2+2,y + picheight/2 + m_height/2-symsize, symsize, symsize,
382 &memoryDC, symsize * m_suit, sympos2, wxCOPY);
383 break;
384 }
385
386 }
387 dc.SetBackground( backgroundBrush );
388 } // Card:Draw()
389
390
391 //+-------------------------------------------------------------+
392 //| Card::DrawNullCard() |
393 //+-------------------------------------------------------------+
394 //| Description: |
395 //| Draws the outline of a card at (x, y). |
396 //| Used to draw place holders for empty piles of cards. |
397 //+-------------------------------------------------------------+
398 void Card::DrawNullCard(wxDC& dc, int x, int y)
399 {
400 wxPen* pen = wxThePenList->FindOrCreatePen(FortyApp::TextColour(), 1, wxSOLID);
401 dc.SetBrush(FortyApp::BackgroundBrush());
402 dc.SetPen(*pen);
403 dc.DrawRoundedRectangle(x, y, m_width, m_height, 4);
404 } // Card::DrawNullCard()
405
406