summaryrefslogtreecommitdiff
path: root/noncore/games/solitaire/canvascard.cpp
Unidiff
Diffstat (limited to 'noncore/games/solitaire/canvascard.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/solitaire/canvascard.cpp282
1 files changed, 282 insertions, 0 deletions
diff --git a/noncore/games/solitaire/canvascard.cpp b/noncore/games/solitaire/canvascard.cpp
new file mode 100644
index 0000000..ae3c859
--- a/dev/null
+++ b/noncore/games/solitaire/canvascard.cpp
@@ -0,0 +1,282 @@
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 "canvascard.h"
23
24#include <qpe/resource.h>
25
26#include <qpainter.h>
27#include <qimage.h>
28#include <qpaintdevice.h>
29#include <qbitmap.h>
30
31#include <math.h>
32
33#if defined( QT_QWS_CASSIOPEIA )
34#define SLOW_HARDWARE
35#endif
36
37// Seems to be fast enough to me even without Transformations in the library
38//#if defined( QT_NO_TRANSFORMATIONS ) && defined( QT_QWS_IPAQ )
39//#define SLOW_HARDWARE
40//#endif
41
42
43QBitmap *Create180RotatedBitmap(QBitmap *srcBitmap)
44{
45#ifdef QT_NO_TRANSFORMATIONS
46 int w = srcBitmap->width();
47 int h = srcBitmap->height();
48 QBitmap *dstBitmap = new QBitmap( w, h );
49 // ### this is very poorly implemented and probably could be much faster
50 for (int i = 0; i < w; i++)
51 for (int j = 0; j < h; j++)
52 bitBlt( dstBitmap, i, j, srcBitmap, w - i - 1, h - j - 1, 1, 1 );
53 return dstBitmap;
54#else
55 QWMatrix m;
56 m.rotate( 180.0 );
57 return new QBitmap( srcBitmap->xForm( m ) );
58#endif
59}
60
61
62QPixmap *CreateScaledPixmap(QPixmap *srcPixmap, double scaleX, double scaleY)
63{
64#ifdef QT_NO_TRANSFORMATIONS
65 int w = srcPixmap->width();
66 int h = srcPixmap->height();
67 int newW = (int)(w * scaleX);
68 int newH = (int)(h * scaleY);
69 QPixmap *dstPixmap = new QPixmap( newW, newH );
70 // ### this is very poorly implemented and probably could be much faster
71 for (int i = 0; i < newW; i++) {
72 int srcX = w * i / newW;
73 if (newH == h) {
74 // Optimise for scaleing in the X-axis only
75 bitBlt( dstPixmap, i, 0, srcPixmap, srcX, 0, 1, h );
76 } else {
77 for (int j = 0; j < newH; j++) {
78 int srcY = h * j / newH;
79 bitBlt( dstPixmap, i, j, srcPixmap, srcX, srcY, 1, 1 );
80 }
81 }
82 }
83 return dstPixmap;
84#else
85 QWMatrix s;
86 s.scale( scaleX, scaleY );
87 return new QPixmap( srcPixmap->xForm( s ) );
88#endif
89}
90
91
92// Initialise static member variables to NULL
93QPixmap *CanvasCard::cardsFaces = NULL;
94QPixmap *CanvasCard::cardsBacks = NULL;
95QBitmap *CanvasCard::cardsChars = NULL;
96QBitmap *CanvasCard::cardsSuits = NULL;
97QBitmap *CanvasCard::cardsCharsUpsideDown = NULL;
98QBitmap *CanvasCard::cardsSuitsUpsideDown = NULL;
99
100
101CanvasCard::CanvasCard( eValue v, eSuit s, bool f, QCanvas *canvas ) :
102 Card(v, s, f), QCanvasRectangle( 0, 0, 1, 1, canvas ), cardBack(1), scaleX(1.0), scaleY(1.0)
103{
104 if ( !cardsFaces ) {
105 cardsFaces = new QPixmap( Resource::loadPixmap( "cards/card_face" ) );
106 cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0001" ) );
107 cardsChars = new QBitmap( Resource::loadBitmap( "cards/card_chars" ) );
108 cardsSuits = new QBitmap( Resource::loadBitmap( "cards/card_suits" ) );
109 cardsCharsUpsideDown = Create180RotatedBitmap( cardsChars );
110 cardsSuitsUpsideDown = Create180RotatedBitmap( cardsSuits );
111 }
112 xOff = cardsFaces->width() / 2;
113 yOff = cardsFaces->height() / 2;
114 setSize( cardsFaces->width(), cardsFaces->height() );
115 setPen( NoPen );
116 flipping = FALSE;
117}
118
119
120void CanvasCard::setCardBack(int b)
121{
122 if ( cardBack != b ) {
123
124 cardBack = b;
125
126 if ( cardsBacks )
127 delete cardsBacks;
128
129 switch (cardBack) {
130 case 0:
131 cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0001" ) ); break;
132 case 1:
133 cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0002" ) ); break;
134 case 2:
135 cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0003" ) ); break;
136 case 3:
137 cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0004" ) ); break;
138 case 4:
139 cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0005" ) ); break;
140 }
141
142 if ( !isFacing() )
143 redraw();
144 }
145}
146
147
148void CanvasCard::draw(QPainter &painter)
149{
150 int ix = (int)x(), iy = (int)y();
151
152 QPainter *p = &painter;
153 QPixmap *unscaledCard = NULL;
154
155 if ((scaleX <= 0.98) || (scaleY <= 0.98))
156 {
157 p = new QPainter();
158 unscaledCard = new QPixmap( cardsFaces->width(), cardsFaces->height() );
159 p->begin(unscaledCard);
160 ix = 0;
161 iy = 0;
162 }
163
164 if ( isFacing() ) {
165
166/*
167 // Now add the joker and card backs to the list of pixmaps
168 QPixmap *CardsBack = new QPixmap( Resource::loadPixmap( "cards/card_joker.png" ) );
169 QPoint *newBackHotspot = new QPoint( 0, 0 );
170 pixmaps->append((const QPixmap *)CardsBack);
171 hotspots->append((const QPoint *)newBackHotspot);
172*/
173
174 int w = cardsFaces->width(), h = cardsFaces->height();
175
176 //p->setBrush( NoBrush );
177 p->setBrush( QColor( 0xFF, 0xFF, 0xFF ) );
178
179 if ( isRed() == TRUE )
180 p->setPen( QColor( 0xFF, 0, 0 ) );
181 else
182 p->setPen( QColor( 0, 0, 0 ) );
183
184 p->drawPixmap( ix + 0, iy + 0, *cardsFaces );
185 p->drawPixmap( ix + 4, iy + 4, *cardsChars, 7*(getValue()-1), 0, 7, 7 );
186 p->drawPixmap( ix + 12, iy + 4, *cardsSuits, 7*(getSuit()-1), 0, 7, 8 );
187 p->drawPixmap( ix + w-4-7, iy + h-4-7, *cardsCharsUpsideDown, 7*(12-getValue()+1), 0, 7, 7 );
188 p->drawPixmap( ix + w-12-7, iy + h-5-7, *cardsSuitsUpsideDown, 7*(3-getSuit()+1), 0, 7, 8 );
189
190 } else {
191
192 p->drawPixmap( ix, iy, *cardsBacks );
193
194 }
195
196 if (p != &painter)
197 {
198 p->end();
199 QPixmap *scaledCard = CreateScaledPixmap( unscaledCard, scaleX, scaleY );
200 int xoff = scaledCard->width() / 2;
201 int yoff = scaledCard->height() / 2;
202 painter.drawPixmap( (int)x() + xOff - xoff, (int)y() + yOff - yoff, *scaledCard );
203 delete p;
204 delete unscaledCard;
205 delete scaledCard;
206 }
207}
208
209
210static const double flipLift = 1.5;
211
212
213void CanvasCard::flipTo(int x2, int y2, int steps)
214{
215 flipSteps = steps;
216
217#ifdef SLOW_HARDWARE
218 move(x2,y2);
219 Card::flipTo(x2,y2,steps);
220#else
221 int x1 = (int)x();
222 int y1 = (int)y();
223 double dx = x2 - x1;
224 double dy = y2 - y1;
225
226 flipping = TRUE;
227 destX = x2;
228 destY = y2;
229 animSteps = flipSteps;
230 setVelocity(dx/animSteps, dy/animSteps-flipLift);
231 setAnimated(TRUE);
232#endif
233}
234
235
236void CanvasCard::advance(int stage)
237{
238 if ( stage==1 ) {
239 if ( animSteps-- <= 0 ) {
240 scaleX = 1.0;
241 scaleY = 1.0;
242 flipping = FALSE;
243 setVelocity(0,0);
244 setAnimated(FALSE);
245 move(destX,destY); // exact
246 } else {
247 if ( flipping ) {
248 if ( animSteps > flipSteps / 2 ) {
249 // animSteps = flipSteps .. flipSteps/2 (flip up) -> 1..0
250 scaleX = ((double)animSteps/flipSteps-0.5)*2;
251 } else {
252 // animSteps = flipSteps/2 .. 0 (flip down) -> 0..1
253 scaleX = 1-((double)animSteps/flipSteps)*2;
254 }
255 if ( animSteps == flipSteps / 2-1 ) {
256 setYVelocity(yVelocity()+flipLift*2);
257 setFace( !isFacing() );
258 }
259 }
260 }
261 }
262 QCanvasRectangle::advance(stage);
263}
264
265
266void CanvasCard::animatedMove(int x2, int y2, int steps)
267{
268 destX = x2;
269 destY = y2;
270
271 double x1 = x(), y1 = y(), dx = x2 - x1, dy = y2 - y1;
272
273 // Ensure a good speed
274 while ( fabs(dx/steps)+fabs(dy/steps) < 5.0 && steps > 4 )
275 steps--;
276
277 setAnimated(TRUE);
278 setVelocity(dx/steps, dy/steps);
279
280 animSteps = steps;
281}
282