diff options
Diffstat (limited to 'examples/tetrix')
-rw-r--r-- | examples/tetrix/README | 28 | ||||
-rw-r--r-- | examples/tetrix/gtetrix.cpp | 502 | ||||
-rw-r--r-- | examples/tetrix/gtetrix.h | 92 | ||||
-rw-r--r-- | examples/tetrix/qdragapp.cpp | 502 | ||||
-rw-r--r-- | examples/tetrix/qdragapp.h | 31 | ||||
-rw-r--r-- | examples/tetrix/qtetrix.cpp | 176 | ||||
-rw-r--r-- | examples/tetrix/qtetrix.h | 74 | ||||
-rw-r--r-- | examples/tetrix/qtetrixb.cpp | 241 | ||||
-rw-r--r-- | examples/tetrix/qtetrixb.h | 69 | ||||
-rw-r--r-- | examples/tetrix/tetrix.cpp | 24 | ||||
-rw-r--r-- | examples/tetrix/tetrix.doc | 15 | ||||
-rw-r--r-- | examples/tetrix/tetrix.pro | 19 | ||||
-rw-r--r-- | examples/tetrix/tpiece.cpp | 180 | ||||
-rw-r--r-- | examples/tetrix/tpiece.h | 50 |
14 files changed, 2003 insertions, 0 deletions
diff --git a/examples/tetrix/README b/examples/tetrix/README new file mode 100644 index 000000000..869c2dbfb --- /dev/null +++ b/examples/tetrix/README @@ -0,0 +1,28 @@ + Oslo, May 14 1995 + +This code was written to test the very first Qt skeleton. It was in +fact the first Qt application and was written at a time when Qt only +had pushbutton widgets and the drawing engine was limited to drawing +text in a single font and drawing lines (no kidding, those were the +only two drawing operations). In fact the tetrix project doubled the +number of widgets in Qt by introducing the QLCDNumber widget. The whole +application was written in 5 evenings and 1 weekend and is not very +well documented. The tetrix engine is implemented in the GenericTetrix +class and was first made on my good old 10 MHZ AT where I made a DOS +text-mode Tetrix (using about 50 lines) to test it out, it was later +moved to a SUN Sparc 10, where it met Qt. GenericTetrix is totally +independent of Qt, feel free to use it in any way you like. (see the +file gtetrix.h for a brief description of how to use it) + +Enjoy! + + Eirik Eng + ----- + +P.S. Tetrix has later been updated to show new versions of Qt. + +P.P.S The tetrix program uses a special application object called + QDragApplication. Try to guess what it does. + Hint: Try pressing the right mouse button somewhere in the + tetrix window and start dragging.... + diff --git a/examples/tetrix/gtetrix.cpp b/examples/tetrix/gtetrix.cpp new file mode 100644 index 000000000..92b946b44 --- /dev/null +++ b/examples/tetrix/gtetrix.cpp @@ -0,0 +1,502 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "gtetrix.h" + +#include <string.h> + +GenericTetrix::GenericTetrix(int boardWidth,int boardHeight) +{ + int i,j; + + width = boardWidth; + height = boardHeight; + boardPtr = new int[height*width]; // Note the order, this makes it easier + // to remove full lines. + for(i = 0 ; i < height ; i++) + for(j = 0 ; j < width ; j++) + board(j,i) = 0; + currentLine = -1; // -1 if no falling piece. + currentPos = 0; + showNext = 0; // FALSE + nLinesRemoved = 0; + nPiecesDropped = 0; + score = 0; + level = 1; + gameID = 0; + nClearLines = height; +} + +GenericTetrix::~GenericTetrix() +{ + delete[] boardPtr; +} + + +void GenericTetrix::clearBoard(int fillRandomLines) +{ + int i,j; + + if (fillRandomLines >= height) + fillRandomLines = height - 1; + + erasePiece(); + for(i = height - nClearLines - 1 ; i >= fillRandomLines ; i--) + for(j = 0 ; j < width ; j++) + if (board(j,i) != 0) { + draw(j,i,0); + board(j,i) = 0; + } + if (fillRandomLines != 0) + for (i = 0 ; i < fillRandomLines ; i++) { + fillRandom(i); + } + nClearLines = height - fillRandomLines; +} + +void GenericTetrix::showBoard() +{ + int i,j; + + showPiece(); + for(i = height - nClearLines - 1 ; i >= 0 ; i--) + for(j = 0 ; j < width ; j++) + if (board(j,i) != 0) + draw(j,i,board(j,i)); +} + +void GenericTetrix::hideBoard() +{ + int i,j; + + erasePiece(); + for(i = height - nClearLines - 1 ; i >= 0 ; i--) + for(j = 0 ; j < width ; j++) + if (board(j,i) != 0) + draw(j,i,0); +} + +void GenericTetrix::startGame(int gameType,int fillRandomLines) +{ + gameID = gameType; + clearBoard(fillRandomLines); + nLinesRemoved = 0; + updateRemoved(nLinesRemoved); + nClearLines = height; + nPiecesDropped = 0; + score = 0; + updateScore(score); + level = 1; + updateLevel(level); + newPiece(); +} + +void GenericTetrix::revealNextPiece(int revealIt) +{ + if (showNext == revealIt) + return; + showNext = revealIt; + if (!showNext) + eraseNextPiece(); + else + showNextPiece(); +} + +void GenericTetrix::updateBoard(int x1,int y1,int x2, int y2, + int dontUpdateBlanks) +{ + int i,j; + int tmp; + + if (x1 > x2) { + tmp = x2; + x2 = x1; + x1 = tmp; + } + if (y1 > y2) { + tmp = y2; + y2 = y1; + y1 = tmp; + } + if (x1 < 0) + x1 = 0; + if (x2 >= width) + x2 = width - 1; + if (y1 < 0) + y1 = 0; + if (y2 >= height) + y2 = height - 1; + for(i = y1 ; i <= y2 ; i++) + for(j = x1 ; j <= x2 ; j++) + if (!dontUpdateBlanks || board(j,height - i - 1) != 0) + draw(j,height - i - 1,board(j,height - i - 1)); + showPiece(); // Remember to update piece correctly!!!! +} + + +void GenericTetrix::fillRandom(int line) +{ + int i,j; + int holes; + + for(i = 0 ; i < width ; i++) + board(i,line) = TetrixPiece::randomValue(7); + holes = 0; + for(i = 0 ; i < width ; i++) + if (board(i,line) == 0) // Count holes in the line. + holes++; + if (holes == 0) // Full line, make a random hole: + board(TetrixPiece::randomValue(width),line) = 0; + if (holes == width) // Empty line, make a random square: + board(TetrixPiece::randomValue(width),line) = + TetrixPiece::randomValue(6) + 1; + for(j = 0 ; j < width ; j++) + draw(j,i,board(j,i)); +} + +void GenericTetrix::moveLeft(int steps) +{ + while(steps) { + if (!canMoveTo(currentPos - 1,currentLine)) + return; + moveTo(currentPos - 1,currentLine); + steps--; + } +} + +void GenericTetrix::moveRight(int steps) +{ + while(steps) { + if (!canMoveTo(currentPos + 1,currentLine)) + return; + moveTo(currentPos + 1,currentLine); + steps--; + } +} + +void GenericTetrix::rotateLeft() +{ + TetrixPiece tmp(currentPiece); + + tmp.rotateLeft(); + if (!canPosition(tmp)) + return; + position(tmp); + currentPiece = tmp; +} + +void GenericTetrix::rotateRight() +{ + TetrixPiece tmp(currentPiece); + + tmp.rotateRight(); + if (!canPosition(tmp)) + return; + position(tmp); + currentPiece = tmp; +} + +void GenericTetrix::dropDown() +{ + if (currentLine == -1) + return; + + int dropHeight = 0; + int newLine = currentLine; + while(newLine) { + if (!canMoveTo(currentPos,newLine - 1)) + break; + newLine--; + dropHeight++; + } + if (dropHeight != 0) + moveTo(currentPos,newLine); + internalPieceDropped(dropHeight); +} + +void GenericTetrix::oneLineDown() +{ + if (currentLine == -1) + return; + if (canMoveTo(currentPos,currentLine - 1)) { + moveTo(currentPos,currentLine - 1); + } else { + internalPieceDropped(0); + } +} + +void GenericTetrix::newPiece() +{ + currentPiece = nextPiece; + if (showNext) + eraseNextPiece(); + nextPiece.setRandomType(); + if (showNext) + showNextPiece(); + currentLine = height - 1 + currentPiece.getMinY(); + currentPos = width/2 + 1; + if (!canMoveTo(currentPos,currentLine)) { + currentLine = -1; + gameOver(); + } else { + showPiece(); + } +} + +void GenericTetrix::removePiece() +{ + erasePiece(); + currentLine = -1; +} + +void GenericTetrix::drawNextSquare(int,int,int) +{ + +} + +void GenericTetrix::pieceDropped(int) +{ + newPiece(); +} + +void GenericTetrix::updateRemoved(int) +{ +} + +void GenericTetrix::updateScore(int) +{ +} + +void GenericTetrix::updateLevel(int) +{ +} + +void GenericTetrix::removeFullLines() +{ + int i,j,k; + int nFullLines; + + for(i = 0 ; i < height - nClearLines ; i++) { + for(j = 0 ; j < width ; j++) + if (board(j,i) == 0) + break; + if (j == width) { + nFullLines = 1; + for(k = i + 1 ; k < height - nClearLines ; k++) { + for(j = 0 ; j < width ; j++) + if (board(j,k) == 0) + break; + if (j == width) { + nFullLines++; + } else { + for(j = 0 ; j < width ; j++) { + if (board(j,k - nFullLines) != board(j,k)) { + board(j,k - nFullLines) = board(j,k); + draw( j,k - nFullLines, + board(j,k - nFullLines)); + } + } + } + } + nClearLines = nClearLines + nFullLines; + nLinesRemoved = nLinesRemoved + nFullLines; + updateRemoved(nLinesRemoved); + score = score + 10*nFullLines; // updateScore must be + // called by caller! + for (i = height - nClearLines ; + i < height - nClearLines + nFullLines ; + i++) + for(j = 0 ; j < width ; j++) + if (board(j,i) != 0) { + draw(j,i,0); + board(j,i) = 0; + } + } + } +} + +void GenericTetrix::showPiece() +{ + int x,y; + + if (currentLine == -1) + return; + + for(int i = 0 ; i < 4 ; i++) { + currentPiece.getCoord(i,x,y); + draw(currentPos + x,currentLine - y,currentPiece.getType()); + } +} + +void GenericTetrix::erasePiece() +{ + int x,y; + + if (currentLine == -1) + return; + + for(int i = 0 ; i < 4 ; i++) { + currentPiece.getCoord(i,x,y); + draw(currentPos + x,currentLine - y,0); + } +} + +void GenericTetrix::internalPieceDropped(int dropHeight) +{ + gluePiece(); + nPiecesDropped++; + if (nPiecesDropped % 25 == 0) { + level++; + updateLevel(level); + } + score = score + 7 + dropHeight; + removeFullLines(); + updateScore(score); + pieceDropped(dropHeight); +} + +void GenericTetrix::gluePiece() +{ + int x,y; + int min; + + if (currentLine == -1) + return; + + for(int i = 0 ; i < 4 ; i++) { + currentPiece.getCoord(i,x,y); + board(currentPos + x,currentLine - y) = currentPiece.getType(); + } + min = currentPiece.getMinY(); + if (currentLine - min >= height - nClearLines) + nClearLines = height - currentLine + min - 1; +} + +void GenericTetrix::showNextPiece(int erase) +{ + int x,y; + int minX = nextPiece.getMinX(); + int minY = nextPiece.getMinY(); + int maxX = nextPiece.getMaxX(); + int maxY = nextPiece.getMaxY(); + + int xOffset = (3 - (maxX - minX))/2; + int yOffset = (3 - (maxY - minY))/2; + + for(int i = 0 ; i < 4 ; i++) { + nextPiece.getCoord(i,x,y); + if (erase) + drawNextSquare(x + xOffset - minX, + y + yOffset - minY,0); + else + drawNextSquare(x + xOffset - minX, + y + yOffset - minY,nextPiece.getType()); + } +} + +int GenericTetrix::canPosition(TetrixPiece &piece) +{ + if (currentLine == -1) + return 0; + + int x,y; + + for(int i = 0 ; i < 4 ; i++) { + piece.getCoord(i,x,y); + x = currentPos + x; + y = currentLine - y; // Board and pieces have inverted y-coord. systems. + if (x < 0 || x >= width || y < 0 || y >= height) + return 0; // Outside board, cannot put piece here. + if (board(x,y) != 0) + return 0; // Over a non-zero square, cannot put piece here. + } + return 1; // Inside board and no non-zero squares underneath. + +} + +int GenericTetrix::canMoveTo(int xPosition,int line) +{ + if (currentLine == -1) + return 0; + + int x,y; + + for(int i = 0 ; i < 4 ; i++) { + currentPiece.getCoord(i,x,y); + x = xPosition + x; + y = line - y; // Board and pieces have inverted y-coord. systems. + if (x < 0 || x >= width || y < 0 || y >= height) + return 0; // Outside board, cannot put piece here. + if (board(x,y) != 0) + return 0; // Over a non-zero square, cannot put piece here. + } + return 1; // Inside board and no non-zero squares underneath. +} + +void GenericTetrix::moveTo(int xPosition,int line) +{ + if (currentLine == -1) + return; + optimizedMove(xPosition,line,currentPiece); + currentPos = xPosition; + currentLine = line; +} + +void GenericTetrix::position(TetrixPiece &piece) +{ + if (currentLine == -1) + return; + + optimizedMove(currentPos,currentLine,piece); +} + +void GenericTetrix::optimizedMove(int newPos, int newLine, + TetrixPiece &newPiece) +{ + int updates [8][3]; + int nUpdates; + int value; + int x,y; + int i,j; + + for(i = 0 ; i < 4 ; i++) { // Put the erasing coords into updates + currentPiece.getCoord(i,x,y); + updates[i][0] = currentPos + x; + updates[i][1] = currentLine - y; + updates[i][2] = 0; + } + nUpdates = 4; + for(i = 0 ; i < 4 ; i++) { // Any drawing coord same as an erasing one? + newPiece.getCoord(i,x,y); + x = newPos + x; + y = newLine - y; + for (j = 0 ; j < 4 ; j++) + if (updates[j][0] == x && updates[j][1] == y) { // Same coord, + // don't have to erase + if (currentPiece.getType() == newPiece.getType()) + updates[j][2] = -1; // Correct on screen, no update! + else + updates[j][2] = newPiece.getType(); + break; + } + if (j == 4) { // This coord does not overlap an erasing one + updates[nUpdates][0] = x; + updates[nUpdates][1] = y; + updates[nUpdates][2] = newPiece.getType(); + nUpdates++; + } + } + for (i = 0 ; i < nUpdates ; i++) { // Do the updating + x = updates[i][0]; + y = updates[i][1]; + value = updates[i][2]; + if (value != -1) // Only update if new value != current + draw(x,y,value); + } +} diff --git a/examples/tetrix/gtetrix.h b/examples/tetrix/gtetrix.h new file mode 100644 index 000000000..170def596 --- /dev/null +++ b/examples/tetrix/gtetrix.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef GTETRIX_H +#define GTETRIX_H + +#include "tpiece.h" + + +class GenericTetrix +{ +public: + GenericTetrix(int boardWidth = 10,int boardHeight = 22); + virtual ~GenericTetrix(); + + void clearBoard(int fillRandomLines = 0); + void revealNextPiece(int revealIt); + void updateBoard(int x1,int y1,int x2,int y2,int dontUpdateBlanks = 0); + void updateNext(){if (showNext) showNextPiece();} + void hideBoard(); + void showBoard(); + void fillRandom(int line); + + void moveLeft(int steps = 1); + void moveRight(int steps = 1); + void rotateLeft(); + void rotateRight(); + void dropDown(); + void oneLineDown(); + void newPiece(); + void removePiece(); + + int noOfClearLines() {return nClearLines;} + int getLinesRemoved() {return nLinesRemoved;} + int getPiecesDropped() {return nPiecesDropped;} + int getScore() {return score;} + int getLevel() {return level;} + int boardHeight() {return height;} + int boardWidth() {return width;} + + virtual void drawSquare(int x,int y,int value) = 0; + virtual void gameOver() = 0; + + virtual void startGame(int gameType = 0,int fillRandomLines = 0); + virtual void drawNextSquare(int x,int y,int value); + virtual void pieceDropped(int dropHeight); + virtual void updateRemoved(int noOfLines); + virtual void updateScore(int newScore); + virtual void updateLevel(int newLevel); + +private: + void draw(int x, int y, int value){drawSquare(x,height - y,value);} + void removeFullLines(); + void removeLine(int line); + void showPiece(); + void erasePiece(); + void internalPieceDropped(int dropHeight); + void gluePiece(); + void showNextPiece(int erase = 0); + void eraseNextPiece(){showNextPiece(1);}; + int canPosition(TetrixPiece &piece); // Returns a boolean value. + int canMoveTo(int xPosition, int line); // Returns a boolean value. + void moveTo(int xPosition,int line); + void position(TetrixPiece &piece); + void optimizedMove(int newPos, int newLine,TetrixPiece &newPiece); + + int &board(int x,int y){return boardPtr[width*y + x];} + + TetrixPiece currentPiece; + TetrixPiece nextPiece; + int currentLine; + int currentPos; + int showNext; // Boolean variable. + int nLinesRemoved; + int nPiecesDropped; + int score; + int level; + int gameID; + int nClearLines; + int width; + int height; + int *boardPtr; +}; + + +#endif diff --git a/examples/tetrix/qdragapp.cpp b/examples/tetrix/qdragapp.cpp new file mode 100644 index 000000000..409d418b3 --- /dev/null +++ b/examples/tetrix/qdragapp.cpp @@ -0,0 +1,502 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "qdragapp.h" +#include "qptrlist.h" +#include "qintdict.h" +#include "qpopupmenu.h" +#include "qguardedptr.h" +#include "qcolor.h" +#include "qwidget.h" +#include "qfontmetrics.h" +#include "qcursor.h" +#include "qobjectlist.h" + +TQWidget *cursorWidget( TQPoint * = 0 ); + +class TQDragger; + + +class DropWindow : public TQWidget +{ + Q_OBJECT +public: + void paintEvent( TQPaintEvent * ); + void closeEvent( TQCloseEvent * ); + + TQDragger *master; +}; + + +struct DropInfo { + DropInfo() { w=0; } + ~DropInfo() { delete w; } + DropWindow *w; + bool userOpened; +}; + +struct DraggedInfo { + TQWidget *w; + TQWidget *mother; + TQPoint pos; +}; + + +class TQDragger : public TQObject +{ + Q_OBJECT +public: + TQDragger(); + ~TQDragger(); + + bool notify( TQObject *, TQEvent * ); // event filter + void closeDropWindow( DropWindow * ); +public slots: + void openDropWindow(); + void killDropWindow(); + void killAllDropWindows(); + void sendChildHome(); + void sendAllChildrenHome(); +private: + bool isParentToDragged( TQWidget * ); + bool noWidgets( TQWidget * ); + void killDropWindow( DropInfo * ); + void killAllDropWindows( bool ); + void sendChildHome( DraggedInfo * ); + void sendAllChildrenHome( TQWidget * ); + TQWidget *openDropWindow( const TQRect&, bool ); + + bool startGrab(); + void grabFinished(); + bool dragEvent( TQWidget *, TQMouseEvent * ); + bool killDropEvent( TQMouseEvent * ); + bool sendChildEvent( TQMouseEvent * ); + + bool killingDrop; + bool sendingChild; + TQWidget *clickedWidget; + TQGuardedPtr<TQWidget> hostWidget; + TQCursor cursor; + + TQPopupMenu* menu; + TQPoint clickOffset; + TQColor dragBackground; + TQColor dragForeground; + DraggedInfo dragInfo; + TQIntDict<DraggedInfo> draggedDict; + TQIntDict<DropInfo> dropDict; +}; + + +TQDragApplication::TQDragApplication( int &argc, char **argv ) + : TQApplication( argc, argv ), dragger( 0 ) +{ + dragger = new TQDragger; +} + +TQDragApplication::~TQDragApplication() +{ + delete dragger; +} + +bool TQDragApplication::notify( TQObject *o, TQEvent *e ) +{ + if ( dragger && !dragger->notify( o, e ) ) + return TQApplication::notify( o, e ); + else + return FALSE; +} + +void DropWindow::paintEvent( TQPaintEvent * ) +{ + const char *msg = "Drag widgets and drop them here or anywhere!"; + int startX = ( width() - fontMetrics().width( msg ) )/2; + startX = startX < 0 ? 0 : startX; + + drawText( startX, height()/2, msg ); +} + +void DropWindow::closeEvent( TQCloseEvent *e ) +{ + master->closeDropWindow( this ); + e->ignore(); +} + +TQDragger::TQDragger() +{ + dragInfo.w = 0; + killingDrop = FALSE; + sendingChild = FALSE; + draggedDict.setAutoDelete( TRUE ); + dropDict .setAutoDelete( TRUE ); + + menu = new TQPopupMenu; + menu->insertItem( "Open drop window", 1 ); + menu->insertItem( "Kill drop window", 2 ); + menu->insertItem( "Kill all drop windows", 3 ); + menu->insertSeparator(); +// menu->insertItem( "Send child home", 4 ); + menu->insertItem( "Send all children home", 5 ); + + menu->connectItem( 1, this, SLOT(openDropWindow()) ); + menu->connectItem( 2, this, SLOT(killDropWindow()) ); + menu->connectItem( 3, this, SLOT(killAllDropWindows()) ); +// menu->connectItem( 4, this, SLOT(sendChildHome()) ); + menu->connectItem( 5, this, SLOT(sendAllChildrenHome()) ); +} + +TQDragger::~TQDragger() +{ + delete menu; +} + + +bool TQDragger::notify( TQObject *o, TQEvent *e ) +{ + if ( !o->isWidgetType() || o == menu ) + return FALSE; + switch( e->type() ) { + case TQEvent::MouseMove: + { + TQMouseEvent *tmp = (TQMouseEvent*) e; + if ( killingDrop ) + return killDropEvent( tmp ); + if ( sendingChild ) + return sendChildEvent( tmp ); + if ( tmp->state() & TQMouseEvent::RightButton ) + return dragEvent( (TQWidget*) o, tmp ); + break; + } + case TQEvent::MouseButtonPress: + case TQEvent::MouseButtonRelease: + case TQEvent::MouseButtonDblClick: + { + TQMouseEvent *tmp = (TQMouseEvent*) e; + if ( killingDrop ) + return killDropEvent( tmp ); + if ( sendingChild ) + return sendChildEvent( tmp ); + if ( tmp->button() == TQMouseEvent::RightButton ) + return dragEvent( (TQWidget*) o, tmp ); + } + break; + default: + break; + } + return FALSE; +} + +bool TQDragger::isParentToDragged( TQWidget *w ) +{ + TQIntDictIterator<DraggedInfo> iter( draggedDict ); + + DraggedInfo *tmp; + while( (tmp = iter.current()) ) { + ++iter; + if ( tmp->mother == w ) + return TRUE; + } + return FALSE; +} + +bool TQDragger::noWidgets( TQWidget *w ) +{ + const TQObjectList *l = w->children(); + if ( !l ) + return TRUE; + TQObjectListIt iter( *l ); + TQObject *tmp; + while( (tmp = iter.current()) ) { + ++iter; + if ( tmp->isWidgetType() ) + return FALSE; + } + return TRUE; +} + +void TQDragger::sendAllChildrenHome( TQWidget *w ) +{ + const TQObjectList *l = w->children(); + if ( !l ) + return; + TQObjectListIt iter( *l ); + TQObject *tmp; + while( (tmp = iter.current()) ) { + ++iter; + if ( tmp->isWidgetType() ) { + sendAllChildrenHome( (TQWidget*) tmp ); + DraggedInfo *di = draggedDict.find( (long) tmp ); + if ( di ) + sendChildHome( di ); + } + } +} + +bool TQDragger::dragEvent( TQWidget *w, TQMouseEvent *e ) +{ + switch( e->type() ) { + case TQEvent::MouseButtonDblClick: + case TQEvent::MouseButtonPress: { + if ( !noWidgets( w ) || // has widget children + isParentToDragged( w ) || // has had widget children + w->parentWidget() == 0 ) { // is top level window + hostWidget = w; + menu->popup( w->mapToGlobal( e->pos() ) ); + return TRUE; + } + if ( !draggedDict.find( (long) w ) ) { + DraggedInfo *tmp = new DraggedInfo; + tmp->w = w; + tmp->mother = w->parentWidget(); + tmp->pos = w->frameGeometry().topLeft(); + draggedDict.insert( (long) w, tmp ); + } + dragBackground = w->backgroundColor(); + dragForeground = w->foregroundColor(); + dragInfo.w = w; + dragInfo.mother = w->parentWidget(); + dragInfo.pos = w->frameGeometry().topLeft(); + clickOffset = e->pos(); + dragInfo.w = w; + TQPoint p = w->mapToGlobal(TQPoint(0,0)); + w->reparent( 0, WType_Popup, p, TRUE ); + + return TRUE; + } + case TQEvent::MouseButtonRelease: + case TQEvent::MouseMove: { + if ( dragInfo.w != 0 ) { + TQPoint p = TQCursor::pos() - clickOffset; + dragInfo.w->move( p ); + if ( e->type() == TQEvent::MouseMove ) + return TRUE; + } else { + return FALSE; + } + if ( !dragInfo.w ) + return FALSE; + if ( w != dragInfo.w ) + w = dragInfo.w; + dragInfo.w = 0; + w->hide(); + TQPoint pos; + TQWidget *target = cursorWidget( &pos ); + pos = pos - clickOffset; + TQPoint p; + if ( !target ) { + target = openDropWindow( TQRect( pos, w->size() ), + FALSE); + p = TQPoint( 0, 0 ); + } + else + p = target->mapFromGlobal( pos ); + w->reparent( target, 0, p, TRUE ); + DropInfo *tmp = dropDict.find( (long) dragInfo.mother ); + if ( tmp ) { + if ( !tmp->userOpened && noWidgets( tmp->w ) ) + dropDict.remove( (long) tmp->w ); + } + if ( !target->isVisible() ) + target->show(); + } + return TRUE; + default: + return FALSE; + } +} + +bool TQDragger::killDropEvent( TQMouseEvent *e ) +{ + switch( e->type() ) { + case TQEvent::MouseButtonDblClick: + case TQEvent::MouseButtonPress: + clickedWidget = cursorWidget(); + return TRUE; + case TQEvent::MouseButtonRelease: + hostWidget->releaseMouse(); + if ( clickedWidget ) { + DropInfo *tmp = dropDict.find( (long) clickedWidget ); + if( tmp ) { + killDropWindow( tmp ); + dropDict.remove( (long) tmp->w ); + } + } + grabFinished(); + return TRUE; + case TQEvent::MouseMove: + return TRUE; + default: + break; + } + return FALSE; +} + +bool TQDragger::sendChildEvent( TQMouseEvent *e ) +{ + switch( e->type() ) { + case TQEvent::MouseButtonDblClick: + case TQEvent::MouseButtonPress: + clickedWidget = cursorWidget(); + return TRUE; + case TQEvent::MouseButtonRelease: + hostWidget->releaseMouse(); + if ( clickedWidget ) { + DraggedInfo *tmp = draggedDict.find((long) clickedWidget); + if( tmp ) { + TQWidget *parent = tmp->w->parentWidget(); + sendChildHome( tmp ); + DropInfo *dri = dropDict.find( (long) parent ); + if ( dri && noWidgets(dri->w) && !dri->userOpened ) { + killDropWindow( dri ); + dropDict.remove( (long) dri ); + } + } + grabFinished(); + } + return TRUE; + case TQEvent::MouseMove: + return TRUE; + default: + break; + } + return FALSE; +} + +bool TQDragger::startGrab() +{ + if ( !hostWidget ) + return FALSE; + clickedWidget = 0; + cursor = hostWidget->cursor(); + hostWidget->grabMouse(); + hostWidget->setCursor( TQCursor( CrossCursor ) ); + return TRUE; +} + +void TQDragger::grabFinished() +{ + killingDrop = FALSE; + sendingChild = FALSE; + if(hostWidget) + hostWidget->setCursor( cursor ); +} + +void TQDragger::closeDropWindow( DropWindow *w ) +{ + DropInfo *tmp = dropDict.find( (long) w); + if( tmp ) + killDropWindow( tmp ); +} + +void TQDragger::openDropWindow() +{ + TQWidget *tmp = openDropWindow( TQRect(100, 100, 300, 200), TRUE ); + tmp->show(); +} + +TQWidget *TQDragger::openDropWindow( const TQRect &r, bool user ) +{ + DropInfo *tmp = new DropInfo; + DropWindow *w = new DropWindow; + if ( user ) { + tmp->userOpened = TRUE; + w->setCaption( "Drop window" ); + } else { + tmp->userOpened = FALSE; + w->setCaption( "Auto drop window" ); + } + tmp->w = w; + w->master = this; + w->setGeometry( r ); + dropDict.insert( (long) w, tmp ); + w->show(); + return w; +} + +void TQDragger::killDropWindow() +{ + if ( startGrab() ) + killingDrop = TRUE; +} + +void TQDragger::killDropWindow( DropInfo *di ) +{ + const TQObjectList *l = di->w->children(); + if ( !l ) + return; + TQObjectListIt iter( *l ); + TQObject *tmp; + while( (tmp = iter.current()) ) { + ++iter; + if ( tmp->isWidgetType() ) { + DraggedInfo *dri = draggedDict.find( (long) tmp ); + if ( dri ) { + sendChildHome( dri ); + draggedDict.remove( (long) tmp ); + } + } + } + di->w->hide(); +} + +void TQDragger::killAllDropWindows() +{ + killAllDropWindows( FALSE ); +} + +void TQDragger::killAllDropWindows( bool autoOnly ) +{ + TQIntDictIterator<DropInfo> iter( dropDict ); + + DropInfo *tmp; + while( (tmp = iter.current()) ) { + ++iter; + if( !autoOnly || !tmp->userOpened ) { + killDropWindow( tmp ); + dropDict.remove( (long) tmp->w ); + } + } +} + +void TQDragger::sendChildHome( DraggedInfo *i ) +{ + i->w->reparent( i->mother, 0, i->pos, TRUE ); +} + +void TQDragger::sendChildHome() +{ + if ( startGrab() ) + sendingChild = TRUE; +} + +void TQDragger::sendAllChildrenHome() +{ + TQIntDictIterator<DraggedInfo> iter( draggedDict ); + + DraggedInfo *tmp; + while( (tmp = iter.current()) ) { + ++iter; + sendChildHome( tmp ); + draggedDict.remove( (long) tmp->w ); + } + killAllDropWindows( TRUE ); + draggedDict.clear(); +} + + +TQWidget *cursorWidget( TQPoint *p ) +{ + TQPoint curpos = TQCursor::pos(); + if ( p ) + *p = curpos; + return TQApplication::widgetAt( curpos ); +} + + +#include "qdragapp.moc" diff --git a/examples/tetrix/qdragapp.h b/examples/tetrix/qdragapp.h new file mode 100644 index 000000000..f0334b829 --- /dev/null +++ b/examples/tetrix/qdragapp.h @@ -0,0 +1,31 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef TQDRAGAPP_H +#define TQDRAGAPP_H + +#include "qapplication.h" + +class TQDragger; + +class TQDragApplication : public TQApplication +{ + Q_OBJECT +public: + TQDragApplication( int &argc, char **argv ); + virtual ~TQDragApplication(); + + virtual bool notify( TQObject *, TQEvent * ); // event filter + +private: + TQDragger *dragger; +}; + + +#endif // TQDRAGAPP_H diff --git a/examples/tetrix/qtetrix.cpp b/examples/tetrix/qtetrix.cpp new file mode 100644 index 000000000..68b49c254 --- /dev/null +++ b/examples/tetrix/qtetrix.cpp @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "qtetrix.h" +#include <qapplication.h> +#include <qlabel.h> +#include <qdatetime.h> + + +void drawTetrixButton( TQPainter *p, int x, int y, int w, int h, + const TQColor *color, TQWidget *widg) +{ + if ( color ) { + TQPointArray a; + a.setPoints( 3, x,y+h-1, x,y, x+w-1,y ); + p->setPen( color->light() ); + p->drawPolyline( a ); + a.setPoints( 3, x+1,y+h-1, x+w-1,y+h-1, x+w-1,y+1 ); + p->setPen( color->dark() ); + p->drawPolyline( a ); + x++; + y++; + w -= 2; + h -= 2; + p->fillRect( x, y, w, h, *color ); + } + else if(widg) { + widg->erase(x, y, w, h); + } else { + p->fillRect(x, y, w, h, p->backgroundColor()); + } +} + + +ShowNextPiece::ShowNextPiece( TQWidget *parent, const char *name ) + : TQFrame( parent, name ) +{ + setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); + xOffset = -1; // -1 until first resizeEvent. +} + +void ShowNextPiece::resizeEvent( TQResizeEvent *e ) +{ + TQSize sz = e->size(); + blockWidth = (sz.width() - 3)/5; + blockHeight = (sz.height() - 3)/6; + xOffset = (sz.width() - 3)/5; + yOffset = (sz.height() - 3)/6; +} + + +void ShowNextPiece::paintEvent( TQPaintEvent * ) +{ + TQPainter p( this ); + drawFrame( &p ); + p.end(); // explicit end() so any slots can paint too + emit update(); +} + + +void ShowNextPiece::drawNextSquare(int x, int y,TQColor *color) +{ + if (xOffset == -1) // Before first resizeEvent? + return; + + TQPainter paint; + paint.begin(this); + drawTetrixButton( &paint, xOffset+x*blockWidth, yOffset+y*blockHeight, + blockWidth, blockHeight, color, this ); + paint.end(); +} + + +TQTetrix::TQTetrix( TQWidget *parent, const char *name ) + : TQWidget( parent, name ) +{ + TQTime t = TQTime::currentTime(); + TetrixPiece::setRandomSeed( (((double)t.hour())+t.minute()+t.second())/ + (24+60+60) ); + +#define ADD_LABEL( str, x, y, w, h ) \ + { TQLabel *label = new TQLabel(str,this); \ + label->setGeometry(x,y,w,h); \ + label->setAlignment(AlignCenter|AlignVCenter); } + + ADD_LABEL( "NEXT", 50, 10, 78, 30 ); + ADD_LABEL( "SCORE", 330, 10, 178, 30 ); + ADD_LABEL( "LEVEL", 50, 130, 78, 30 ); + ADD_LABEL( "LINES REMOVED", 330, 130, 178, 30 ); + + board = new TQTetrixBoard(this); + showNext = new ShowNextPiece(this); +#ifndef QT_NO_LCDNUMBER + showScore = new TQLCDNumber(5,this); + showLevel = new TQLCDNumber(2,this); + showLines = new TQLCDNumber(5,this); +#else + showScore = new TQLabel("0",this); + showLevel = new TQLabel("0",this); + showLines = new TQLabel("0",this); + showScore->setAlignment(AlignCenter); + showLines->setAlignment(AlignCenter); + showLevel->setAlignment(AlignCenter); + showScore->setFrameStyle(TQFrame::Sunken|TQFrame::Box); + showLines->setFrameStyle(TQFrame::Sunken|TQFrame::Box); + showLevel->setFrameStyle(TQFrame::Sunken|TQFrame::Box); +#endif + tquitButton = new TQPushButton("&Quit",this); + startButton = new TQPushButton("&New Game",this); + pauseButton = new TQPushButton("&Pause",this); + + // Don't let the buttons get keyboard focus + tquitButton->setFocusPolicy( TQWidget::NoFocus ); + startButton->setFocusPolicy( TQWidget::NoFocus ); + pauseButton->setFocusPolicy( TQWidget::NoFocus ); + + connect( board, SIGNAL(gameOverSignal()), SLOT(gameOver()) ); + connect( board, SIGNAL(drawNextSquareSignal(int,int,TQColor*)), showNext, + SLOT(drawNextSquare(int,int,TQColor*)) ); + connect( showNext, SIGNAL(update()), board, SLOT(updateNext()) ); +#ifndef QT_NO_LCDNUMBER + connect( board, SIGNAL(updateScoreSignal(int)), showScore, + SLOT(display(int)) ); + connect( board, SIGNAL(updateLevelSignal(int)), showLevel, + SLOT(display(int))); + connect( board, SIGNAL(updateRemovedSignal(int)), showLines, + SLOT(display(int))); +#else + connect( board, SIGNAL(updateScoreSignal(int)), showScore, + SLOT(setNum(int)) ); + connect( board, SIGNAL(updateLevelSignal(int)), showLevel, + SLOT(setNum(int))); + connect( board, SIGNAL(updateRemovedSignal(int)), showLines, + SLOT(setNum(int))); +#endif + connect( startButton, SIGNAL(clicked()), board, SLOT(start()) ); + connect( tquitButton , SIGNAL(clicked()), SLOT(tquit())); + connect( pauseButton, SIGNAL(clicked()), board, SLOT(pause()) ); + + board->setGeometry( 150, 20, 153, 333 ); + showNext->setGeometry( 50, 40, 78, 94 ); + showScore->setGeometry( 330, 40, 178, 93 ); + showLevel->setGeometry( 50, 160, 78, 93 ); + showLines->setGeometry( 330, 160, 178, 93 ); +#ifndef QT_NO_LCDNUMBER + showScore->display( 0 ); + showLevel->display( 0 ); + showLines->display( 0 ); +#else + showScore->setNum( 0 ); + showLevel->setNum( 0 ); + showLines->setNum( 0 ); +#endif + startButton->setGeometry( 46, 288, 90, 30 ); + tquitButton->setGeometry( 370, 265, 90, 30 ); + pauseButton->setGeometry( 370, 310, 90, 30 ); + board->revealNextPiece(TRUE); + + resize( 550, 370 ); +} + +void TQTetrix::gameOver() +{ +} + + +void TQTetrix::tquit() +{ + qApp->tquit(); +} diff --git a/examples/tetrix/qtetrix.h b/examples/tetrix/qtetrix.h new file mode 100644 index 000000000..36d8bd041 --- /dev/null +++ b/examples/tetrix/qtetrix.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef TQTETRIX_H +#define TQTETRIX_H + +#include "qtetrixb.h" +#include <qframe.h> +#include <qlcdnumber.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qpainter.h> + + +class ShowNextPiece : public TQFrame +{ + Q_OBJECT + friend class TQTetrix; +public: + ShowNextPiece( TQWidget *parent=0, const char *name=0 ); +public slots: + void drawNextSquare( int x, int y,TQColor *color ); +signals: + void update(); +private: + void paintEvent( TQPaintEvent * ); + void resizeEvent( TQResizeEvent * ); + + int blockWidth,blockHeight; + int xOffset,yOffset; +}; + + +class TQTetrix : public TQWidget +{ + Q_OBJECT +public: + TQTetrix( TQWidget *parent=0, const char *name=0 ); + void startGame() { board->startGame(); } + +public slots: + void gameOver(); + void tquit(); +private: + void keyPressEvent( TQKeyEvent *e ) { board->keyPressEvent(e); } + + TQTetrixBoard *board; + ShowNextPiece *showNext; +#ifndef QT_NO_LCDNUMBER + TQLCDNumber *showScore; + TQLCDNumber *showLevel; + TQLCDNumber *showLines; +#else + TQLabel *showScore; + TQLabel *showLevel; + TQLabel *showLines; +#endif + TQPushButton *tquitButton; + TQPushButton *startButton; + TQPushButton *pauseButton; +}; + + +void drawTetrixButton( TQPainter *, int x, int y, int w, int h, + const TQColor *color, TQWidget *widg); + + +#endif diff --git a/examples/tetrix/qtetrixb.cpp b/examples/tetrix/qtetrixb.cpp new file mode 100644 index 000000000..26fd2c2d0 --- /dev/null +++ b/examples/tetrix/qtetrixb.cpp @@ -0,0 +1,241 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "qtetrixb.h" +#include "qtetrix.h" +#include <qtimer.h> +#include <qpainter.h> + +const int waitAfterLineTime = 500; + +TQTetrixBoard::TQTetrixBoard( TQWidget *p, const char *name ) + : TQFrame( p, name ) +{ + setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); + paint = 0; + paint_widget = 0; + timer = new TQTimer(this); + connect( timer, SIGNAL(timeout()), SLOT(timeout()) ); + + colors[0].setRgb(200,100,100); + colors[1].setRgb(100,200,100); + colors[2].setRgb(100,100,200); + colors[3].setRgb(200,200,100); + colors[4].setRgb(200,100,200); + colors[5].setRgb(100,200,200); + colors[6].setRgb(218,170, 0); + + xOffset = -1; // -1 until a resizeEvent is received. + blockWidth = 20; + yOffset = 30; + blockHeight = 20; + noGame = TRUE; + isPaused = FALSE; + waitingAfterLine = FALSE; + updateTimeoutTime(); // Sets timeoutTime +} + +void TQTetrixBoard::startGame(int gameType,int fillRandomLines) +{ + if ( isPaused ) + return; // ignore if game is paused + noGame = FALSE; + GenericTetrix::startGame( gameType, fillRandomLines ); + // Note that the timer is started by updateLevel! +} + + +void TQTetrixBoard::pause() +{ + if ( noGame ) // game not active + return; + isPaused = !isPaused; + if ( isPaused ) { + timer->stop(); + hideBoard(); + } + else + timer->start(timeoutTime); + update(); +} + + +void TQTetrixBoard::drawSquare(int x,int y,int value) +{ + if (xOffset == -1) // Before first resizeEvent? + return; + + const int X = xOffset + x*blockWidth; + const int Y = yOffset + (y - 1)*blockHeight; + + bool localPainter = paint == 0; + TQPainter *p; + TQWidget *w; + if ( localPainter ) { + p = new TQPainter( this ); + w = this; + } else { + p = paint; + w = paint_widget; + } + drawTetrixButton( p, X, Y, blockWidth, blockHeight, + value == 0 ? 0 : &colors[value-1], w); + /* + if ( value != 0 ) { + TQColor tc, bc; + tc = colors[value-1].light(); + bc = colors[value-1].dark(); + p->drawShadePanel( X, Y, blockWidth, blockHeight, + tc, bc, 1, colors[value-1], TRUE ); + } + else + p->fillRect( X, Y, blockWidth, blockHeight, backgroundColor() ); + */ + if ( localPainter ) + delete p; +} + +void TQTetrixBoard::drawNextSquare( int x, int y, int value ) +{ + if ( value == 0 ) + emit drawNextSquareSignal (x, y, 0 ); + else + emit drawNextSquareSignal( x, y, &colors[value-1] ); +} + +void TQTetrixBoard::updateRemoved( int noOfLines ) +{ + if ( noOfLines > 0 ) { + timer->stop(); + timer->start( waitAfterLineTime ); + waitingAfterLine = TRUE; + } + emit updateRemovedSignal( noOfLines ); +} + +void TQTetrixBoard::updateScore( int newScore ) +{ + emit updateScoreSignal( newScore ); +} + +void TQTetrixBoard::updateLevel( int newLevel ) +{ + timer->stop(); + updateTimeoutTime(); + timer->start( timeoutTime ); + emit updateLevelSignal( newLevel ); +} + +void TQTetrixBoard::pieceDropped(int) +{ + if ( waitingAfterLine ) // give player a break if a line has been removed + return; + newPiece(); +} + +void TQTetrixBoard::gameOver() +{ + timer->stop(); + noGame = TRUE; + emit gameOverSignal(); +} + +void TQTetrixBoard::timeout() +{ + if ( waitingAfterLine ) { + timer->stop(); + waitingAfterLine = FALSE; + newPiece(); + timer->start( timeoutTime ); + } else { + oneLineDown(); + } +} + +void TQTetrixBoard::drawContents( TQPainter *p ) +{ + const char *text = "Press \"Pause\""; + TQRect r = contentsRect(); + paint = p; // set widget painter + if ( isPaused ) { + p->drawText( r, AlignCenter | AlignVCenter, text ); + return; + } + int x1,y1,x2,y2; + x1 = (r.left() - xOffset) / blockWidth; + if (x1 < 0) + x1 = 0; + if (x1 >= boardWidth()) + x1 = boardWidth() - 1; + + x2 = (r.right() - xOffset) / blockWidth; + if (x2 < 0) + x2 = 0; + if (x2 >= boardWidth()) + x2 = boardWidth() - 1; + + y1 = (r.top() - yOffset) / blockHeight; + if (y1 < 0) + y1 = 0; + if (y1 >= boardHeight()) + y1 = boardHeight() - 1; + + y2 = (r.bottom() - yOffset) / blockHeight; + if (y2 < 0) + y2 = 0; + if (y2 >= boardHeight()) + y2 = boardHeight() - 1; + + updateBoard( x1, y1, x2, y2, TRUE ); + paint = 0; // reset widget painter + return; +} + +void TQTetrixBoard::resizeEvent(TQResizeEvent *e) +{ + TQSize sz = e->size(); + blockWidth = (sz.width() - 3)/10; + blockHeight = (sz.height() - 3)/22; + xOffset = 1; + yOffset = 1; +} + +void TQTetrixBoard::keyPressEvent( TQKeyEvent *e ) +{ + if ( noGame || isPaused || waitingAfterLine ) + return; + switch( e->key() ) { + case Key_Left : + moveLeft(); + break; + case Key_Right : + moveRight(); + break; + case Key_Down : + rotateRight(); + break; + case Key_Up : + rotateLeft(); + break; + case Key_Space : + dropDown(); + break; + case Key_D : + oneLineDown(); + break; + default: + return; + } + e->accept(); +} + +void TQTetrixBoard::updateTimeoutTime() +{ + timeoutTime = 1000/(1 + getLevel()); +} diff --git a/examples/tetrix/qtetrixb.h b/examples/tetrix/qtetrixb.h new file mode 100644 index 000000000..236f02e18 --- /dev/null +++ b/examples/tetrix/qtetrixb.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef TQTETRIXB_H +#define TQTETRIXB_H + +#include "gtetrix.h" +#include <qframe.h> + +class TQTimer; + +class TQTetrixBoard : public TQFrame, public GenericTetrix +{ + Q_OBJECT +public: + TQTetrixBoard( TQWidget *parent=0, const char *name=0 ); + + void gameOver(); + void startGame(int gameType = 0,int fillRandomLines = 0); + +public slots: + void timeout(); + void updateNext() { GenericTetrix::updateNext(); } + void key(TQKeyEvent *e) { keyPressEvent(e); } + void start() { startGame(); } + void pause(); + +signals: + void gameOverSignal(); + void drawNextSquareSignal(int x,int y,TQColor *color1); + void updateRemovedSignal(int noOfLines); + void updateScoreSignal(int score); + void updateLevelSignal(int level); + +public: // until we have keyboard focus, should be protected + void keyPressEvent( TQKeyEvent * ); + +private: + void drawContents( TQPainter * ); + void resizeEvent( TQResizeEvent * ); + void drawSquare(int x,int y,int value); + void drawNextSquare(int x,int y,int value); + void updateRemoved(int noOfLines); + void updateScore(int newScore); + void updateLevel(int newLlevel); + void pieceDropped(int dropHeight); + void updateTimeoutTime(); + + TQTimer *timer; + + int xOffset,yOffset; + int blockWidth,blockHeight; + int timeoutTime; + bool noGame; + bool isPaused; + bool waitingAfterLine; + + TQColor colors[7]; + TQPainter *paint; + TQWidget *paint_widget; +}; + +#endif diff --git a/examples/tetrix/tetrix.cpp b/examples/tetrix/tetrix.cpp new file mode 100644 index 000000000..e3cf9c29f --- /dev/null +++ b/examples/tetrix/tetrix.cpp @@ -0,0 +1,24 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "qtetrix.h" +#include "qdragapp.h" +#include "qfont.h" + +int main( int argc, char **argv ) +{ + TQApplication::setColorSpec( TQApplication::CustomColor ); + TQDragApplication a(argc,argv); + TQTetrix *tetrix = new TQTetrix; + tetrix->setCaption("Tetrix"); + a.setMainWidget(tetrix); + tetrix->setCaption("TQt Example - Tetrix"); + tetrix->show(); + return a.exec(); +} diff --git a/examples/tetrix/tetrix.doc b/examples/tetrix/tetrix.doc new file mode 100644 index 000000000..93afca4eb --- /dev/null +++ b/examples/tetrix/tetrix.doc @@ -0,0 +1,15 @@ +/* +*/ +/*! \page tetrix-example.html + + \ingroup examples + \title Tetrix + + This is the Qt implementation of the well known game Tetris. + + <hr> + + Main: + + \include tetrix/tetrix.cpp +*/ diff --git a/examples/tetrix/tetrix.pro b/examples/tetrix/tetrix.pro new file mode 100644 index 000000000..ad8ad831a --- /dev/null +++ b/examples/tetrix/tetrix.pro @@ -0,0 +1,19 @@ +TEMPLATE = app +TARGET = tetrix + +CONFIG += qt warn_on release +DEPENDPATH = ../../include + +REQUIRES = small-config + +HEADERS = gtetrix.h \ + qdragapp.h \ + qtetrix.h \ + qtetrixb.h \ + tpiece.h +SOURCES = gtetrix.cpp \ + qdragapp.cpp \ + qtetrix.cpp \ + qtetrixb.cpp \ + tetrix.cpp \ + tpiece.cpp diff --git a/examples/tetrix/tpiece.cpp b/examples/tetrix/tpiece.cpp new file mode 100644 index 000000000..71e47e9b3 --- /dev/null +++ b/examples/tetrix/tpiece.cpp @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "tpiece.h" +#include "qstring.h" +#include <stdlib.h> + +void TetrixPiece::rotateLeft() +{ + if ( pieceType == 5 ) // don't rotate square piece type + return; + int tmp; + for (int i = 0 ; i < 4 ; i++) { + tmp = getXCoord(i); + setXCoord(i,getYCoord(i)); + setYCoord(i,-tmp); + } +} + +void TetrixPiece::rotateRight() +{ + if ( pieceType == 5 ) // don't rotate square piece type + return; + int tmp; + for (int i = 0 ; i < 4 ; i++) { + tmp = getXCoord(i); + setXCoord(i,-getYCoord(i)); + setYCoord(i,tmp); + } +} + +int TetrixPiece::getMinX() +{ + int tmp = coordinates[0][0]; + for(int i = 1 ; i < 4 ; i++) + if (tmp > coordinates[i][0]) + tmp = coordinates[i][0]; + return tmp; +} + +int TetrixPiece::getMaxX() +{ + int tmp = coordinates[0][0]; + for(int i = 1 ; i < 4 ; i++) + if (tmp < coordinates[i][0]) + tmp = coordinates[i][0]; + return tmp; + +} + +int TetrixPiece::getMinY() +{ + int tmp = coordinates[0][1]; + for(int i = 1 ; i < 4 ; i++) + if (tmp > coordinates[i][1]) + tmp = coordinates[i][1]; + return tmp; +} + +int TetrixPiece::getMaxY() +{ + int tmp = coordinates[0][1]; + for(int i = 1 ; i < 4 ; i++) + if (tmp < coordinates[i][1]) + tmp = coordinates[i][1]; + return tmp; +} + +void TetrixPiece::initialize(int type) +{ + static int pieceTypes[7][4][2] = {{{ 0,-1}, + { 0, 0}, + {-1, 0}, + {-1, 1}}, + + {{ 0,-1}, + { 0, 0}, + { 1, 0}, + { 1, 1}}, + + {{ 0,-1}, + { 0, 0}, + { 0, 1}, + { 0, 2}}, + + {{-1, 0}, + { 0, 0}, + { 1, 0}, + { 0, 1}}, + + {{ 0, 0}, + { 1, 0}, + { 0, 1}, + { 1, 1}}, + + {{-1,-1}, + { 0,-1}, + { 0, 0}, + { 0, 1}}, + + {{ 1,-1}, + { 0,-1}, + { 0, 0}, + { 0, 1}}}; + if (type < 1 || type > 7) + type = 1; + pieceType = type; + for(int i = 0 ; i < 4 ; i++) { + coordinates[i][0] = pieceTypes[type - 1][i][0]; + coordinates[i][1] = pieceTypes[type - 1][i][1]; + } +} + + +/* + * Sigh, oh beautiful nostalgia! This random algorithm has + * been taken from the book "Adventures with your pocket calculator" + * and I used it in my first implemented and machine- + * run program of any size to speak of. Imagine how hungry I + * was after having programmed BASIC on paper for + * half a year?!!?!?!?!?!? The first program I typed in was a + * slot machine game and was made in BASIC on a SHARP + * PC-1211 with 1,47 KB RAM (one point four seven kilobytes) and + * a one-line LCD-display (I think it had 32 characters) in the + * year of our lord 1981. The man I had bought the machine from worked + * as a COBOL programmer and was amazed and impressed + * when I demonstrated the program 2 days after I had + * bought the machine, quote: "Gees, I have been looking so long + * for a "random" command in that BASIC, what is it called?" + * Oh, how I still get a thrill out of the thought of the + * explanation I then gave him... + */ + +/* + * Sukk, aa vakre nostalgi! Denne random algoritmen er + * tatt fra boka "Adventures with your pocket calculator" + * og den brukte jeg i mitt foerste implementerte og maskin- + * kjoerte program av nevneverdig stoerrelse. Tror du jeg var + * noe sulten etter aa ha programmert BASIC paa papir i et + * halvt aar?!!?!?!?!?!? Programmet jeg tasta inn foerst var et + * "enarmet banditt" spill og ble laget i BASIC paa en SHARP + * PC-1211 med 1,47 KB RAM (en komma foertisju kilobyte) og + * et en-linjers LCD-display (tror det hadde 32 karakterer) i det + * herrens aar 1981. Mannen jeg kjoepte maskinen av jobbet til + * daglig med COBOL programmering og var forbloeffet og imponert + * da jeg demonstrerte programmet 2 dager etter at jeg hadde + * kjoept maskinen, sitat: "Joess, jeg som har leita saa lenge + * etter en random kommando i den BASICen, hva var det den + * het?" Aa, jeg frydes ennaa ved tanken paa forklaringen jeg + * deretter ga ham... + */ + +double TetrixPiece::randomSeed = 0.33333; + +void TetrixPiece::setRandomSeed(double seed) +{ + TQCString buffer; + if (seed < 0) + seed = - seed; + if (seed >= 1) + seed = seed - (double) ((int) seed); + buffer.sprintf("%1.5f",(float) seed); + for (int i = 0 ; i < 5 ; i++) + if ((buffer[i + 2] - '0') % 2 == 0) + buffer[i + 2]++; + randomSeed = atof(buffer); +} + +int TetrixPiece::randomValue(int maxPlusOne) +{ + randomSeed = randomSeed*147; + randomSeed = randomSeed - (double) ((int) randomSeed); + return (int) (randomSeed*maxPlusOne); +} diff --git a/examples/tetrix/tpiece.h b/examples/tetrix/tpiece.h new file mode 100644 index 000000000..11a0ffb49 --- /dev/null +++ b/examples/tetrix/tpiece.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef TPIECE_H +#define TPIECE_H + +class TetrixPiece +{ +public: + TetrixPiece() {setRandomType();} + TetrixPiece(int type) {initialize(type % 7 + 1);} + + void setRandomType() {initialize(randomValue(7) + 1);} + + void rotateLeft(); + void rotateRight(); + + int getType() {return pieceType;} + int getXCoord(int index) {return coordinates[index][0];} + int getYCoord(int index) {return coordinates[index][1];} + void getCoord(int index,int &x,int&y){x = coordinates[index][0]; + y = coordinates[index][1];} + int getMinX(); + int getMaxX(); + int getMinY(); + int getMaxY(); + + static void setRandomSeed(double seed); + static int randomValue(int maxPlusOne); + +private: + void setXCoord(int index,int value) {coordinates[index][0] = value;} + void setYCoord(int index,int value) {coordinates[index][1] = value;} + void setCoords(int index,int x,int y){coordinates[index][0] = x; + coordinates[index][1] = y;} + void initialize(int type); + + int pieceType; + int coordinates[4][2]; + + static double randomSeed; +}; + +#endif |