summaryrefslogtreecommitdiff
path: root/noncore/games/solitaire/canvascardgame.cpp
Unidiff
Diffstat (limited to 'noncore/games/solitaire/canvascardgame.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/solitaire/canvascardgame.cpp380
1 files changed, 380 insertions, 0 deletions
diff --git a/noncore/games/solitaire/canvascardgame.cpp b/noncore/games/solitaire/canvascardgame.cpp
new file mode 100644
index 0000000..32635a0
--- a/dev/null
+++ b/noncore/games/solitaire/canvascardgame.cpp
@@ -0,0 +1,380 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "cardgame.h"
22#include "canvasshapes.h"
23#include "canvascard.h"
24#include "canvascardgame.h"
25
26#include <qpe/resource.h>
27#include <qpe/config.h>
28
29#include <qmainwindow.h>
30#include <qpe/qpemenubar.h>
31#include <qpainter.h>
32
33#include <stdlib.h>
34#include <limits.h>
35#include <time.h>
36#include <math.h>
37
38
39extern int highestZ;
40
41
42class CanvasCardPile : public QCanvasRectangle
43{
44public:
45 CanvasCardPile( CanvasCardGame *ccg, QCanvas *canvas ) : QCanvasRectangle( canvas ), parent( ccg ) {
46 pile = new QPixmap( 0, 0 );
47 pileHeight = 0;
48 firstCard = NULL;
49 }
50
51 void addCard( CanvasCard *card );
52 void advance(int stage);
53 void animatedMove() { animatedMove(savedX, savedY); }
54 void savePos(void) { savedX = (int)x(); savedY = (int)y(); }
55 void animatedMove(int x2, int y2, int steps = 7 );
56
57protected:
58 virtual void draw( QPainter& p );
59
60private:
61 CanvasCardGame *parent;
62 QPixmap *pile;
63 QImage tempImage32;
64 CanvasCard *firstCard;
65 int pileHeight;
66 int destX, destY;
67 int savedX, savedY;
68 int animSteps;
69};
70
71
72void CanvasCardPile::addCard( CanvasCard *card )
73{
74 if ( !firstCard )
75 firstCard = card;
76
77 int height = 36 + pileHeight * 13;
78 setSize( 23, height );
79 pile->resize( 23, height );
80 QPainter p( pile );
81 p.translate( -card->x(), -card->y() + pileHeight * 13 );
82 card->draw( p );
83 pileHeight++;
84
85 QImage tempImage;
86 tempImage = *pile;
87 tempImage32 = tempImage.convertDepth( 32 );
88 tempImage32.setAlphaBuffer( TRUE );
89 for ( int i = 0; i < tempImage32.width(); i++ )
90 for ( int j = 0; j < tempImage32.height(); j++ ) {
91 QRgb col = tempImage32.pixel( i, j );
92 int a = 255-j*220/tempImage32.height();
93 QRgb alpha = qRgba( qRed( col ), qGreen( col ), qBlue( col ), a );
94 tempImage32.setPixel( i, j, alpha );
95 }
96
97 QRgb alpha = qRgba( 0, 0, 0, 0 );
98 tempImage32.setPixel( 1, 0, alpha );
99 tempImage32.setPixel( 0, 0, alpha );
100 tempImage32.setPixel( 0, 1, alpha );
101
102 tempImage32.setPixel( 21, 0, alpha );
103 tempImage32.setPixel( 22, 0, alpha );
104 tempImage32.setPixel( 22, 1, alpha );
105 height--;
106 tempImage32.setPixel( 1, height, alpha );
107 tempImage32.setPixel( 0, height - 1, alpha );
108 tempImage32.setPixel( 0, height, alpha );
109
110 tempImage32.setPixel( 21, height, alpha );
111 tempImage32.setPixel( 22, height, alpha );
112 tempImage32.setPixel( 22, height - 1, alpha );
113}
114
115
116void CanvasCardPile::advance(int stage)
117{
118 if ( stage==1 ) {
119 if ( animSteps-- <= 0 ) {
120 CanvasCard *item = firstCard;
121 while (item) {
122 item->show();
123 item = (CanvasCard *)item->getCardPile()->cardInfront(item);
124 }
125 setVelocity(0,0);
126 setAnimated(FALSE);
127 parent->cancelMoving();
128 hide();
129 move(destX,destY); // exact
130 }
131 }
132 QCanvasRectangle::advance(stage);
133}
134
135
136void CanvasCardPile::animatedMove(int x2, int y2, int steps = 7 )
137{
138 destX = x2;
139 destY = y2;
140
141 double x1 = x(), y1 = y(), dx = x2 - x1, dy = y2 - y1;
142
143 // Ensure a good speed
144 while ( fabs(dx/steps)+fabs(dy/steps) < 5.0 && steps > 4 )
145 steps--;
146
147 setAnimated(TRUE);
148 setVelocity(dx/steps, dy/steps);
149
150 animSteps = steps;
151}
152
153
154void CanvasCardPile::draw( QPainter& p )
155{
156 int ix = (int)x(), iy = (int)y();
157 p.drawImage( ix, iy, tempImage32 );
158}
159
160
161CanvasCardGame::~CanvasCardGame() {
162 // the deletion stuff should be fixed now and only deletes
163 // items created by this CardGame. I haven't verified there are zero
164 // memory leaks yet
165 if ( alphaCardPile )
166 delete alphaCardPile;
167}
168
169
170void CanvasCardGame::gameWon() {
171
172 srand(time(NULL));
173
174 QCanvasItemList list = canvas()->allItems();
175 QCanvasItemList::Iterator it = list.begin();
176
177 for (; it != list.end(); ++it) {
178 if ( (*it)->rtti() == canvasCardId ) {
179 // disperse the cards everywhere
180 int x = 300 - rand() % 1000;
181 int y = 300 + rand() % 200;
182 ((CanvasCard *)*it)->animatedMove( x, y, 50 );
183 }
184 }
185}
186
187
188void CanvasCardGame::contentsMousePressEvent(QMouseEvent *e) {
189
190 if ( moving )
191 return;
192
193 QCanvasItemList l = canvas()->collisions( e->pos() );
194
195 for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
196
197 if ( (*it)->rtti() == canvasCardId ) {
198
199 moving = (CanvasCard *)*it;
200
201 if ( moving->animated() )
202 return;
203
204 cardXOff = (int)(e->pos().x() - moving->x());
205 cardYOff = (int)(e->pos().y() - moving->y());
206
207 if ( !mousePressCard( moving, e->pos() ) ) {
208 CanvasCard *card = moving;
209
210 if ( alphaCardPile )
211 delete alphaCardPile;
212
213 alphaCardPile = new CanvasCardPile( this, canvas() );
214 alphaCardPile->move( card->x(), card->y() );
215 alphaCardPile->savePos();
216 alphaCardPile->show();
217
218 while (card) {
219 alphaCardPile->addCard( card );
220 card->hide();
221 card = (CanvasCard *)card->getCardPile()->cardInfront(card);
222 }
223
224 alphaCardPile->setZ( INT_MAX );
225
226 moved = TRUE;
227 } else {
228 if ( alphaCardPile )
229 alphaCardPile->hide();
230 }
231 return;
232 }
233 }
234
235 mousePress( e->pos() );
236}
237
238/*
239//
240// Should have some intelligent way to make double clicking on a
241// card send it to the most appropriate pile
242//
243void CanvasCardGame::contentsMouseDoubleClickEvent(QMouseEvent *e) {
244 QCanvasItemList l = canvas()->collisions( e->pos() );
245 for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
246 if ( (*it)->rtti() == canvasCardId ) {
247 CanvasCard *card = (CanvasCard *)*it;
248
249 if ( card->animated() )
250 return;
251
252 if ( card->getCardPile()->isAllowedToBeMoved(card) ) {
253 if (card->getCardPile()->cardInfront(card) == NULL) {
254 CardPile *pile = first();
255 if (pile && pile->isAllowedOnTop(card)) {
256 // move card to this pile
257 return;
258 }
259 }
260 }
261 }
262 }
263}
264*/
265
266void CanvasCardGame::contentsMouseMoveEvent(QMouseEvent *e) {
267
268 QPoint p = e->pos();
269
270 if ( moving ) {
271
272 moved = TRUE;
273
274 if (moving->isFacing() != TRUE)
275 return;
276
277 int tx = (int)p.x() - cardXOff;
278 int ty = (int)p.y() - cardYOff;
279
280 if (snapOn == TRUE) {
281 CardPile *pile = closestPile( tx, ty, 50 );
282 if ( pile && pile->isAllowedOnTop( moving ) ) {
283 QPoint p = pile->getHypertheticalNextCardPos();
284 if ( alphaCardPile )
285 alphaCardPile->move( p.x(), p.y() );
286 return;
287 }
288 }
289
290 if ( alphaCardPile )
291 alphaCardPile->move( tx, ty );
292 }
293
294}
295
296
297void CanvasCardGame::contentsMouseReleaseEvent(QMouseEvent *e)
298{
299 QPoint p = e->pos();
300
301 Q_UNUSED(p);
302
303 if ( moving ) {
304
305 CanvasCard *item = moving;
306
307 if ( item->animated() )
308 return;
309
310 if ( alphaCardPile )
311 if ( moved ) {
312
313 CardPile *pile = closestPile((int)alphaCardPile->x(), (int)alphaCardPile->y(), 30);
314
315 if (pile && pile->isAllowedOnTop(item)) {
316 CardPile *oldPile = item->getCardPile();
317 Card *c = NULL;
318 if ( oldPile != pile) {
319 while ( item ) {
320 item->show();
321 if ( oldPile ) {
322 c = oldPile->cardInfront(item);
323 oldPile->removeCard(item);
324 }
325 pile->addCardToTop(item);
326 item->setCardPile(pile);
327 //item->move( pile->getCardPos(item) );
328 QPoint p = pile->getCardPos(item);
329 item->setPos( p.x(), p.y(), highestZ );
330 highestZ++;
331
332 if (item->getValue() == king && haveWeWon()) {
333 alphaCardPile->hide();
334 gameWon();
335 moving = NULL;
336 return;
337 }
338
339 if (oldPile) {
340 item = (CanvasCard *)c;
341 } else {
342 item = NULL;
343 }
344 }
345 alphaCardPile->hide();
346 moving = NULL;
347 return;
348 }
349 }
350
351 alphaCardPile->animatedMove();
352 }
353 }
354
355 moved = FALSE;
356}
357
358
359void CanvasCardGame::readPile( Config& cfg, CardPile *pile, QString name, int& highestZ )
360{
361 cfg.setGroup( name );
362 int numberOfCards = cfg.readNumEntry("NumberOfCards", 0);
363 Card *card = NULL;
364 for ( int i = 0; i < numberOfCards; i++ ) {
365 QString cardStr;
366 cardStr.sprintf( "%i", i );
367 int val = cfg.readNumEntry( "Card" + cardStr );
368 bool facing = cfg.readBoolEntry( "CardFacing" + cardStr );
369 card = cards[ val ];
370 card->setFace(facing);
371 pile->addCardToTop(card);
372 card->setCardPile(pile);
373 QPoint p = pile->getCardPos( card );
374 card->setPos( p.x(), p.y(), highestZ );
375 card->showCard();
376 highestZ++;
377 }
378}
379
380