summaryrefslogtreecommitdiff
path: root/noncore/games/solitaire
Side-by-side diff
Diffstat (limited to 'noncore/games/solitaire') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/solitaire/.cvsignore3
-rw-r--r--noncore/games/solitaire/Makefile.in235
-rw-r--r--noncore/games/solitaire/canvascard.cpp282
-rw-r--r--noncore/games/solitaire/canvascard.h82
-rw-r--r--noncore/games/solitaire/canvascardgame.cpp380
-rw-r--r--noncore/games/solitaire/canvascardgame.h95
-rw-r--r--noncore/games/solitaire/canvascardwindow.cpp227
-rw-r--r--noncore/games/solitaire/canvascardwindow.h70
-rw-r--r--noncore/games/solitaire/canvasshapes.cpp92
-rw-r--r--noncore/games/solitaire/canvasshapes.h55
-rw-r--r--noncore/games/solitaire/card.cpp53
-rw-r--r--noncore/games/solitaire/card.h84
-rw-r--r--noncore/games/solitaire/carddeck.cpp81
-rw-r--r--noncore/games/solitaire/carddeck.h49
-rw-r--r--noncore/games/solitaire/cardgame.cpp35
-rw-r--r--noncore/games/solitaire/cardgame.h45
-rw-r--r--noncore/games/solitaire/cardgamelayout.cpp61
-rw-r--r--noncore/games/solitaire/cardgamelayout.h42
-rw-r--r--noncore/games/solitaire/cardpile.cpp114
-rw-r--r--noncore/games/solitaire/cardpile.h101
-rw-r--r--noncore/games/solitaire/freecellcardgame.cpp137
-rw-r--r--noncore/games/solitaire/freecellcardgame.h152
-rw-r--r--noncore/games/solitaire/main.cpp36
-rw-r--r--noncore/games/solitaire/patiencecardgame.cpp234
-rw-r--r--noncore/games/solitaire/patiencecardgame.h206
-rw-r--r--noncore/games/solitaire/qpe-solitaire.control9
-rwxr-xr-xnoncore/games/solitaire/solitaire.pro18
27 files changed, 2978 insertions, 0 deletions
diff --git a/noncore/games/solitaire/.cvsignore b/noncore/games/solitaire/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/noncore/games/solitaire/.cvsignore
@@ -0,0 +1,3 @@
+moc_*
+*.moc
+Makefile
diff --git a/noncore/games/solitaire/Makefile.in b/noncore/games/solitaire/Makefile.in
new file mode 100644
index 0000000..3c50345
--- a/dev/null
+++ b/noncore/games/solitaire/Makefile.in
@@ -0,0 +1,235 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = patience
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = canvascard.h \
+ canvasshapes.h \
+ cardgame.h \
+ cardgamelayout.h \
+ cardpile.h \
+ card.h \
+ carddeck.h \
+ canvascardgame.h \
+ freecellcardgame.h \
+ patiencecardgame.h \
+ canvascardwindow.h
+SOURCES = canvascard.cpp \
+ canvasshapes.cpp \
+ cardgame.cpp \
+ cardgamelayout.cpp \
+ cardpile.cpp \
+ card.cpp \
+ carddeck.cpp \
+ canvascardgame.cpp \
+ freecellcardgame.cpp \
+ patiencecardgame.cpp \
+ canvascardwindow.cpp \
+ main.cpp
+OBJECTS = canvascard.o \
+ canvasshapes.o \
+ cardgame.o \
+ cardgamelayout.o \
+ cardpile.o \
+ card.o \
+ carddeck.o \
+ canvascardgame.o \
+ freecellcardgame.o \
+ patiencecardgame.o \
+ canvascardwindow.o \
+ main.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_canvascardwindow.cpp
+OBJMOC = moc_canvascardwindow.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake solitaire.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=patience
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+canvascard.o: canvascard.cpp \
+ cardgame.h \
+ card.h \
+ cardpile.h \
+ carddeck.h \
+ cardgamelayout.h \
+ canvascard.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+canvasshapes.o: canvasshapes.cpp \
+ canvasshapes.h
+
+cardgame.o: cardgame.cpp \
+ cardgame.h \
+ card.h \
+ cardpile.h \
+ carddeck.h \
+ cardgamelayout.h
+
+cardgamelayout.o: cardgamelayout.cpp \
+ cardgamelayout.h \
+ cardpile.h
+
+cardpile.o: cardpile.cpp \
+ cardpile.h \
+ card.h \
+ $(QPEDIR)/include/qpe/config.h
+
+card.o: card.cpp \
+ card.h \
+ $(QPEDIR)/include/qpe/config.h
+
+carddeck.o: carddeck.cpp \
+ card.h \
+ carddeck.h
+
+canvascardgame.o: canvascardgame.cpp \
+ cardgame.h \
+ card.h \
+ cardpile.h \
+ carddeck.h \
+ cardgamelayout.h \
+ canvasshapes.h \
+ canvascard.h \
+ canvascardgame.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h
+
+freecellcardgame.o: freecellcardgame.cpp \
+ freecellcardgame.h \
+ patiencecardgame.h \
+ canvascardgame.h \
+ cardgame.h \
+ card.h \
+ cardpile.h \
+ carddeck.h \
+ cardgamelayout.h \
+ canvasshapes.h \
+ canvascard.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h
+
+patiencecardgame.o: patiencecardgame.cpp \
+ patiencecardgame.h \
+ canvascardgame.h \
+ cardgame.h \
+ card.h \
+ cardpile.h \
+ carddeck.h \
+ cardgamelayout.h \
+ canvasshapes.h \
+ canvascard.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h
+
+canvascardwindow.o: canvascardwindow.cpp \
+ canvascardwindow.h \
+ patiencecardgame.h \
+ canvascardgame.h \
+ cardgame.h \
+ card.h \
+ cardpile.h \
+ carddeck.h \
+ cardgamelayout.h \
+ canvasshapes.h \
+ canvascard.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h \
+ freecellcardgame.h
+
+main.o: main.cpp \
+ canvascardwindow.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+moc_canvascardwindow.o: moc_canvascardwindow.cpp \
+ canvascardwindow.h
+
+moc_canvascardwindow.cpp: canvascardwindow.h
+ $(MOC) canvascardwindow.h -o moc_canvascardwindow.cpp
+
+
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "cardgame.h"
+#include "canvascard.h"
+
+#include <qpe/resource.h>
+
+#include <qpainter.h>
+#include <qimage.h>
+#include <qpaintdevice.h>
+#include <qbitmap.h>
+
+#include <math.h>
+
+#if defined( QT_QWS_CASSIOPEIA )
+#define SLOW_HARDWARE
+#endif
+
+// Seems to be fast enough to me even without Transformations in the library
+//#if defined( QT_NO_TRANSFORMATIONS ) && defined( QT_QWS_IPAQ )
+//#define SLOW_HARDWARE
+//#endif
+
+
+QBitmap *Create180RotatedBitmap(QBitmap *srcBitmap)
+{
+#ifdef QT_NO_TRANSFORMATIONS
+ int w = srcBitmap->width();
+ int h = srcBitmap->height();
+ QBitmap *dstBitmap = new QBitmap( w, h );
+ // ### this is very poorly implemented and probably could be much faster
+ for (int i = 0; i < w; i++)
+ for (int j = 0; j < h; j++)
+ bitBlt( dstBitmap, i, j, srcBitmap, w - i - 1, h - j - 1, 1, 1 );
+ return dstBitmap;
+#else
+ QWMatrix m;
+ m.rotate( 180.0 );
+ return new QBitmap( srcBitmap->xForm( m ) );
+#endif
+}
+
+
+QPixmap *CreateScaledPixmap(QPixmap *srcPixmap, double scaleX, double scaleY)
+{
+#ifdef QT_NO_TRANSFORMATIONS
+ int w = srcPixmap->width();
+ int h = srcPixmap->height();
+ int newW = (int)(w * scaleX);
+ int newH = (int)(h * scaleY);
+ QPixmap *dstPixmap = new QPixmap( newW, newH );
+ // ### this is very poorly implemented and probably could be much faster
+ for (int i = 0; i < newW; i++) {
+ int srcX = w * i / newW;
+ if (newH == h) {
+ // Optimise for scaleing in the X-axis only
+ bitBlt( dstPixmap, i, 0, srcPixmap, srcX, 0, 1, h );
+ } else {
+ for (int j = 0; j < newH; j++) {
+ int srcY = h * j / newH;
+ bitBlt( dstPixmap, i, j, srcPixmap, srcX, srcY, 1, 1 );
+ }
+ }
+ }
+ return dstPixmap;
+#else
+ QWMatrix s;
+ s.scale( scaleX, scaleY );
+ return new QPixmap( srcPixmap->xForm( s ) );
+#endif
+}
+
+
+// Initialise static member variables to NULL
+QPixmap *CanvasCard::cardsFaces = NULL;
+QPixmap *CanvasCard::cardsBacks = NULL;
+QBitmap *CanvasCard::cardsChars = NULL;
+QBitmap *CanvasCard::cardsSuits = NULL;
+QBitmap *CanvasCard::cardsCharsUpsideDown = NULL;
+QBitmap *CanvasCard::cardsSuitsUpsideDown = NULL;
+
+
+CanvasCard::CanvasCard( eValue v, eSuit s, bool f, QCanvas *canvas ) :
+ Card(v, s, f), QCanvasRectangle( 0, 0, 1, 1, canvas ), cardBack(1), scaleX(1.0), scaleY(1.0)
+{
+ if ( !cardsFaces ) {
+ cardsFaces = new QPixmap( Resource::loadPixmap( "cards/card_face" ) );
+ cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0001" ) );
+ cardsChars = new QBitmap( Resource::loadBitmap( "cards/card_chars" ) );
+ cardsSuits = new QBitmap( Resource::loadBitmap( "cards/card_suits" ) );
+ cardsCharsUpsideDown = Create180RotatedBitmap( cardsChars );
+ cardsSuitsUpsideDown = Create180RotatedBitmap( cardsSuits );
+ }
+ xOff = cardsFaces->width() / 2;
+ yOff = cardsFaces->height() / 2;
+ setSize( cardsFaces->width(), cardsFaces->height() );
+ setPen( NoPen );
+ flipping = FALSE;
+}
+
+
+void CanvasCard::setCardBack(int b)
+{
+ if ( cardBack != b ) {
+
+ cardBack = b;
+
+ if ( cardsBacks )
+ delete cardsBacks;
+
+ switch (cardBack) {
+ case 0:
+ cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0001" ) ); break;
+ case 1:
+ cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0002" ) ); break;
+ case 2:
+ cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0003" ) ); break;
+ case 3:
+ cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0004" ) ); break;
+ case 4:
+ cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0005" ) ); break;
+ }
+
+ if ( !isFacing() )
+ redraw();
+ }
+}
+
+
+void CanvasCard::draw(QPainter &painter)
+{
+ int ix = (int)x(), iy = (int)y();
+
+ QPainter *p = &painter;
+ QPixmap *unscaledCard = NULL;
+
+ if ((scaleX <= 0.98) || (scaleY <= 0.98))
+ {
+ p = new QPainter();
+ unscaledCard = new QPixmap( cardsFaces->width(), cardsFaces->height() );
+ p->begin(unscaledCard);
+ ix = 0;
+ iy = 0;
+ }
+
+ if ( isFacing() ) {
+
+/*
+ // Now add the joker and card backs to the list of pixmaps
+ QPixmap *CardsBack = new QPixmap( Resource::loadPixmap( "cards/card_joker.png" ) );
+ QPoint *newBackHotspot = new QPoint( 0, 0 );
+ pixmaps->append((const QPixmap *)CardsBack);
+ hotspots->append((const QPoint *)newBackHotspot);
+*/
+
+ int w = cardsFaces->width(), h = cardsFaces->height();
+
+// p->setBrush( NoBrush );
+ p->setBrush( QColor( 0xFF, 0xFF, 0xFF ) );
+
+ if ( isRed() == TRUE )
+ p->setPen( QColor( 0xFF, 0, 0 ) );
+ else
+ p->setPen( QColor( 0, 0, 0 ) );
+
+ p->drawPixmap( ix + 0, iy + 0, *cardsFaces );
+ p->drawPixmap( ix + 4, iy + 4, *cardsChars, 7*(getValue()-1), 0, 7, 7 );
+ p->drawPixmap( ix + 12, iy + 4, *cardsSuits, 7*(getSuit()-1), 0, 7, 8 );
+ p->drawPixmap( ix + w-4-7, iy + h-4-7, *cardsCharsUpsideDown, 7*(12-getValue()+1), 0, 7, 7 );
+ p->drawPixmap( ix + w-12-7, iy + h-5-7, *cardsSuitsUpsideDown, 7*(3-getSuit()+1), 0, 7, 8 );
+
+ } else {
+
+ p->drawPixmap( ix, iy, *cardsBacks );
+
+ }
+
+ if (p != &painter)
+ {
+ p->end();
+ QPixmap *scaledCard = CreateScaledPixmap( unscaledCard, scaleX, scaleY );
+ int xoff = scaledCard->width() / 2;
+ int yoff = scaledCard->height() / 2;
+ painter.drawPixmap( (int)x() + xOff - xoff, (int)y() + yOff - yoff, *scaledCard );
+ delete p;
+ delete unscaledCard;
+ delete scaledCard;
+ }
+}
+
+
+static const double flipLift = 1.5;
+
+
+void CanvasCard::flipTo(int x2, int y2, int steps)
+{
+ flipSteps = steps;
+
+#ifdef SLOW_HARDWARE
+ move(x2,y2);
+ Card::flipTo(x2,y2,steps);
+#else
+ int x1 = (int)x();
+ int y1 = (int)y();
+ double dx = x2 - x1;
+ double dy = y2 - y1;
+
+ flipping = TRUE;
+ destX = x2;
+ destY = y2;
+ animSteps = flipSteps;
+ setVelocity(dx/animSteps, dy/animSteps-flipLift);
+ setAnimated(TRUE);
+#endif
+}
+
+
+void CanvasCard::advance(int stage)
+{
+ if ( stage==1 ) {
+ if ( animSteps-- <= 0 ) {
+ scaleX = 1.0;
+ scaleY = 1.0;
+ flipping = FALSE;
+ setVelocity(0,0);
+ setAnimated(FALSE);
+ move(destX,destY); // exact
+ } else {
+ if ( flipping ) {
+ if ( animSteps > flipSteps / 2 ) {
+ // animSteps = flipSteps .. flipSteps/2 (flip up) -> 1..0
+ scaleX = ((double)animSteps/flipSteps-0.5)*2;
+ } else {
+ // animSteps = flipSteps/2 .. 0 (flip down) -> 0..1
+ scaleX = 1-((double)animSteps/flipSteps)*2;
+ }
+ if ( animSteps == flipSteps / 2-1 ) {
+ setYVelocity(yVelocity()+flipLift*2);
+ setFace( !isFacing() );
+ }
+ }
+ }
+ }
+ QCanvasRectangle::advance(stage);
+}
+
+
+void CanvasCard::animatedMove(int x2, int y2, int steps)
+{
+ destX = x2;
+ destY = y2;
+
+ double x1 = x(), y1 = y(), dx = x2 - x1, dy = y2 - y1;
+
+ // Ensure a good speed
+ while ( fabs(dx/steps)+fabs(dy/steps) < 5.0 && steps > 4 )
+ steps--;
+
+ setAnimated(TRUE);
+ setVelocity(dx/steps, dy/steps);
+
+ animSteps = steps;
+}
+
diff --git a/noncore/games/solitaire/canvascard.h b/noncore/games/solitaire/canvascard.h
new file mode 100644
index 0000000..cd9691f
--- a/dev/null
+++ b/noncore/games/solitaire/canvascard.h
@@ -0,0 +1,82 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CANVAS_CARD_H
+#define CANVAS_CARD_H
+
+
+#include <qpainter.h>
+#include <qbitmap.h>
+#include <qpixmap.h>
+#include <qpoint.h>
+#include <qcanvas.h>
+#include "cardgame.h"
+
+
+// ### Just made the number up, is that what you do???
+static const int canvasCardId = 2434321;
+
+
+class CanvasCard : public Card, public QCanvasRectangle
+{
+public:
+ CanvasCard( eValue v, eSuit s, bool f, QCanvas *canvas );
+ virtual ~CanvasCard() { canvas()->removeItem(this); }
+
+ int rtti () const { return canvasCardId; }
+ void move(QPoint p) { QCanvasItem::move( p.x(), p.y() ); }
+ void move(int x, int y) { QCanvasItem::move( x, y ); }
+ void animatedMove(int x, int y, int steps = 10);
+ void animatedMove() { animatedMove(savedX, savedY); }
+ void savePos(void) { savedX = (int)x(); savedY = (int)y(); }
+ void moveToPile(int p) { Q_UNUSED(p); }
+ void setCardBack(int b);
+
+ /*virtual*/ void flipTo(int x, int y, int steps = 8);
+ /*virtual*/ void setPos( int x, int y, int z ) { setX( x ); setY( y ); setZ( z ); }
+ /*virtual*/ void showCard(void) { show(); }
+ /*virtual*/ void redraw(void) { hide(); show(); }
+ /*virtual*/ void draw(QPainter &p);
+
+ void advance(int stage);
+
+protected:
+ /*virtual*/ void flip(void) { redraw(); }
+
+private:
+ int destX, destY;
+ int animSteps;
+ int flipSteps;
+ bool flipping;
+ int savedX, savedY;
+ int cardBack;
+ int oldCardBack;
+ double scaleX, scaleY;
+ int xOff, yOff;
+ static QPixmap *cardsFaces;
+ static QPixmap *cardsBacks;
+ static QBitmap *cardsChars;
+ static QBitmap *cardsSuits;
+ static QBitmap *cardsCharsUpsideDown;
+ static QBitmap *cardsSuitsUpsideDown;
+};
+
+
+#endif
+
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "cardgame.h"
+#include "canvasshapes.h"
+#include "canvascard.h"
+#include "canvascardgame.h"
+
+#include <qpe/resource.h>
+#include <qpe/config.h>
+
+#include <qmainwindow.h>
+#include <qpe/qpemenubar.h>
+#include <qpainter.h>
+
+#include <stdlib.h>
+#include <limits.h>
+#include <time.h>
+#include <math.h>
+
+
+extern int highestZ;
+
+
+class CanvasCardPile : public QCanvasRectangle
+{
+public:
+ CanvasCardPile( CanvasCardGame *ccg, QCanvas *canvas ) : QCanvasRectangle( canvas ), parent( ccg ) {
+ pile = new QPixmap( 0, 0 );
+ pileHeight = 0;
+ firstCard = NULL;
+ }
+
+ void addCard( CanvasCard *card );
+ void advance(int stage);
+ void animatedMove() { animatedMove(savedX, savedY); }
+ void savePos(void) { savedX = (int)x(); savedY = (int)y(); }
+ void animatedMove(int x2, int y2, int steps = 7 );
+
+protected:
+ virtual void draw( QPainter& p );
+
+private:
+ CanvasCardGame *parent;
+ QPixmap *pile;
+ QImage tempImage32;
+ CanvasCard *firstCard;
+ int pileHeight;
+ int destX, destY;
+ int savedX, savedY;
+ int animSteps;
+};
+
+
+void CanvasCardPile::addCard( CanvasCard *card )
+{
+ if ( !firstCard )
+ firstCard = card;
+
+ int height = 36 + pileHeight * 13;
+ setSize( 23, height );
+ pile->resize( 23, height );
+ QPainter p( pile );
+ p.translate( -card->x(), -card->y() + pileHeight * 13 );
+ card->draw( p );
+ pileHeight++;
+
+ QImage tempImage;
+ tempImage = *pile;
+ tempImage32 = tempImage.convertDepth( 32 );
+ tempImage32.setAlphaBuffer( TRUE );
+ for ( int i = 0; i < tempImage32.width(); i++ )
+ for ( int j = 0; j < tempImage32.height(); j++ ) {
+ QRgb col = tempImage32.pixel( i, j );
+ int a = 255-j*220/tempImage32.height();
+ QRgb alpha = qRgba( qRed( col ), qGreen( col ), qBlue( col ), a );
+ tempImage32.setPixel( i, j, alpha );
+ }
+
+ QRgb alpha = qRgba( 0, 0, 0, 0 );
+ tempImage32.setPixel( 1, 0, alpha );
+ tempImage32.setPixel( 0, 0, alpha );
+ tempImage32.setPixel( 0, 1, alpha );
+
+ tempImage32.setPixel( 21, 0, alpha );
+ tempImage32.setPixel( 22, 0, alpha );
+ tempImage32.setPixel( 22, 1, alpha );
+ height--;
+ tempImage32.setPixel( 1, height, alpha );
+ tempImage32.setPixel( 0, height - 1, alpha );
+ tempImage32.setPixel( 0, height, alpha );
+
+ tempImage32.setPixel( 21, height, alpha );
+ tempImage32.setPixel( 22, height, alpha );
+ tempImage32.setPixel( 22, height - 1, alpha );
+}
+
+
+void CanvasCardPile::advance(int stage)
+{
+ if ( stage==1 ) {
+ if ( animSteps-- <= 0 ) {
+ CanvasCard *item = firstCard;
+ while (item) {
+ item->show();
+ item = (CanvasCard *)item->getCardPile()->cardInfront(item);
+ }
+ setVelocity(0,0);
+ setAnimated(FALSE);
+ parent->cancelMoving();
+ hide();
+ move(destX,destY); // exact
+ }
+ }
+ QCanvasRectangle::advance(stage);
+}
+
+
+void CanvasCardPile::animatedMove(int x2, int y2, int steps = 7 )
+{
+ destX = x2;
+ destY = y2;
+
+ double x1 = x(), y1 = y(), dx = x2 - x1, dy = y2 - y1;
+
+ // Ensure a good speed
+ while ( fabs(dx/steps)+fabs(dy/steps) < 5.0 && steps > 4 )
+ steps--;
+
+ setAnimated(TRUE);
+ setVelocity(dx/steps, dy/steps);
+
+ animSteps = steps;
+}
+
+
+void CanvasCardPile::draw( QPainter& p )
+{
+ int ix = (int)x(), iy = (int)y();
+ p.drawImage( ix, iy, tempImage32 );
+}
+
+
+CanvasCardGame::~CanvasCardGame() {
+ // the deletion stuff should be fixed now and only deletes
+ // items created by this CardGame. I haven't verified there are zero
+ // memory leaks yet
+ if ( alphaCardPile )
+ delete alphaCardPile;
+}
+
+
+void CanvasCardGame::gameWon() {
+
+ srand(time(NULL));
+
+ QCanvasItemList list = canvas()->allItems();
+ QCanvasItemList::Iterator it = list.begin();
+
+ for (; it != list.end(); ++it) {
+ if ( (*it)->rtti() == canvasCardId ) {
+ // disperse the cards everywhere
+ int x = 300 - rand() % 1000;
+ int y = 300 + rand() % 200;
+ ((CanvasCard *)*it)->animatedMove( x, y, 50 );
+ }
+ }
+}
+
+
+void CanvasCardGame::contentsMousePressEvent(QMouseEvent *e) {
+
+ if ( moving )
+ return;
+
+ QCanvasItemList l = canvas()->collisions( e->pos() );
+
+ for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+
+ if ( (*it)->rtti() == canvasCardId ) {
+
+ moving = (CanvasCard *)*it;
+
+ if ( moving->animated() )
+ return;
+
+ cardXOff = (int)(e->pos().x() - moving->x());
+ cardYOff = (int)(e->pos().y() - moving->y());
+
+ if ( !mousePressCard( moving, e->pos() ) ) {
+ CanvasCard *card = moving;
+
+ if ( alphaCardPile )
+ delete alphaCardPile;
+
+ alphaCardPile = new CanvasCardPile( this, canvas() );
+ alphaCardPile->move( card->x(), card->y() );
+ alphaCardPile->savePos();
+ alphaCardPile->show();
+
+ while (card) {
+ alphaCardPile->addCard( card );
+ card->hide();
+ card = (CanvasCard *)card->getCardPile()->cardInfront(card);
+ }
+
+ alphaCardPile->setZ( INT_MAX );
+
+ moved = TRUE;
+ } else {
+ if ( alphaCardPile )
+ alphaCardPile->hide();
+ }
+ return;
+ }
+ }
+
+ mousePress( e->pos() );
+}
+
+/*
+//
+// Should have some intelligent way to make double clicking on a
+// card send it to the most appropriate pile
+//
+void CanvasCardGame::contentsMouseDoubleClickEvent(QMouseEvent *e) {
+ QCanvasItemList l = canvas()->collisions( e->pos() );
+ for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+ if ( (*it)->rtti() == canvasCardId ) {
+ CanvasCard *card = (CanvasCard *)*it;
+
+ if ( card->animated() )
+ return;
+
+ if ( card->getCardPile()->isAllowedToBeMoved(card) ) {
+ if (card->getCardPile()->cardInfront(card) == NULL) {
+ CardPile *pile = first();
+ if (pile && pile->isAllowedOnTop(card)) {
+ // move card to this pile
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+*/
+
+void CanvasCardGame::contentsMouseMoveEvent(QMouseEvent *e) {
+
+ QPoint p = e->pos();
+
+ if ( moving ) {
+
+ moved = TRUE;
+
+ if (moving->isFacing() != TRUE)
+ return;
+
+ int tx = (int)p.x() - cardXOff;
+ int ty = (int)p.y() - cardYOff;
+
+ if (snapOn == TRUE) {
+ CardPile *pile = closestPile( tx, ty, 50 );
+ if ( pile && pile->isAllowedOnTop( moving ) ) {
+ QPoint p = pile->getHypertheticalNextCardPos();
+ if ( alphaCardPile )
+ alphaCardPile->move( p.x(), p.y() );
+ return;
+ }
+ }
+
+ if ( alphaCardPile )
+ alphaCardPile->move( tx, ty );
+ }
+
+}
+
+
+void CanvasCardGame::contentsMouseReleaseEvent(QMouseEvent *e)
+{
+ QPoint p = e->pos();
+
+ Q_UNUSED(p);
+
+ if ( moving ) {
+
+ CanvasCard *item = moving;
+
+ if ( item->animated() )
+ return;
+
+ if ( alphaCardPile )
+ if ( moved ) {
+
+ CardPile *pile = closestPile((int)alphaCardPile->x(), (int)alphaCardPile->y(), 30);
+
+ if (pile && pile->isAllowedOnTop(item)) {
+ CardPile *oldPile = item->getCardPile();
+ Card *c = NULL;
+ if ( oldPile != pile) {
+ while ( item ) {
+ item->show();
+ if ( oldPile ) {
+ c = oldPile->cardInfront(item);
+ oldPile->removeCard(item);
+ }
+ pile->addCardToTop(item);
+ item->setCardPile(pile);
+ //item->move( pile->getCardPos(item) );
+ QPoint p = pile->getCardPos(item);
+ item->setPos( p.x(), p.y(), highestZ );
+ highestZ++;
+
+ if (item->getValue() == king && haveWeWon()) {
+ alphaCardPile->hide();
+ gameWon();
+ moving = NULL;
+ return;
+ }
+
+ if (oldPile) {
+ item = (CanvasCard *)c;
+ } else {
+ item = NULL;
+ }
+ }
+ alphaCardPile->hide();
+ moving = NULL;
+ return;
+ }
+ }
+
+ alphaCardPile->animatedMove();
+ }
+ }
+
+ moved = FALSE;
+}
+
+
+void CanvasCardGame::readPile( Config& cfg, CardPile *pile, QString name, int& highestZ )
+{
+ cfg.setGroup( name );
+ int numberOfCards = cfg.readNumEntry("NumberOfCards", 0);
+ Card *card = NULL;
+ for ( int i = 0; i < numberOfCards; i++ ) {
+ QString cardStr;
+ cardStr.sprintf( "%i", i );
+ int val = cfg.readNumEntry( "Card" + cardStr );
+ bool facing = cfg.readBoolEntry( "CardFacing" + cardStr );
+ card = cards[ val ];
+ card->setFace(facing);
+ pile->addCardToTop(card);
+ card->setCardPile(pile);
+ QPoint p = pile->getCardPos( card );
+ card->setPos( p.x(), p.y(), highestZ );
+ card->showCard();
+ highestZ++;
+ }
+}
+
+
diff --git a/noncore/games/solitaire/canvascardgame.h b/noncore/games/solitaire/canvascardgame.h
new file mode 100644
index 0000000..4d32014
--- a/dev/null
+++ b/noncore/games/solitaire/canvascardgame.h
@@ -0,0 +1,95 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CANVAS_CARD_GAME_H
+#define CANVAS_CARD_GAME_H
+
+#include "cardgame.h"
+#include "canvasshapes.h"
+#include "canvascard.h"
+
+#include <qpe/resource.h>
+#include <qpe/config.h>
+
+#include <qmainwindow.h>
+#include <qpe/qpemenubar.h>
+#include <qpainter.h>
+
+#include <stdlib.h>
+#include <time.h>
+
+
+class CanvasCardPile;
+
+
+class CanvasCardGame : public QCanvasView, public CardGame
+{
+public:
+ CanvasCardGame(QCanvas &c, bool snap, QWidget *parent = 0, const char *name = 0, WFlags f = 0) :
+ QCanvasView( &c, parent, name, f ),
+ moved(FALSE),
+ moving(NULL),
+ alphaCardPile( NULL ),
+ cardXOff(0), cardYOff(0),
+ snapOn(snap),
+ numberToDraw(1) { }
+
+ virtual ~CanvasCardGame();
+
+ virtual Card *newCard( eValue v, eSuit s, bool f ) {
+ return new CanvasCard( v, s, f, canvas() );
+ }
+
+ virtual void readConfig( Config& cfg ) { Q_UNUSED( cfg ); }
+ virtual void writeConfig( Config& cfg ) { Q_UNUSED( cfg ); }
+
+ virtual void gameWon();
+ virtual bool haveWeWon() { return FALSE; }
+
+ virtual bool mousePressCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); return FALSE; }
+ virtual void mouseReleaseCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); }
+
+ void cancelMoving() { moving = NULL; }
+ void toggleSnap() { snapOn = (snapOn == TRUE) ? FALSE : TRUE; }
+ void toggleCardsDrawn() { numberToDraw = (numberToDraw == 1) ? 3 : 1; }
+ int cardsDrawn() { return numberToDraw; }
+ void setNumberToDraw(int numToDraw) { this->numberToDraw = numToDraw; }
+
+ void readPile( Config& cfg, CardPile *pile, QString name, int& highestZ );
+
+protected:
+ void contentsMousePressEvent(QMouseEvent *e);
+ void contentsMouseReleaseEvent(QMouseEvent *e);
+ void contentsMouseMoveEvent(QMouseEvent *e);
+
+protected:
+ // Mouse event state variables
+ bool moved;
+ CanvasCard *moving;
+ CanvasCardPile *alphaCardPile;
+ int cardXOff, cardYOff;
+
+private:
+ bool snapOn;
+ int numberToDraw;
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/canvascardwindow.cpp b/noncore/games/solitaire/canvascardwindow.cpp
new file mode 100644
index 0000000..4c365a5
--- a/dev/null
+++ b/noncore/games/solitaire/canvascardwindow.cpp
@@ -0,0 +1,227 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "canvascardwindow.h"
+#include "patiencecardgame.h"
+#include "freecellcardgame.h"
+
+#include <qpe/resource.h>
+
+#include <qmainwindow.h>
+#include <qpopupmenu.h>
+#include <qstyle.h>
+
+
+CanvasCardWindow::CanvasCardWindow(QWidget* parent, const char* name, WFlags f) :
+ QMainWindow(parent, name, f), canvas(230, 260), snapOn(TRUE), cardBack(4), gameType(0),
+ cardGame(NULL)
+{
+ setIcon( Resource::loadPixmap( "cards" ) );
+
+ // Create Playing Area for Games
+ if ( QPixmap::defaultDepth() < 12 ) {
+// canvas.setBackgroundColor(QColor(0x51, 0x74, 0x6B));
+// canvas.setBackgroundColor(QColor(0x20, 0xb0, 0x50));
+ canvas.setBackgroundColor(QColor(0x08, 0x98, 0x2D));
+ } else {
+ QPixmap bg;
+ bg.convertFromImage( Resource::loadImage( "table_pattern" ), ThresholdDither );
+ canvas.setBackgroundPixmap(bg);
+ }
+
+#if defined( QT_QWS_CASSIOPEIA )
+ canvas.setAdvancePeriod(70);
+#else
+ canvas.setAdvancePeriod(30);
+#endif
+
+
+#ifdef _PATIENCE_USE_ACCELS_
+ QPEMenuBar* menu = menuBar();
+
+ QPopupMenu* file = new QPopupMenu;
+ file->insertItem(tr("Patience"), this, SLOT(initPatience()), CTRL+Key_F);
+ file->insertItem(tr("Freecell"), this, SLOT(initFreecell()), CTRL+Key_F);
+ menu->insertItem(tr("&Game"), file);
+
+ menu->insertSeparator();
+
+ settings = new QPopupMenu;
+ settings->insertItem(tr("&Change Card Backs"), this, SLOT(changeCardBacks()), Key_F2);
+ snap_id = settings->insertItem(tr("&Snap To Position"), this, SLOT(snapToggle()), Key_F3);
+ settings->setCheckable(TRUE);
+ menu->insertItem(tr("&Settings"),settings);
+
+ menu->insertSeparator();
+
+ QPopupMenu* help = new QPopupMenu;
+ help->insertItem(tr("&About"), this, SLOT(help()), Key_F1);
+ help->setItemChecked(dbf_id, TRUE);
+ menu->insertItem(tr("&Help"),help);
+#else
+ QMenuBar* menu = menuBar();
+
+ QPopupMenu* file = new QPopupMenu;
+ file->insertItem(tr("Patience"), this, SLOT(initPatience()));
+ file->insertItem(tr("Freecell"), this, SLOT(initFreecell()));
+ menu->insertItem(tr("Play"), file);
+
+ menu->insertSeparator();
+
+ settings = new QPopupMenu;
+ settings->setCheckable(TRUE);
+ settings->insertItem(tr("Change Card Backs"), this, SLOT(changeCardBacks()));
+ snap_id = settings->insertItem(tr("Snap To Position"), this, SLOT(snapToggle()));
+ QString m;
+
+ drawId = settings->insertItem(tr("Turn One Card"), this, SLOT(drawnToggle()));
+ menu->insertItem(tr("Settings"),settings);
+
+#endif
+
+ menu->show();
+
+ Config cfg( "Patience" );
+ cfg.setGroup( "GlobalSettings" );
+ snapOn = cfg.readBoolEntry( "SnapOn", TRUE);
+ settings->setItemChecked(snap_id, snapOn);
+ gameType = cfg.readNumEntry( "GameType", -1 );
+ drawThree = cfg.readBoolEntry( "DrawThree", TRUE);
+ if ( gameType == 0 ) {
+ cardGame = new PatienceCardGame( &canvas, snapOn, this );
+ cardGame->setNumberToDraw(drawThree ? 3 : 1);
+ setCaption(tr("Patience"));
+ setCentralWidget(cardGame);
+ cardGame->readConfig( cfg );
+ setCardBacks();
+ } else if ( gameType == 1 ) {
+ cardGame = new FreecellCardGame( &canvas, snapOn, this );
+ setCaption(tr("Freecell"));
+ setCentralWidget(cardGame);
+ //cardGame->newGame(); // Until we know how to handle reading freecell config
+ cardGame->readConfig( cfg );
+ setCardBacks();
+ } else {
+ // Probably there isn't a config file or it is broken
+ // Start a new game
+ initPatience();
+ }
+
+ updateDraw();
+}
+
+
+CanvasCardWindow::~CanvasCardWindow()
+{
+ if (cardGame) {
+ Config cfg("Patience");
+ cfg.setGroup( "GlobalSettings" );
+ cfg.writeEntry( "GameType", gameType );
+ cfg.writeEntry( "SnapOn", snapOn );
+ cfg.writeEntry( "DrawThree", drawThree);
+ cardGame->writeConfig( cfg );
+ delete cardGame;
+ }
+}
+
+
+void CanvasCardWindow::resizeEvent(QResizeEvent *)
+{
+ QSize s = centralWidget()->size();
+ int fw = style().defaultFrameWidth();
+ canvas.resize( s.width() - fw - 2, s.height() - fw - 2);
+}
+
+
+void CanvasCardWindow::initPatience()
+{
+ // Create New Game
+ if ( cardGame )
+ delete cardGame;
+ cardGame = new PatienceCardGame( &canvas, snapOn, this );
+ cardGame->setNumberToDraw(drawThree ? 3 : 1);
+ gameType = 0;
+ setCaption(tr("Patience"));
+ setCentralWidget(cardGame);
+ cardGame->newGame();
+ setCardBacks();
+ updateDraw();
+}
+
+
+void CanvasCardWindow::initFreecell()
+{
+ // Create New Game
+ if ( cardGame ) {
+ delete cardGame;
+ }
+ cardGame = new FreecellCardGame( &canvas, snapOn, this );
+ gameType = 1;
+ setCaption(tr("Freecell"));
+ setCentralWidget(cardGame);
+ cardGame->newGame();
+ setCardBacks();
+}
+
+
+void CanvasCardWindow::snapToggle()
+{
+ snapOn = !snapOn;
+ settings->setItemChecked(snap_id, snapOn);
+ cardGame->toggleSnap();
+}
+
+
+void CanvasCardWindow::drawnToggle()
+{
+ cardGame->toggleCardsDrawn();
+ updateDraw();
+}
+
+void CanvasCardWindow::updateDraw() {
+ if(cardGame->cardsDrawn() == 3)
+ settings->changeItem(drawId, tr("Turn One Card"));
+ else
+ settings->changeItem(drawId, tr("Turn Three Cards"));
+}
+
+
+void CanvasCardWindow::setCardBacks()
+{
+ QCanvasItemList l = canvas.allItems();
+
+ for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
+ if ( (*it)->rtti() == canvasCardId )
+ ((CanvasCard *)(*it))->setCardBack( cardBack );
+ }
+}
+
+
+void CanvasCardWindow::changeCardBacks()
+{
+ cardBack++;
+
+ if (cardBack == 5)
+ cardBack = 0;
+
+ setCardBacks();
+}
+
+
diff --git a/noncore/games/solitaire/canvascardwindow.h b/noncore/games/solitaire/canvascardwindow.h
new file mode 100644
index 0000000..b75d40a
--- a/dev/null
+++ b/noncore/games/solitaire/canvascardwindow.h
@@ -0,0 +1,70 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CANVAS_CARD_WINDOW_H
+#define CANVAS_CARD_WINDOW_H
+
+
+#include <qmainwindow.h>
+#include <qcanvas.h>
+
+
+class CanvasCardGame;
+class QPopupMenu;
+
+
+class CanvasCardWindow : public QMainWindow {
+ Q_OBJECT
+
+public:
+ CanvasCardWindow(QWidget* parent=0, const char* name=0, WFlags f=0);
+ virtual ~CanvasCardWindow();
+
+public slots:
+ void setCardBacks();
+ void changeCardBacks();
+ void snapToggle();
+ void drawnToggle();
+
+private slots:
+ void initFreecell();
+ void initPatience();
+
+protected:
+ virtual void resizeEvent(QResizeEvent *e);
+
+ void updateDraw();
+private:
+ QCanvas canvas;
+ bool snapOn;
+ bool drawThree;
+ int drawId;
+ int cardBack;
+ int gameType;
+ CanvasCardGame *cardGame;
+
+ QPopupMenu* options;
+ QPopupMenu* settings;
+ int dbf_id;
+ int snap_id;
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/canvasshapes.cpp b/noncore/games/solitaire/canvasshapes.cpp
new file mode 100644
index 0000000..28d0b4e
--- a/dev/null
+++ b/noncore/games/solitaire/canvasshapes.cpp
@@ -0,0 +1,92 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qpainter.h>
+#include <qcanvas.h>
+#include "canvasshapes.h"
+
+
+CanvasRoundRect::CanvasRoundRect(int x, int y, QCanvas *canvas) :
+ QCanvasRectangle( x, y, 23, 36, canvas)
+{
+ setZ(0);
+ show();
+}
+
+
+void CanvasRoundRect::redraw()
+{
+ hide();
+ show();
+}
+
+
+void CanvasRoundRect::drawShape(QPainter &p)
+{
+ p.drawRoundRect( (int)x(), (int)y(), 23, 36);
+}
+
+
+CanvasCircleOrCross::CanvasCircleOrCross(int x, int y, QCanvas *canvas) :
+ QCanvasRectangle( x, y, 21, 21, canvas), circleShape(TRUE)
+{
+ show();
+}
+
+
+void CanvasCircleOrCross::redraw()
+{
+ hide();
+ show();
+}
+
+
+void CanvasCircleOrCross::setCircle()
+{
+ circleShape = TRUE;
+ redraw();
+}
+
+
+void CanvasCircleOrCross::setCross()
+{
+ circleShape = FALSE;
+ redraw();
+}
+
+
+void CanvasCircleOrCross::drawShape(QPainter &p)
+{
+ int x1 = (int)x(), y1 = (int)y();
+ // Green circle
+ if (circleShape == TRUE) {
+ p.setPen( QPen( QColor(0x10, 0xE0, 0x10), 1 ) );
+ p.drawEllipse( x1 - 1, y1 - 1, 21, 21);
+ p.drawEllipse( x1 - 1, y1 - 0, 21, 19);
+ p.drawEllipse( x1 + 0, y1 + 0, 19, 19);
+ p.drawEllipse( x1 + 1, y1 + 0, 17, 19);
+ p.drawEllipse( x1 + 1, y1 + 1, 17, 17);
+ // Red cross
+ } else {
+ p.setPen( QPen( QColor(0xE0, 0x10, 0x10), 5 ) );
+ p.drawLine( x1, y1, x1 + 20, y1 + 20);
+ p.drawLine( x1 + 20, y1, x1, y1 + 20);
+ }
+}
+
diff --git a/noncore/games/solitaire/canvasshapes.h b/noncore/games/solitaire/canvasshapes.h
new file mode 100644
index 0000000..72acf6b
--- a/dev/null
+++ b/noncore/games/solitaire/canvasshapes.h
@@ -0,0 +1,55 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CANVAS_SHAPES_H
+#define CANVAS_SHAPES_H
+
+
+#include <qcanvas.h>
+
+
+class QPainter;
+
+
+class CanvasRoundRect : QCanvasRectangle
+{
+public:
+ CanvasRoundRect(int x, int y, QCanvas *canvas);
+ void redraw();
+protected:
+ void drawShape(QPainter &p);
+};
+
+
+class CanvasCircleOrCross : QCanvasRectangle
+{
+public:
+ CanvasCircleOrCross(int x, int y, QCanvas *canvas);
+ void redraw();
+ void setCircle();
+ void setCross();
+protected:
+ void drawShape(QPainter &p);
+private:
+ bool circleShape;
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/card.cpp b/noncore/games/solitaire/card.cpp
new file mode 100644
index 0000000..609e280
--- a/dev/null
+++ b/noncore/games/solitaire/card.cpp
@@ -0,0 +1,53 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "card.h"
+
+#include <qpe/config.h>
+
+#include <qpoint.h>
+#include <qlist.h>
+
+/*
+Card( eValue v, eSuit s, bool f ) :
+ val(v), suit(s), faceUp(f), showing(FALSE), ix(0), iy(0), iz(0), cardPile(NULL) { }
+virtual ~Card() { }
+eValue getValue() { return val; }
+eSuit getSuit() { return suit; }
+CardPile *getCardPile() { return cardPile; }
+bool isFacing() { return faceUp; }
+bool isShowing() { return showing; }
+bool isRed() { return ((suit == diamonds) || (suit == hearts)); }
+int getX(void) { return ix; }
+int getY(void) { return iy; }
+int getZ(void) { return iz; }
+void setCardPile(CardPile *p) { cardPile = p; }
+void setFace(bool f) { faceUp = f; }
+void flip(void) { flipTo(getX(), getY()); }
+virtual void setPos(int x, int y, int z) { ix = x; iy = y; iz = z; }
+virtual void move(int x, int y) { ix = x; iy = y; }
+virtual void move(QPoint p) { ix = p.x(); iy = p.y(); }
+virtual void flipTo(int x, int y, int steps = 8) { ix = x; iy = y; faceUp = !faceUp; redraw(); Q_UNUSED(steps); }
+virtual void showCard(void) { showing = TRUE; }
+virtual void hideCard(void) { showing = FALSE; }
+virtual void redraw(void) { }
+*/
+
+
diff --git a/noncore/games/solitaire/card.h b/noncore/games/solitaire/card.h
new file mode 100644
index 0000000..eb30d30
--- a/dev/null
+++ b/noncore/games/solitaire/card.h
@@ -0,0 +1,84 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CARD_H
+#define CARD_H
+
+
+#include <qpoint.h>
+
+
+class CardPile;
+
+
+enum eSuit {
+ jokerSuit = 0, clubs, spades, diamonds, hearts
+};
+
+
+enum eValue {
+ jokerVal = 0, ace, two, three, four, five,
+ six, seven, eight, nine, ten, jack, queen, king
+};
+
+
+class Card
+{
+public:
+ Card( eValue v, eSuit s, bool f ) :
+ val(v), suit(s), faceUp(f), showing(FALSE), ix(0), iy(0), iz(0), cardPile(NULL) { }
+ virtual ~Card() { }
+
+ eValue getValue() { return val; }
+ eSuit getSuit() { return suit; }
+
+ void setCardPile(CardPile *p) { cardPile = p; }
+ CardPile *getCardPile() { return cardPile; }
+
+ void setFace(bool f) { faceUp = f; /* flip(); */ }
+ bool isFacing() { return faceUp; }
+
+ bool isShowing() { return showing; }
+ bool isRed() { return ((suit == diamonds) || (suit == hearts)); }
+
+ int getX(void) { return ix; }
+ int getY(void) { return iy; }
+ int getZ(void) { return iz; }
+ void flip(void) { flipTo(getX(), getY()); }
+
+ virtual void setPos(int x, int y, int z) { ix = x; iy = y; iz = z; }
+ virtual void move(int x, int y) { ix = x; iy = y; }
+ virtual void move(QPoint p) { ix = p.x(); iy = p.y(); }
+ virtual void flipTo(int x, int y, int steps = 8) { ix = x; iy = y; faceUp = !faceUp; redraw(); Q_UNUSED(steps); }
+ virtual void showCard(void) { showing = TRUE; }
+ virtual void hideCard(void) { showing = FALSE; }
+protected:
+ virtual void redraw(void) { }
+private:
+ eValue val;
+ eSuit suit;
+ bool faceUp;
+ bool showing;
+ int ix, iy, iz;
+ CardPile *cardPile;
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/carddeck.cpp b/noncore/games/solitaire/carddeck.cpp
new file mode 100644
index 0000000..87c043a
--- a/dev/null
+++ b/noncore/games/solitaire/carddeck.cpp
@@ -0,0 +1,81 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <stdlib.h>
+#include <time.h>
+#include "card.h"
+#include "carddeck.h"
+
+
+CardDeck::CardDeck(int jokers) : numberOfJokers(jokers), deckCreated(FALSE)
+{
+ cards = new (Card *)[getNumberOfCards()];
+}
+
+
+CardDeck::~CardDeck()
+{
+ for (int i = 0; i < getNumberOfCards(); i++)
+ delete cards[i];
+ delete cards;
+}
+
+
+void CardDeck::createDeck()
+{
+ if (!deckCreated) {
+ for (int i = 0; i < 52; i++)
+ cards[i] = newCard( (eValue)((i % 13) + 1), (eSuit)((i / 13) + 1), FALSE );
+ for (int i = 0; i < getNumberOfJokers(); i++)
+ cards[52 + i] = newCard( jokerVal, jokerSuit, FALSE );
+ deckCreated = TRUE;
+ }
+}
+
+
+void CardDeck::shuffle()
+{
+ srand(time(NULL));
+ for (int i = 0; i < getNumberOfCards(); i++) {
+ int index = rand() % getNumberOfCards();
+ Card *tmpCard = cards[i];
+ cards[i] = cards[index];
+ cards[index] = tmpCard;
+ }
+}
+
+
+int CardDeck::getNumberOfCards()
+{
+ return 52 + getNumberOfJokers();
+}
+
+
+int CardDeck::getNumberOfJokers()
+{
+ return numberOfJokers;
+}
+
+
+Card *CardDeck::newCard( eValue v, eSuit s, bool f )
+{
+ return new Card(v, s, f);
+}
+
+
diff --git a/noncore/games/solitaire/carddeck.h b/noncore/games/solitaire/carddeck.h
new file mode 100644
index 0000000..9ad35a9
--- a/dev/null
+++ b/noncore/games/solitaire/carddeck.h
@@ -0,0 +1,49 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CARD_DECK_H
+#define CARD_DECK_H
+
+
+class Card;
+
+
+class CardDeck
+{
+public:
+ CardDeck(int jokers = 0);
+ virtual ~CardDeck();
+
+ void createDeck();
+ void shuffle();
+ int getNumberOfCards();
+ int getNumberOfJokers();
+
+ virtual Card *newCard( eValue v, eSuit s, bool f );
+ virtual void deal() { }
+
+ Card **cards;
+private:
+ int numberOfJokers;
+ bool deckCreated;
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/cardgame.cpp b/noncore/games/solitaire/cardgame.cpp
new file mode 100644
index 0000000..b19aeef
--- a/dev/null
+++ b/noncore/games/solitaire/cardgame.cpp
@@ -0,0 +1,35 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "cardgame.h"
+
+
+void CardGame::newGame()
+{
+ // Create Cards
+ createDeck();
+
+ // Shuffle Cards
+ shuffle();
+
+ // Deal Cards
+ deal();
+}
+
+
diff --git a/noncore/games/solitaire/cardgame.h b/noncore/games/solitaire/cardgame.h
new file mode 100644
index 0000000..dd7efab
--- a/dev/null
+++ b/noncore/games/solitaire/cardgame.h
@@ -0,0 +1,45 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CARD_GAME_H
+#define CARD_GAME_H
+
+
+#include <qpoint.h>
+#include "card.h"
+#include "cardpile.h"
+#include "carddeck.h"
+#include "cardgamelayout.h"
+
+
+class CardGame : public CardGameLayout, public CardDeck
+{
+public:
+ CardGame(int numOfJokers = 0) : CardGameLayout(), CardDeck(numOfJokers) { }
+ virtual ~CardGame() { }
+ virtual void newGame();
+ virtual void mousePress(QPoint p) { Q_UNUSED(p); }
+ virtual void mouseRelease(QPoint p) { Q_UNUSED(p); }
+ virtual void mouseMove(QPoint p) { Q_UNUSED(p); }
+private:
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/cardgamelayout.cpp b/noncore/games/solitaire/cardgamelayout.cpp
new file mode 100644
index 0000000..1ceee8d
--- a/dev/null
+++ b/noncore/games/solitaire/cardgamelayout.cpp
@@ -0,0 +1,61 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "cardgamelayout.h"
+
+
+CardGameLayout::~CardGameLayout()
+{
+ // Should I just do setAutoDelete( TRUE ); ?
+ for (CardPile *p = first(); p != NULL; p = next())
+ delete p;
+}
+
+
+CardPile *CardGameLayout::closestPile(int x, int y, int maxDistance)
+{
+ int closestDistance = maxDistance * maxDistance;
+ CardPile *closestPile = NULL;
+
+ for (CardPile *p = first(); p != NULL; p = next()) {
+ int d = p->distanceFromNextPos(x, y);
+ if (d < closestDistance) {
+ closestDistance = d;
+ closestPile = p;
+ }
+ }
+
+ return closestPile;
+}
+
+
+void CardGameLayout::beginDealing()
+{
+ for (CardPile *p = first(); p != NULL; p = next())
+ p->beginDealing();
+}
+
+
+void CardGameLayout::endDealing()
+{
+ for (CardPile *p = first(); p != NULL; p = next())
+ p->endDealing();
+}
+
+
diff --git a/noncore/games/solitaire/cardgamelayout.h b/noncore/games/solitaire/cardgamelayout.h
new file mode 100644
index 0000000..bb36e6b
--- a/dev/null
+++ b/noncore/games/solitaire/cardgamelayout.h
@@ -0,0 +1,42 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CARD_GAME_LAYOUT_H
+#define CARD_GAME_LAYOUT_H
+
+
+#include <qlist.h>
+#include "cardpile.h"
+
+
+class CardGameLayout : public QList<CardPile>
+{
+public:
+ CardGameLayout() { }
+ virtual ~CardGameLayout();
+
+ void addCardPile(CardPile *pile) { append((const CardPile *)pile); }
+ CardPile *closestPile(int x, int y, int maxDistance);
+ void beginDealing();
+ void endDealing();
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/cardpile.cpp b/noncore/games/solitaire/cardpile.cpp
new file mode 100644
index 0000000..0b738d2
--- a/dev/null
+++ b/noncore/games/solitaire/cardpile.cpp
@@ -0,0 +1,114 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "cardpile.h"
+#include "card.h"
+
+#include <qpe/config.h>
+#include <qpoint.h>
+
+#include <qlist.h>
+
+
+CardPile::CardPile(int x, int y) : pileX(x), pileY(y), dealing(FALSE) {
+ pileWidth = 0;
+ pileHeight = 0;
+ pileNextX = pileX;
+ pileNextY = pileY;
+ pileCenterX = x + pileWidth / 2;
+ pileCenterY = y + pileHeight / 2;
+ pileRadius = (pileWidth > pileHeight) ? pileWidth : pileHeight;
+}
+
+
+int CardPile::distanceFromPile(int x, int y) {
+ return (pileCenterX-x)*(pileCenterX-x)+(pileCenterY-y)*(pileCenterY-y);
+}
+
+
+int CardPile::distanceFromNextPos(int x, int y) {
+ return (pileNextX-x)*(pileNextX-x)+(pileNextY-y)*(pileNextY-y);
+}
+
+
+Card *CardPile::cardInfront(Card *c) {
+ CardPile *p = c->getCardPile();
+ if (p) {
+ p->at(p->find(c));
+ return p->next();
+ } else {
+ return NULL;
+ }
+}
+
+
+bool CardPile::kingOnTop() {
+ Card *top = cardOnTop();
+ return top && top->getValue() == king;
+}
+
+
+bool CardPile::addCardToTop(Card *c) {
+ if (dealing || isAllowedOnTop(c)) {
+ append((const Card *)c);
+ cardAddedToTop(c);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+bool CardPile::addCardToBottom(Card *c) {
+ if (dealing || isAllowedOnBottom(c)) {
+ prepend((const Card *)c);
+ cardAddedToBottom(c);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+bool CardPile::removeCard(Card *c) {
+ if (dealing || isAllowedToBeMoved(c)) {
+ take(find(c));
+ cardRemoved(c);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+void CardPile::writeConfig( Config& cfg, QString name ) {
+ int numberOfCards = 0;
+ cfg.setGroup( name );
+ Card *card = cardOnBottom();
+ while ( card ) {
+ QString cardStr;
+ cardStr.sprintf( "%i", numberOfCards );
+ int val = (int)card->getValue() - 1 + ( (int)card->getSuit() - 1 ) * 13;
+ cfg.writeEntry( "Card" + cardStr, val );
+ cfg.writeEntry( "CardFacing" + cardStr, card->isFacing() );
+ card = cardInfront( card );
+ numberOfCards++;
+ }
+ cfg.writeEntry("NumberOfCards", numberOfCards);
+}
+
+
diff --git a/noncore/games/solitaire/cardpile.h b/noncore/games/solitaire/cardpile.h
new file mode 100644
index 0000000..c515bbc
--- a/dev/null
+++ b/noncore/games/solitaire/cardpile.h
@@ -0,0 +1,101 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CARD_PILE_H
+#define CARD_PILE_H
+
+
+#include <qpoint.h>
+#include <qlist.h>
+
+
+enum ePileStackingType {
+ pileCascades = 0, pileStacks, pileCascadesOrStacks
+};
+
+
+enum ePileFaceingType {
+ pileFaceUp = 0, pileFaceDown, pileFaceUpOrDown
+};
+
+
+class Card;
+class Config;
+
+
+class CardPile : public QList<Card>
+{
+public:
+ CardPile(int x, int y);
+ virtual ~CardPile() { }
+
+ int getX() { return pileX; }
+ int getY() { return pileY; }
+ int getNextX() { return pileNextX; }
+ int getNextY() { return pileNextY; }
+ int getWidth() { return pileWidth; }
+ int getHeight() { return pileHeight; }
+
+ void setX(int x) { pileX = x; }
+ void setY(int y) { pileY = y; }
+ void setNextX(int x) { pileNextX = x; }
+ void setNextY(int y) { pileNextY = y; }
+ void setWidth(int width) { pileWidth = width; }
+ void setHeight(int height) { pileHeight = height; }
+
+ void beginDealing() { dealing = TRUE; }
+ void endDealing() { dealing = FALSE; }
+ bool isDealing() { return dealing; }
+
+ int distanceFromPile(int x, int y);
+ int distanceFromNextPos(int x, int y);
+
+ Card *cardOnTop() { return getLast(); }
+ Card *cardOnBottom() { return getFirst(); }
+ Card *cardInfront(Card *c);
+ bool kingOnTop();
+
+ bool addCardToTop(Card *c);
+ bool addCardToBottom(Card *c);
+ bool removeCard(Card *c);
+
+ virtual void cardAddedToTop(Card *) { }
+ virtual void cardAddedToBottom(Card *) { }
+ virtual void cardRemoved(Card *) { }
+ virtual bool isAllowedOnTop(Card *) { return FALSE; }
+ virtual bool isAllowedOnBottom(Card *) { return FALSE; }
+ virtual bool isAllowedToBeMoved(Card *) { return FALSE; }
+ virtual QPoint getCardPos(Card *) { return QPoint(pileX, pileY); }
+ virtual QPoint getHypertheticalNextCardPos() { return QPoint(pileX, pileY); }
+
+ void writeConfig( Config& cfg, QString name );
+
+protected:
+ int pileX, pileY;
+ int pileNextX, pileNextY;
+ int pileWidth, pileHeight;
+ int pileCenterX, pileCenterY;
+ int pileRadius;
+private:
+ bool dealing;
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/freecellcardgame.cpp b/noncore/games/solitaire/freecellcardgame.cpp
new file mode 100644
index 0000000..e82afd4
--- a/dev/null
+++ b/noncore/games/solitaire/freecellcardgame.cpp
@@ -0,0 +1,137 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "freecellcardgame.h"
+
+
+extern int highestZ;
+int numberOfFreeCells = 4;
+
+
+FreecellCardGame::FreecellCardGame(QCanvas *c, bool snap, QWidget *parent) : CanvasCardGame(*c, snap, parent)
+{
+ numberOfFreeCells = 4;
+ highestZ = 0;
+
+ for (int i = 0; i < 4; i++) {
+ freecellPiles[i] = new FreecellFreecellPile( 5 + i * 28, 10, canvas() );
+ addCardPile(freecellPiles[i]);
+ }
+ for (int i = 0; i < 4; i++) {
+ discardPiles[i] = new FreecellDiscardPile( 125 + i * 28, 10, canvas() );
+ addCardPile(discardPiles[i]);
+ }
+ for (int i = 0; i < 8; i++) {
+ workingPiles[i] = new FreecellWorkingPile( 10 + i * 28, 50, canvas() );
+ addCardPile(workingPiles[i]);
+ }
+}
+
+
+void FreecellCardGame::deal(void)
+{
+ highestZ = 1;
+
+ beginDealing();
+
+ for (int i = 0; i < 52; i++) {
+ Card *card = cards[i];
+ card->setFace( TRUE );
+ card->setPos( 0, 0, highestZ );
+ card->setCardPile( workingPiles[i%8] );
+ workingPiles[i%8]->addCardToTop( card );
+ card->move( workingPiles[i%8]->getCardPos( card ) );
+ card->showCard();
+ highestZ++;
+ }
+
+ endDealing();
+}
+
+
+bool FreecellCardGame::mousePressCard( Card *c, QPoint p )
+{
+ Q_UNUSED(p);
+
+ if ( !c->getCardPile()->isAllowedToBeMoved(c) ) {
+ moving = NULL;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+void FreecellCardGame::readConfig( Config& cfg )
+{
+ cfg.setGroup("GameState");
+
+ // Create Cards, but don't shuffle or deal them yet
+ createDeck();
+
+ // Move the cards to their piles (deal them to their previous places)
+ beginDealing();
+
+ highestZ = 1;
+
+ for (int k = 0; k < 4; k++) {
+ QString pile;
+ pile.sprintf( "FreeCellPile%i", k );
+ readPile( cfg, freecellPiles[k], pile, highestZ );
+ }
+
+ for (int k = 0; k < 4; k++) {
+ QString pile;
+ pile.sprintf( "DiscardPile%i", k );
+ readPile( cfg, discardPiles[k], pile, highestZ );
+ }
+
+ for (int k = 0; k < 8; k++) {
+ QString pile;
+ pile.sprintf( "WorkingPile%i", k );
+ readPile( cfg, workingPiles[k], pile, highestZ );
+ }
+
+ highestZ++;
+
+ endDealing();
+}
+
+
+void FreecellCardGame::writeConfig( Config& cfg )
+{
+ cfg.setGroup("GameState");
+ for ( int i = 0; i < 4; i++ ) {
+ QString pile;
+ pile.sprintf( "FreeCellPile%i", i );
+ freecellPiles[i]->writeConfig( cfg, pile );
+ }
+ for ( int i = 0; i < 4; i++ ) {
+ QString pile;
+ pile.sprintf( "DiscardPile%i", i );
+ discardPiles[i]->writeConfig( cfg, pile );
+ }
+ for ( int i = 0; i < 8; i++ ) {
+ QString pile;
+ pile.sprintf( "WorkingPile%i", i );
+ workingPiles[i]->writeConfig( cfg, pile );
+ }
+}
+
+
diff --git a/noncore/games/solitaire/freecellcardgame.h b/noncore/games/solitaire/freecellcardgame.h
new file mode 100644
index 0000000..f1b09ab
--- a/dev/null
+++ b/noncore/games/solitaire/freecellcardgame.h
@@ -0,0 +1,152 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef FREECELL_CARD_GAME_H
+#define FREECELL_CARD_GAME_H
+
+
+#include "patiencecardgame.h"
+
+
+extern int numberOfFreeCells;
+
+
+class FreecellDiscardPile : public PatienceDiscardPile
+{
+public:
+ FreecellDiscardPile(int x, int y, QCanvas *canvas) :
+ PatienceDiscardPile(x, y, canvas) { }
+
+};
+
+
+class FreecellWorkingPile : public PatienceWorkingPile
+{
+public:
+ FreecellWorkingPile(int x, int y, QCanvas *canvas) :
+ PatienceWorkingPile(x, y, canvas) { }
+
+ virtual bool isAllowedOnTop(Card *card) {
+ if ( cardOnBottom() == NULL ) {
+ int numberOfCardsBeingMoved = 0;
+ Card *tempCard = card;
+
+ while ((tempCard != NULL)) {
+ numberOfCardsBeingMoved++;
+ tempCard = cardInfront(tempCard);
+ }
+
+ if (numberOfCardsBeingMoved > numberOfFreeCells)
+ return FALSE;
+ }
+
+ if ( card->isFacing() &&
+ cardOnTop() == NULL )
+ return TRUE;
+ return PatienceWorkingPile::isAllowedOnTop( card );
+ }
+
+ virtual bool isAllowedToBeMoved(Card *card) {
+ int nextExpectedValue = (int)card->getValue();
+ bool nextExpectedColor = card->isRed();
+ int numberOfCardsBeingMoved = 0;
+
+ while ((card != NULL)) {
+ numberOfCardsBeingMoved++;
+ if ( (int)card->getValue() != nextExpectedValue )
+ return FALSE;
+ if ( card->isRed() != nextExpectedColor )
+ return FALSE;
+ nextExpectedValue--;;
+ nextExpectedColor = !nextExpectedColor;
+ card = cardInfront(card);
+ }
+
+ if (numberOfCardsBeingMoved <= (numberOfFreeCells + 1))
+ return TRUE;
+
+ return FALSE;
+ }
+ virtual void cardRemoved(Card *card) {
+ if ( !isDealing() && !cardOnTop() )
+ numberOfFreeCells++;
+ PatienceWorkingPile::cardRemoved( card );
+ }
+ virtual void cardAddedToTop(Card *card) {
+ if ( !isDealing() && cardOnBottom() == card )
+ numberOfFreeCells--;
+ PatienceWorkingPile::cardAddedToTop( card );
+ }
+};
+
+
+class FreecellFreecellPile : public CardPile, public CanvasRoundRect
+{
+public:
+ FreecellFreecellPile(int x, int y, QCanvas *canvas)
+ : CardPile(x, y), CanvasRoundRect(x, y, canvas) { }
+ virtual bool isAllowedOnTop(Card *card) {
+ if ( ( cardOnTop() == NULL ) && ( card->getCardPile()->cardInfront(card) == NULL ) )
+ return TRUE;
+ return FALSE;
+ }
+ virtual bool isAllowedToBeMoved(Card *card) {
+ Q_UNUSED(card);
+ return TRUE;
+ }
+ virtual void cardAddedToTop(Card *card) {
+ Q_UNUSED(card);
+ numberOfFreeCells--;
+ }
+ virtual void cardRemoved(Card *card) {
+ Q_UNUSED(card);
+ numberOfFreeCells++;
+ }
+};
+
+
+class FreecellCardGame : public CanvasCardGame
+{
+public:
+ FreecellCardGame(QCanvas *c, bool snap, QWidget *parent = 0);
+ virtual void deal(void);
+ virtual bool haveWeWon() {
+ return ( discardPiles[0]->kingOnTop() &&
+ discardPiles[1]->kingOnTop() &&
+ discardPiles[2]->kingOnTop() &&
+ discardPiles[3]->kingOnTop() );
+ }
+ virtual void mousePress(QPoint p) { Q_UNUSED(p); }
+ virtual void mouseRelease(QPoint p) { Q_UNUSED(p); }
+// virtual void mouseMove(QPoint p);
+ virtual bool mousePressCard(Card *card, QPoint p);
+ virtual void mouseReleaseCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); }
+// virtual void mouseMoveCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); }
+ void readConfig( Config& cfg );
+ void writeConfig( Config& cfg );
+ bool snapOn;
+private:
+ FreecellFreecellPile *freecellPiles[8];
+ FreecellWorkingPile *workingPiles[8];
+ FreecellDiscardPile *discardPiles[4];
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/main.cpp b/noncore/games/solitaire/main.cpp
new file mode 100644
index 0000000..f81aa3c
--- a/dev/null
+++ b/noncore/games/solitaire/main.cpp
@@ -0,0 +1,36 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "canvascardwindow.h"
+
+#include <qpe/qpeapplication.h>
+
+
+int main( int argc, char ** argv )
+{
+ QPEApplication a( argc, argv );
+
+ CanvasCardWindow m;
+ m.setCaption( CanvasCardWindow::tr("Patience") );
+ a.showMainWidget( &m );
+
+ return a.exec();
+}
+
diff --git a/noncore/games/solitaire/patiencecardgame.cpp b/noncore/games/solitaire/patiencecardgame.cpp
new file mode 100644
index 0000000..5a9326a
--- a/dev/null
+++ b/noncore/games/solitaire/patiencecardgame.cpp
@@ -0,0 +1,234 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "patiencecardgame.h"
+
+
+int highestZ = 0;
+
+
+PatienceCardGame::PatienceCardGame(QCanvas *c, bool snap, QWidget *parent) : CanvasCardGame(*c, snap, parent)
+{
+ numberOfTimesThroughDeck = 0;
+ highestZ = 0;
+
+ circleCross = new CanvasCircleOrCross( 7, 18, canvas() );
+ rectangle = new CanvasRoundRect( 35, 10, canvas() );
+
+ for (int i = 0; i < 4; i++) {
+ discardPiles[i] = new PatienceDiscardPile( 110 + i * 30, 10, canvas() );
+ addCardPile(discardPiles[i]);
+ }
+ for (int i = 0; i < 7; i++) {
+ workingPiles[i] = new PatienceWorkingPile( 10 + i * 30, 50, canvas() );
+ addCardPile(workingPiles[i]);
+ }
+ faceDownDealingPile = new PatienceFaceDownDeck( 5, 10, canvas() );
+ faceUpDealingPile = new PatienceFaceUpDeck( 35, 10, canvas() );
+}
+
+
+PatienceCardGame::~PatienceCardGame()
+{
+ delete circleCross;
+ delete rectangle;
+ delete faceDownDealingPile;
+ delete faceUpDealingPile;
+}
+
+
+void PatienceCardGame::deal(void)
+{
+ highestZ = 1;
+ int t = 0;
+
+ beginDealing();
+
+ for (int i = 0; i < 7; i++) {
+ cards[t]->setFace(TRUE);
+ for (int k = i; k < 7; k++, t++) {
+ Card *card = cards[t];
+ workingPiles[k]->addCardToTop(card);
+ card->setCardPile( workingPiles[k] );
+ QPoint p = workingPiles[k]->getCardPos( card );
+ card->setPos( p.x(), p.y(), highestZ );
+ card->showCard();
+ highestZ++;
+ }
+ }
+
+ for ( ; t < 52; t++) {
+ Card *card = cards[t];
+ faceDownDealingPile->addCardToTop(card);
+ card->setCardPile( faceDownDealingPile );
+ QPoint p = faceDownDealingPile->getCardPos( card );
+ card->setPos( p.x(), p.y(), highestZ );
+ card->showCard();
+ highestZ++;
+ }
+
+ endDealing();
+}
+
+
+void PatienceCardGame::readConfig( Config& cfg )
+{
+ cfg.setGroup("GameState");
+
+ // Do we have a config file to read in?
+ if ( !cfg.hasKey("numberOfTimesThroughDeck") ) {
+ // if not, create a new game
+ newGame();
+ return;
+ }
+ // We have a config file, lets read it in and use it
+
+ // Create Cards, but don't shuffle or deal them yet
+ createDeck();
+
+ // How many times through the deck have we been
+ numberOfTimesThroughDeck = cfg.readNumEntry("NumberOfTimesThroughDeck");
+
+ // restore state to the circle/cross under the dealing pile
+ if ( canTurnOverDeck() )
+ circleCross->setCircle();
+ else
+ circleCross->setCross();
+
+ // Move the cards to their piles (deal them to their previous places)
+ beginDealing();
+
+ highestZ = 1;
+
+ for (int k = 0; k < 7; k++) {
+ QString pile;
+ pile.sprintf( "WorkingPile%i", k );
+ readPile( cfg, workingPiles[k], pile, highestZ );
+ }
+
+ for (int k = 0; k < 4; k++) {
+ QString pile;
+ pile.sprintf( "DiscardPile%i", k );
+ readPile( cfg, discardPiles[k], pile, highestZ );
+ }
+
+ readPile( cfg, faceDownDealingPile, "FaceDownDealingPile", highestZ );
+ readPile( cfg, faceUpDealingPile, "FaceUpDealingPile", highestZ );
+
+ highestZ++;
+
+ endDealing();
+}
+
+
+void PatienceCardGame::writeConfig( Config& cfg )
+{
+ cfg.setGroup("GameState");
+ cfg.writeEntry("numberOfTimesThroughDeck", numberOfTimesThroughDeck);
+
+ for ( int i = 0; i < 7; i++ ) {
+ QString pile;
+ pile.sprintf( "WorkingPile%i", i );
+ workingPiles[i]->writeConfig( cfg, pile );
+ }
+ for ( int i = 0; i < 4; i++ ) {
+ QString pile;
+ pile.sprintf( "DiscardPile%i", i );
+ discardPiles[i]->writeConfig( cfg, pile );
+ }
+ faceDownDealingPile->writeConfig( cfg, "FaceDownDealingPile" );
+ faceUpDealingPile->writeConfig( cfg, "FaceUpDealingPile" );
+}
+
+
+bool PatienceCardGame::mousePressCard( Card *card, QPoint p )
+{
+ Q_UNUSED(p);
+
+ CanvasCard *item = (CanvasCard *)card;
+ if (item->isFacing() != TRUE) {
+ // From facedown stack
+ if ((item->x() == 5) && ((int)item->y() == 10)) {
+ item->setZ(highestZ);
+ highestZ++;
+
+ // Added Code
+ faceDownDealingPile->removeCard(item);
+ faceUpDealingPile->addCardToTop(item);
+ item->setCardPile( faceUpDealingPile );
+
+ item->flipTo( 35, (int)item->y() );
+ }
+ moving = NULL;
+ moved = FALSE;
+
+ // move two other cards if we flip three at a time
+ int flipped = 1;
+ QCanvasItemList l = canvas()->collisions( p );
+ for (QCanvasItemList::Iterator it = l.begin(); (it != l.end()) && (flipped != cardsDrawn()); ++it) {
+ if ( (*it)->rtti() == canvasCardId ) {
+ CanvasCard *item = (CanvasCard *)*it;
+ if (item->animated())
+ continue;
+ item->setZ(highestZ);
+ highestZ++;
+ flipped++;
+
+ // Added Code
+ faceDownDealingPile->removeCard(item);
+ faceUpDealingPile->addCardToTop(item);
+ item->setCardPile( faceUpDealingPile );
+
+ item->flipTo( 35, (int)item->y(), 8 * flipped );
+ }
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+void PatienceCardGame::mousePress(QPoint p)
+{
+ if ( canTurnOverDeck() &&
+ (p.x() > 5) && (p.x() < 28) &&
+ (p.y() > 10) && (p.y() < 46) ) {
+
+ beginDealing();
+ Card *card = faceUpDealingPile->cardOnTop();
+ while ( card ) {
+ card->setPos( 5, 10, highestZ );
+ card->setFace( FALSE );
+ faceUpDealingPile->removeCard( card );
+ faceDownDealingPile->addCardToTop( card );
+ card->setCardPile( faceDownDealingPile );
+ card = faceUpDealingPile->cardOnTop();
+ highestZ++;
+ }
+ endDealing();
+
+ throughDeck();
+
+ moved = TRUE;
+ }
+}
+
+
diff --git a/noncore/games/solitaire/patiencecardgame.h b/noncore/games/solitaire/patiencecardgame.h
new file mode 100644
index 0000000..c4f6c48
--- a/dev/null
+++ b/noncore/games/solitaire/patiencecardgame.h
@@ -0,0 +1,206 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef PATIENCE_CARD_GAME_H
+#define PATIENCE_CARD_GAME_H
+
+
+#include <qpopupmenu.h>
+#include <qmainwindow.h>
+#include <qintdict.h>
+#include <qcanvas.h>
+// #include "canvascardshapes.h"
+// #include "canvascard.h"
+#include "canvascardgame.h"
+
+
+class PatienceFaceDownDeck : public CardPile, public CanvasRoundRect
+{
+public:
+ PatienceFaceDownDeck(int x, int y, QCanvas *canvas)
+ : CardPile(x, y), CanvasRoundRect(x, y, canvas) { }
+ virtual bool isAllowedOnTop(Card *card) {
+ Q_UNUSED(card);
+ // Need to check it is from the faceUpDealingPile
+ return TRUE;
+ }
+ virtual bool isAllowedToBeMoved(Card *card) {
+ Q_UNUSED(card);
+ //if ( ( !card->isFacing() ) && ( card == cardOnTop() ) )
+ if ( card == cardOnTop() )
+ return TRUE;
+ return FALSE;
+ }
+};
+
+
+class PatienceFaceUpDeck : public CardPile, public CanvasRoundRect
+{
+public:
+ PatienceFaceUpDeck(int x, int y, QCanvas *canvas)
+ : CardPile(x, y), CanvasRoundRect(x, y, canvas) { }
+ virtual bool isAllowedOnTop(Card *card) {
+ Q_UNUSED(card);
+ // Need to check it is from the faceDownDealingPile
+ return TRUE;
+ }
+ virtual bool isAllowedToBeMoved(Card *card) {
+ Q_UNUSED(card);
+ //if ( ( card->isFacing() ) && ( card == cardOnTop() ) )
+ if ( card == cardOnTop() )
+ return TRUE;
+ return FALSE;
+ }
+};
+
+
+class PatienceDiscardPile : public CardPile, public CanvasRoundRect
+{
+public:
+ PatienceDiscardPile(int x, int y, QCanvas *canvas)
+ : CardPile(x, y), CanvasRoundRect(x, y, canvas) { }
+ virtual bool isAllowedOnTop(Card *card) {
+ if ( card->isFacing() && ( card->getCardPile()->cardInfront(card) == NULL ) &&
+ ( ( ( cardOnTop() == NULL ) && ( card->getValue() == ace ) ) ||
+ ( ( cardOnTop() != NULL ) &&
+ ( (int)card->getValue() == (int)cardOnTop()->getValue() + 1 ) &&
+ ( card->getSuit() == cardOnTop()->getSuit() ) ) ) )
+ return TRUE;
+ return FALSE;
+ }
+ virtual bool isAllowedToBeMoved(Card *card) {
+ if ( card->isFacing() && ( card == cardOnTop() ) )
+ return TRUE;
+ return FALSE;
+ }
+};
+
+
+class PatienceWorkingPile : public CardPile, public CanvasRoundRect
+{
+public:
+ PatienceWorkingPile(int x, int y, QCanvas *canvas)
+ : CardPile(x, y), CanvasRoundRect(x, y, canvas), top(x, y) { }
+ virtual bool isAllowedOnTop(Card *card) {
+ if ( card->isFacing() &&
+ ( ( ( cardOnTop() == NULL ) && (card->getValue() == king) ) ||
+ ( ( cardOnTop() != NULL ) &&
+ ( (int)card->getValue() + 1 == (int)cardOnTop()->getValue() ) &&
+ ( card->isRed() != cardOnTop()->isRed() ) ) ) )
+ return TRUE;
+ return FALSE;
+ }
+ virtual bool isAllowedToBeMoved(Card *card) {
+ if ( card->isFacing() )
+ return TRUE;
+ return FALSE;
+ }
+ virtual void cardAddedToTop(Card *card) {
+ Q_UNUSED(card);
+ top = getCardPos(NULL);
+ setNextX( top.x() );
+ setNextY( top.y() );
+ }
+ virtual void cardRemoved(Card *card) {
+ Q_UNUSED(card);
+
+ Card *newTopCard = cardOnTop();
+
+ if ( !newTopCard ) {
+ top = QPoint( pileX, pileY );
+ setNextX( pileX );
+ setNextY( pileY );
+ return;
+ } else {
+ top = getCardPos(NULL);
+ if ( newTopCard->isFacing() == FALSE ) {
+ // correct the position taking in to account the card is not
+ // yet flipped, but will become flipped
+ top = QPoint( top.x() - 1, top.y() - 3 );
+ newTopCard->flipTo( top.x(), top.y() );
+ top = QPoint( top.x(), top.y() + 13 );
+ }
+ setNextX( top.x() );
+ setNextY( top.y() );
+ }
+ }
+ virtual QPoint getCardPos(Card *c) {
+ int x = pileX, y = pileY;
+ Card *card = cardOnBottom();
+ while ((card != c) && (card != NULL)) {
+ if (card->isFacing()) {
+ y += 13;
+ } else {
+ x += 1;
+ y += 3;
+ }
+ card = cardInfront(card);
+ }
+ return QPoint( x, y );
+ }
+ virtual QPoint getHypertheticalNextCardPos(void) {
+ return top;
+ // return QPoint( getNextX(), getNextY() );
+ }
+private:
+ QPoint top;
+
+};
+
+
+class PatienceCardGame : public CanvasCardGame
+{
+public:
+ PatienceCardGame(QCanvas *c, bool snap, QWidget *parent = 0);
+ virtual ~PatienceCardGame();
+ virtual void deal(void);
+ virtual bool haveWeWon() {
+ return ( discardPiles[0]->kingOnTop() &&
+ discardPiles[1]->kingOnTop() &&
+ discardPiles[2]->kingOnTop() &&
+ discardPiles[3]->kingOnTop() );;
+ }
+ virtual void mousePress(QPoint p);
+ virtual void mouseRelease(QPoint p) { Q_UNUSED(p); }
+// virtual void mouseMove(QPoint p);
+ virtual bool mousePressCard(Card *card, QPoint p);
+ virtual void mouseReleaseCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); }
+// virtual void mouseMoveCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); }
+ bool canTurnOverDeck(void) { return (numberOfTimesThroughDeck != 3); }
+ void throughDeck(void) {
+ numberOfTimesThroughDeck++;
+ if (numberOfTimesThroughDeck == 3)
+ circleCross->setCross();
+ }
+ bool snapOn;
+ virtual void writeConfig( Config& cfg );
+ virtual void readConfig( Config& cfg );
+private:
+ CanvasCircleOrCross *circleCross;
+ CanvasRoundRect *rectangle;
+ PatienceWorkingPile *workingPiles[7];
+ PatienceDiscardPile *discardPiles[4];
+ PatienceFaceDownDeck *faceDownDealingPile;
+ PatienceFaceUpDeck *faceUpDealingPile;
+ int numberOfTimesThroughDeck;
+};
+
+
+#endif
+
diff --git a/noncore/games/solitaire/qpe-solitaire.control b/noncore/games/solitaire/qpe-solitaire.control
new file mode 100644
index 0000000..71abb0c
--- a/dev/null
+++ b/noncore/games/solitaire/qpe-solitaire.control
@@ -0,0 +1,9 @@
+Files: bin/patience apps/Games/patience.desktop pics/cards
+Priority: optional
+Section: qpe/games
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Game: solitaire card games
+ A solitaire game for the Qtopia environment.
diff --git a/noncore/games/solitaire/solitaire.pro b/noncore/games/solitaire/solitaire.pro
new file mode 100755
index 0000000..8617cab
--- a/dev/null
+++ b/noncore/games/solitaire/solitaire.pro
@@ -0,0 +1,18 @@
+TEMPLATE = app
+
+CONFIG += qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+
+HEADERS = canvascard.h canvasshapes.h cardgame.h cardgamelayout.h cardpile.h card.h carddeck.h canvascardgame.h freecellcardgame.h patiencecardgame.h canvascardwindow.h
+
+SOURCES = canvascard.cpp canvasshapes.cpp cardgame.cpp cardgamelayout.cpp cardpile.cpp card.cpp carddeck.cpp canvascardgame.cpp freecellcardgame.cpp patiencecardgame.cpp canvascardwindow.cpp main.cpp
+
+TARGET = patience
+
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+REQUIRES = patience
+
+TRANSLATIONS = ../i18n/de/patience.ts