summaryrefslogtreecommitdiff
path: root/noncore/games
Side-by-side diff
Diffstat (limited to 'noncore/games') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/kpacman/bitfont.cpp71
-rw-r--r--noncore/games/kpacman/bitfont.h31
-rw-r--r--noncore/games/kpacman/bitmaps.h67
-rw-r--r--noncore/games/kpacman/board.cpp425
-rw-r--r--noncore/games/kpacman/board.h102
-rw-r--r--noncore/games/kpacman/colors.h21
-rw-r--r--noncore/games/kpacman/config.cpp394
-rw-r--r--noncore/games/kpacman/config.h74
-rw-r--r--noncore/games/kpacman/energizer.cpp61
-rw-r--r--noncore/games/kpacman/energizer.h30
-rw-r--r--noncore/games/kpacman/fruit.cpp176
-rw-r--r--noncore/games/kpacman/fruit.h53
-rw-r--r--noncore/games/kpacman/keys.cpp203
-rw-r--r--noncore/games/kpacman/keys.h48
-rw-r--r--noncore/games/kpacman/kpacman.cpp369
-rw-r--r--noncore/games/kpacman/kpacman.h95
-rw-r--r--noncore/games/kpacman/kpacman.moc.cpp73
-rw-r--r--noncore/games/kpacman/kpacman.pro42
-rw-r--r--noncore/games/kpacman/kpacmanwidget.cpp162
-rw-r--r--noncore/games/kpacman/kpacmanwidget.h50
-rw-r--r--noncore/games/kpacman/main.cpp66
-rw-r--r--noncore/games/kpacman/monster.cpp262
-rw-r--r--noncore/games/kpacman/monster.h62
-rw-r--r--noncore/games/kpacman/opie-kpacman.control11
-rwxr-xr-xnoncore/games/kpacman/opie-kpacman.postinst6
-rw-r--r--noncore/games/kpacman/pacman.cpp147
-rw-r--r--noncore/games/kpacman/pacman.h47
-rw-r--r--noncore/games/kpacman/painter.cpp972
-rw-r--r--noncore/games/kpacman/painter.h148
-rw-r--r--noncore/games/kpacman/portable.h63
-rw-r--r--noncore/games/kpacman/referee.cpp1426
-rw-r--r--noncore/games/kpacman/referee.h196
-rw-r--r--noncore/games/kpacman/score.cpp642
-rw-r--r--noncore/games/kpacman/score.h129
-rw-r--r--noncore/games/kpacman/status.cpp367
-rw-r--r--noncore/games/kpacman/status.h78
36 files changed, 7169 insertions, 0 deletions
diff --git a/noncore/games/kpacman/bitfont.cpp b/noncore/games/kpacman/bitfont.cpp
new file mode 100644
index 0000000..40581c8
--- a/dev/null
+++ b/noncore/games/kpacman/bitfont.cpp
@@ -0,0 +1,71 @@
+#include "bitfont.h"
+
+Bitfont::Bitfont(QString fontname, uchar firstChar, uchar lastChar)
+{
+ if (!fontname.isEmpty())
+ font.load(fontname);
+ if (font.width() == font.height()) {
+ fontWidth = fontHeight = font.width() / 16;
+ fontFirstChar = 1;
+ fontLastChar = 255;
+ } else {
+ fontWidth = font.width()/(lastChar-firstChar+1);
+ fontHeight = font.height();
+ fontFirstChar = firstChar;
+ fontLastChar = lastChar;
+ }
+}
+
+QRect Bitfont::rect(QString str)
+{
+ return QRect(0, 0, str.length()*fontWidth, fontHeight);
+}
+
+QPixmap Bitfont::text(QString str, QColor fg, QColor bg)
+{
+ QPixmap FG(str.length()*fontWidth, fontHeight);
+ QBitmap MASK(str.length()*fontWidth, fontHeight, TRUE);
+
+ const uchar *s = (const uchar *) str.data();
+ for (uint i = 0; i < str.length(); i++) {
+ if (font.width() == font.height())
+ bitBlt(&MASK, i*fontWidth, 0, &font,
+ (*s%16)*fontWidth, (*s/16)*fontWidth, fontWidth, fontHeight);
+ else
+ if (*s >= fontFirstChar && *s <= fontLastChar)
+ bitBlt(&MASK, i*fontWidth, 0, &font,
+ (*s-fontFirstChar)*fontWidth, 0, fontWidth, fontHeight);
+ s++;
+ }
+
+ FG.fill(fg);
+ FG.setMask(MASK);
+
+ if (bg.isValid()) {
+ QPixmap BG(str.length()*fontWidth, fontHeight);
+ BG.fill(bg);
+ bitBlt(&BG, 0, 0, &FG);
+ return BG;
+ } else
+ return FG;
+}
+
+uchar Bitfont::firstChar()
+{
+ return fontFirstChar;
+}
+
+uchar Bitfont::lastChar()
+{
+ return fontLastChar;
+}
+
+int Bitfont::width()
+{
+ return fontWidth;
+}
+
+int Bitfont::height()
+{
+ return fontHeight;
+}
diff --git a/noncore/games/kpacman/bitfont.h b/noncore/games/kpacman/bitfont.h
new file mode 100644
index 0000000..c12aa0f
--- a/dev/null
+++ b/noncore/games/kpacman/bitfont.h
@@ -0,0 +1,31 @@
+#ifndef BITFONT_H
+#define BITFONT_H
+
+#include <qstring.h>
+#include <qbitmap.h>
+#include <qpixmap.h>
+#include <qrect.h>
+
+#include "colors.h"
+
+class Bitfont
+{
+public:
+ Bitfont(QString fontname, uchar firstChar, uchar lastChar);
+
+ QPixmap text(QString str, QColor fg = BLACK, QColor bg = QColor());
+ QRect rect(QString str);
+ int width();
+ int height();
+ uchar firstChar();
+ uchar lastChar();
+private:
+ QBitmap font;
+ int fontWidth;
+ int fontHeight;
+ uchar fontFirstChar;
+ uchar fontLastChar;
+};
+
+#endif // BITFONT_H
+
diff --git a/noncore/games/kpacman/bitmaps.h b/noncore/games/kpacman/bitmaps.h
new file mode 100644
index 0000000..f430384
--- a/dev/null
+++ b/noncore/games/kpacman/bitmaps.h
@@ -0,0 +1,67 @@
+static unsigned char demo_bits[] = {
+ "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+ "++*******************************************************++"
+ "+*********************************************************+"
+ "+** *** **+"
+ "+** . . . . . . . . . . . . *** . . . . . . . . . . . . **+"
+ "+** *** **+"
+ "+** . ******* . ********* . *** . ********* . ******* . **+"
+ "+** ******* ********* *** ********* ******* **+"
+ "+** o ******* . ********* . *** . ********* . ******* o **+"
+ "+** ******* ********* *** ********* ******* **+"
+ "+** . ******* . ********* . *** . ********* . ******* . **+"
+ "+** **+"
+ "+** . . . . . . . . . . . . . . . . . . . . . . . . . . **+"
+ "+** **+"
+ "+** . ******* . *** . *************** . *** . ******* . **+"
+ "+** ******* *** *************** *** ******* **+"
+ "+** . ******* . *** . *************** . *** . ******* . **+"
+ "+** *** *** *** **+"
+ "+** . . . . . . *** . . . . *** . . . . *** . . . . . . **+"
+ "+** *** *** *** **+"
+ "+************ . ********* *** ********* . ************+"
+ "++*********** ********* *** ********* ***********++"
+ "+++++++++++** . ********* *** ********* . **+++++++++++"
+ "+++++++++++** *** *** **+++++++++++"
+ "+++++++++++** . *** 0 *** . **+++++++++++"
+ "+++++++++++** *** *** **+++++++++++"
+ "+++++++++++** . *** ######---###### *** . **+++++++++++"
+ "+************ *** ######---###### *** ************+"
+ "+************ . *** ## ## *** . ************+"
+ " ## ## "
+ " . ## 2 1 3 ## . "
+ " ## ## "
+ "+************ . *** ## ## *** . ************+"
+ "+************ *** ############### *** ************+"
+ "+++++++++++** . *** ############### *** . **+++++++++++"
+ "+++++++++++** *** *** **+++++++++++"
+ "+++++++++++** . *** F *** . **+++++++++++"
+ "+++++++++++** *** *** **+++++++++++"
+ "+++++++++++** . *** *************** *** . **+++++++++++"
+ "++*********** *** *************** *** ***********++"
+ "+************ . *** *************** *** . ************+"
+ "+** *** **+"
+ "+** . . . . . . . . . . . . *** . . . . . . . . . . . . **+"
+ "+** *** **+"
+ "+** . ******* . ********* . *** . ********* . ******* . **+"
+ "+** ******* ********* *** ********* ******* **+"
+ "+** . ******* . ********* . *** . ********* . ******* . **+"
+ "+** *** *** **+"
+ "+** o . . *** . . . . . . . P . . . . . . . *** . . o **+"
+ "+** *** *** **+"
+ "+****** . *** . *** . *************** . *** . *** . ******+"
+ "+****** *** *** *************** *** *** ******+"
+ "+****** . *** . *** . *************** . *** . *** . ******+"
+ "+** *** *** *** **+"
+ "+** . . . . . . *** . . . . *** . . . . *** . . . . . . **+"
+ "+** *** *** *** **+"
+ "+** . ******************* . *** . ******************* . **+"
+ "+** ******************* *** ******************* **+"
+ "+** . ******************* . *** . ******************* . **+"
+ "+** **+"
+ "+** . . . . . . . . . . . . . . . . . . . . . . . . . . **+"
+ "+** **+"
+ "+*********************************************************+"
+ "++*******************************************************++"
+ "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+};
diff --git a/noncore/games/kpacman/board.cpp b/noncore/games/kpacman/board.cpp
new file mode 100644
index 0000000..849e75b
--- a/dev/null
+++ b/noncore/games/kpacman/board.cpp
@@ -0,0 +1,425 @@
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <kapp.h>
+#include <klocale.h>
+#endif
+
+#include <qrect.h>
+#include <qregexp.h>
+#include <qmessagebox.h>
+#include <qfile.h>
+#include <qtextstream.h>
+
+#include "board.h"
+#include "bitmaps.h"
+
+Board::Board(int size) : QArray<int> (size)
+{
+ sz = size; // set size of board
+
+ map = "";
+ mapName = ""; // no map loaded so far
+
+ init(None); // initialize varibales
+}
+
+void Board::init(Image image, QString levelName)
+{
+ prisonEntry = OUT;
+ prisonExit = OUT;
+ fruitHome = OUT;
+ fruitPosition = OUT;
+ pacmanHome = OUT;
+ pacmanPosition = OUT;
+ for (int m = 0; m < 8; m++) {
+ monsterHome[m] = OUT;
+ monsterPosition[m] = OUT;
+ }
+ for (int e = 0; e < 8; e++) {
+ energizerPosition[e] = OUT;
+ }
+ for (int e = 0; e < 8; e++) {
+ tunnelPosition[e] = OUT;
+ }
+
+ fill(0);
+ numPoints = 0;
+ numEnergizers = 0;
+ numMonsters = 0;
+ numTunnels = 0;
+
+ if (!levelName.isNull() && !levelName.isEmpty())
+ if (mapName == levelName)
+ image = File;
+ else {
+ QFile levelFile(levelName);
+ if (!levelFile.open(IO_ReadOnly)) {
+
+ QString msg = i18n("The levelmap could not be constructed.\n\n"
+ "The file '@LEVELNAME@' does not exist,\n"
+ "or could not be opened for reading.");
+ msg.replace(QRegExp("@LEVELNAME@"), levelName);
+ // QMessageBox::information(0, i18n("Initialization Error"), msg);
+ printf("%s\n", msg.data());
+ } else {
+ map.fill(' ', BoardHeight*BoardWidth);
+ int height = 0;
+
+ QTextStream levelStream(&levelFile);
+ while (!levelStream.eof() && height < BoardHeight) {
+ QString line = levelStream.readLine();
+
+ if (line.find(QRegExp("^ *;")) == -1) {
+
+ line.replace(QRegExp(";.*"), ""); // strip off comments
+ line.replace(QRegExp("\" *$"), ""); // strip off trailing "
+ line.replace(QRegExp("^ *\""), ""); // strip off leading "
+
+ map.replace(height*BoardWidth,
+ (line.length() > BoardWidth) ? BoardWidth : line.length(),
+ line.data());
+
+ height++;
+ }
+ }
+ mapName = levelName;
+ levelFile.close();
+ image = File;
+ }
+ }
+
+ switch (image) {
+ case Intro : // setup(demo_bits);
+ break;
+ case Demo : setup(demo_bits);
+ break;
+ case Level : setup(demo_bits);
+ break;
+ case File : setup((uchar *) map.data());
+ break;
+ default : break;
+ }
+}
+
+void Board::setup(const uchar *buf)
+{
+ for ( int index = 0; buf[index] != 0 && index < BoardWidth*BoardHeight; index++ ) {
+ switch (buf[index]) {
+ case '*' : set(index, brick); break;
+ case '+' : set(index, out); break;
+ case '#' : set(index, prison); break;
+ case '-' : set(index, gate); break;
+ case 'E' : set(index, tunnel); break;
+ case '.' : set(index, Point); break;
+ case 'o' : set(index, energizer); break;
+ case 'I' : set(index, prisonentry); break;
+ case 'O' : set(index, prisonexit); break;
+ case 'F' : set(index, fruithome); break;
+ case 'P' : set(index, pacmanhome); break;
+ default : if (buf[index] >= '0' && buf[index] <= '7') {
+ set(index, monsterhome, buf[index]-(uchar)'0');
+ }
+ }
+ }
+}
+
+bool Board::inBounds(int pos)
+{
+ return ( pos < 0 || pos > sz-1 ? FALSE : TRUE);
+}
+
+void Board::set(int pos, Square sq, int m)
+{
+ if (inBounds(pos))
+ switch (sq) {
+ case out : at(pos) = OUT; break;
+ case Point : at(pos) |= pointBit; numPoints++; break;
+ case tunnel : at(pos) = sq;
+ for (int e = 0; e < numTunnels; e++) { // if tunnel is already on board
+ if (tunnelPosition[e] == pos) // don't do it again.
+ pos = OUT;
+ }
+ if (pos != OUT) {
+ tunnelPosition[numTunnels] = pos;
+ numTunnels++;
+ }
+ break;
+ case energizer : at(pos) |= energizerBit;
+ for (int e = 0; e < numEnergizers; e++) {
+ if (energizerPosition[e] == pos)
+ pos = OUT;
+ }
+ if (pos != OUT) {
+ energizerPosition[numEnergizers] = pos;
+ numEnergizers++;
+ }
+ break;
+ case fruit : at(pos) |= fruitBit; fruitPosition = pos; break;
+ case pacman : at(pos) |= pacmanBit; pacmanPosition = pos; break;
+ case monster : at(pos) |= (monsterBit << m);
+ monsterPosition[m] = pos; break;
+ case prisonentry : prisonEntry = pos; at(pos) = empty; break;
+ case prisonexit : prisonExit = pos; at(pos) = empty; break;
+ case fruithome : fruitHome = pos; at(pos) = empty; break;
+ case pacmanhome : pacmanHome = pos; at(pos) = empty; break;
+ case monsterhome : monsterHome[m] = pos; at(pos) = empty;
+ if (m == 0 && prisonExit == OUT)
+ prisonExit = pos;
+ if (m == 1 && prisonEntry == OUT)
+ prisonEntry = pos;
+ numMonsters++;
+ break;
+ default : at(pos) = sq;
+ }
+}
+
+void Board::reset(int pos, Square sq, int m)
+{
+ bool found = FALSE;
+ if (inBounds(pos))
+ switch (sq) {
+ case out : at(pos) = empty; break;
+ case Point : at(pos) &= ~ pointBit; numPoints--; break;
+ case energizer : at(pos) &= ~ energizerBit;
+ for (int e = 0; e < numEnergizers; e++) { // delete the position of the eaten
+ if (found) // energizer in the position array
+ energizerPosition[e-1] = energizerPosition[e];
+ if (energizerPosition[e] == pos)
+ found = TRUE;
+ }
+ energizerPosition[numEnergizers--] = OUT;
+ break;
+ case fruit : at(pos) &= ~ fruitBit; fruitPosition = OUT; break;
+ case pacman : at(pos) &= ~ pacmanBit; pacmanPosition = OUT; break;
+ case monster : at(pos) &= ~ (monsterBit << m);
+ monsterPosition[m] = OUT; break;
+ default : at(pos) = at(pos) & varBits;
+ }
+}
+
+int Board::position(Square sq, int m)
+{
+ switch(sq) {
+ case prisonentry : return prisonEntry;
+ case prisonexit : return prisonExit;
+ case fruit : return fruitPosition;
+ case fruithome : return fruitHome;
+ case pacman : return pacmanPosition;
+ case pacmanhome : return pacmanHome;
+ case monster : return monsterPosition[m];
+ case monsterhome : return monsterHome[m];
+ case energizer : return energizerPosition[m];
+ case tunnel : return tunnelPosition[m];
+ default : return OUT;
+ }
+}
+
+bool Board::isOut(int pos)
+{
+ if (inBounds(pos))
+ return (at(pos) == OUT ? TRUE : FALSE);
+ return TRUE;
+}
+
+bool Board::isEmpty(int pos)
+{
+ if (inBounds(pos))
+ return ((at(pos) & fixBits) == empty ? TRUE : FALSE);
+ return TRUE;
+}
+
+bool Board::isBrick(int pos)
+{
+ if (inBounds(pos))
+ return ((at(pos) & fixBits) == brick ? TRUE : FALSE);
+ return FALSE;
+}
+
+bool Board::isPrison(int pos)
+{
+ if (inBounds(pos))
+ return ((at(pos) & fixBits) == prison ? TRUE : FALSE);
+ return FALSE;
+}
+
+bool Board::isGate(int pos)
+{
+ if (inBounds(pos))
+ return ((at(pos) & fixBits) == gate ? TRUE : FALSE);
+ return FALSE;
+}
+
+bool Board::isTunnel(int pos)
+{
+ if (inBounds(pos))
+ return ((at(pos) & fixBits) == tunnel ? TRUE : FALSE);
+ return FALSE;
+}
+
+bool Board::isPoint(int pos)
+{
+ if (inBounds(pos) && at(pos) != OUT)
+ return ((at(pos) & pointBit) != 0 ? TRUE : FALSE);
+ return FALSE;
+}
+
+bool Board::isEnergizer(int pos)
+{
+ if (inBounds(pos) && at(pos) != OUT)
+ return ((at(pos) & energizerBit) != 0 ? TRUE : FALSE);
+ return FALSE;
+}
+
+bool Board::isFruit(int pos)
+{
+ if (inBounds(pos) && at(pos) != OUT)
+ return ((at(pos) & fruitBit) != 0 ? TRUE : FALSE);
+ return FALSE;
+}
+
+bool Board::isPacman(int pos)
+{
+ if (inBounds(pos) && at(pos) != OUT)
+ return ((at(pos) & pacmanBit) != 0 ? TRUE : FALSE);
+ return FALSE;
+}
+
+bool Board::isMonster(int pos)
+{
+ if (inBounds(pos) && at(pos) != OUT)
+ return ((at(pos) & monsterBits) != 0 ? TRUE : FALSE);
+ return FALSE;
+}
+
+bool Board::isWay(int pos, int dir, Square sq) {
+ int p1 = move(pos, dir, 2);
+ if (p1 == OUT)
+ return (sq == out ? TRUE : FALSE);
+ int p2, p3;
+ if (dir == N || dir == S) {
+ p2 = move(p1, E);
+ p3 = move(p1, W);
+ } else {
+ p2 = move(p1, N);
+ p3 = move(p1, S);
+ }
+ switch (sq) {
+ case out : return isOut(p1) | isOut(p2) | isOut(p3);
+ case empty : return isEmpty(p1) & isEmpty(p2) & isEmpty(p3);
+ case brick : return isBrick(p1) | isBrick(p2) | isBrick(p3);
+ case prison : return isPrison(p1) | isPrison(p2) | isPrison(p3);
+ case gate : return isGate(p1) & isGate(p2) & isGate(p3);
+ case tunnel : return isTunnel(p1) &
+ (isTunnel(p2) || isEmpty(p2)) &
+ (isTunnel(p3) || isEmpty(p3));
+ default : return FALSE;
+ }
+}
+
+bool Board::isJump(int pos, int dir) {
+ switch (dir) {
+ case NW: return pos < BoardWidth || x(pos) == 0;
+ case N: return pos < BoardWidth;
+ case NE: return pos < BoardWidth || x(pos) == BoardWidth-1;
+ case W: return x(pos) == 0;
+ case E: return x(pos) == BoardWidth-1;
+ case SW: return pos >= sz-BoardWidth || x(pos) == 0;
+ case S: return pos >= sz-BoardWidth;
+ case SE: return pos >= sz-BoardWidth || x(pos) == BoardWidth-1;
+ }
+ return FALSE;
+}
+
+int Board::move(int pos, int dir, int steps)
+{
+ if (steps < 0) { // move backwards
+ dir = turn(dir); // turn around and do your steps
+ steps *= -1;
+ }
+
+ while (steps-- != 0) { // until all steps are gone
+ switch (dir) {
+ case NW: pos = pos >= BoardWidth && x(pos) > 0 ? (pos-BoardWidth)-1 : sz-1;
+ break;
+ case N: pos = pos >= BoardWidth ? pos-BoardWidth : (sz-BoardWidth)+x(pos);
+ break;
+ case NE: pos = pos >= BoardWidth && x(pos) < BoardWidth-1 ?
+ (pos-BoardWidth)+1 : sz-BoardWidth;
+ break;
+ case W: pos = x(pos) > 0 ? pos-1 : pos+(BoardWidth-1);
+ break;
+ case E: pos = x(pos) < BoardWidth-1 ? pos+1 : pos-(BoardWidth-1);
+ break;
+ case SW: pos = pos < sz-BoardWidth && x(pos) > 0 ? (pos+BoardWidth)-1 : BoardWidth-1;
+ break;
+ case S: pos = pos < sz-BoardWidth ? pos+BoardWidth : x(pos);
+ break;
+ case SE: pos = pos < sz-BoardWidth && x(pos) < BoardWidth-1 ? (pos+BoardWidth)+1 : 0;
+ break;
+ }
+ }
+ return pos; // here we are
+}
+
+int Board::closeup(int pos, int dir, int target)
+{
+ if (dir == N || dir == S) {
+ if (x(target) < x(pos))
+ return W;
+ if (x(target) > x(pos))
+ return E;
+ } else {
+ if (y(target) < y(pos))
+ return N;
+ if (y(target) > y(pos))
+ return S;
+ }
+ return dir;
+}
+
+int Board::x(int pos)
+{
+ return pos % BoardWidth;
+}
+
+int Board::y(int pos)
+{
+ return pos/BoardWidth;
+}
+
+int Board::turn(int dir)
+{
+ switch (dir) {
+ case N : return S;
+ case NE : return SW;
+ case E : return W;
+ case SE : return NW;
+ case S : return N;
+ case SW : return NE;
+ case W : return E;
+ case NW : return SE;
+ default : return dir;
+ }
+}
+
+int Board::points()
+{
+ return numPoints;
+}
+
+int Board::energizers()
+{
+ return numEnergizers;
+}
+
+int Board::monsters()
+{
+ return numMonsters;
+}
+
+int Board::tunnels()
+{
+ return numTunnels;
+}
diff --git a/noncore/games/kpacman/board.h b/noncore/games/kpacman/board.h
new file mode 100644
index 0000000..fffde95
--- a/dev/null
+++ b/noncore/games/kpacman/board.h
@@ -0,0 +1,102 @@
+#ifndef BOARD_H
+#define BOARD_H
+
+#include <qarray.h>
+#include <qstring.h>
+#include <qlist.h>
+#include <qrect.h>
+
+#define OUT -1
+
+enum Square {out = OUT, empty, brick, prison, gate, tunnel, prisonentry, prisonexit,
+ Point, energizer, fruit, pacman, monster,
+ fruithome, pacmanhome, monsterhome};
+
+enum Image { None, Intro, Demo, Level, File };
+
+#define X -1
+#define N 0
+#define S 1
+#define E 2
+#define W 3
+#define NE 4
+#define SE 5
+#define NW 6
+#define SW 7
+
+#define BoardWidth 59
+#define BoardHeight 65
+
+#define fixBits 0x0007
+#define varBits 0xFFF8
+#define monsterBits 0xFF00
+
+#define pointBit 0x0008
+#define energizerBit 0x0010
+#define fruitBit 0x0020
+#define pacmanBit 0x0040
+#define monsterBit 0x0100
+
+class Board : public QArray<int>
+{
+public:
+ Board (int size);
+ ~Board() {};
+ void init(Image image, QString levelName=0);
+ void setup(const uchar *buf);
+
+ void set(int pos, Square sq, int m = 0);
+ void reset(int pos, Square sq, int m = 0);
+ int position(Square sq, int m = 0);
+
+ bool isOut(int pos);
+ bool isEmpty(int pos);
+ bool isBrick(int pos);
+ bool isPrison(int pos);
+ bool isGate(int pos);
+ bool isTunnel(int pos);
+ bool isPoint(int pos);
+ bool isEnergizer(int pos);
+ bool isFruit(int pos);
+ bool isPacman(int pos);
+ bool isMonster(int pos);
+ bool isWay(int pos, int dir, Square sq);
+ bool isJump(int pos, int dir);
+
+ int move(int pos, int dir, int steps = 1);
+ int closeup(int pos, int dir, int target);
+ int x(int pos);
+ int y(int pos);
+ int turn(int dir);
+
+ int points();
+ int energizers();
+ int monsters();
+ int tunnels();
+
+private:
+ bool inBounds(int pos);
+ int sz; // size of board
+
+ QString map;
+ QString mapName; // Filename of the latest loaded map
+
+ int prisonEntry; // position of prisonentry
+ int prisonExit; // position of prisonexit
+ int pacmanHome; // startposition of pacman
+ int monsterHome[8]; // startposition of monsters
+ int fruitHome; // startposition of fruit
+
+ int pacmanPosition; // actual position of pacman
+ int monsterPosition[8]; // actual position of monsters
+ int fruitPosition; // actual position of fruit
+ int energizerPosition[8]; // actual position of energizers
+ int tunnelPosition[8]; // position of tunnels
+
+ int numMonsters; // number of monsters on the board
+ int numPoints; // number of points (left) on the board
+ int numEnergizers; // number of energizers (left)
+ int numTunnels; // number of tunnels on the board
+};
+
+#endif // BOARD_H
diff --git a/noncore/games/kpacman/colors.h b/noncore/games/kpacman/colors.h
new file mode 100644
index 0000000..6abf385
--- a/dev/null
+++ b/noncore/games/kpacman/colors.h
@@ -0,0 +1,21 @@
+#ifndef COLORS_H
+#define COLORS_H
+
+#include <qcolor.h>
+
+#define BLACK QColor(Qt::black)
+#define RED QColor(Qt::red)
+#define BROWN QColor(0xde, 0x95, 0x41)
+#define PINK QColor(0xff, 0xba, 0xde)
+#define CYAN QColor(0x00, 0xff, 0xde)
+#define LIGHTBLUE QColor(0x41, 0xba, 0xde)
+#define ORANGE QColor(0xff, 0xba, 0x41)
+#define YELLOW QColor(Qt::yellow)
+#define BLUE QColor(0x20, 0x20, 0xde)
+#define GREEN QColor(Qt::green)
+#define LIGHTGREEN QColor(0x41, 0xba, 0x94)
+#define FLESH QColor(0xff, 0xba, 0x94)
+#define WHITE QColor(0xd8, 0xdc, 0xd8)
+
+#endif // COLORS_H
+
diff --git a/noncore/games/kpacman/config.cpp b/noncore/games/kpacman/config.cpp
new file mode 100644
index 0000000..b9e3607
--- a/dev/null
+++ b/noncore/games/kpacman/config.cpp
@@ -0,0 +1,394 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop 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.
+**
+** $Id$
+**
+**********************************************************************/
+
+#include "config.h"
+
+#include <qfile.h>
+#include <qdir.h>
+#include <qfileinfo.h>
+#include <qtextstream.h>
+#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
+#include <qtextcodec.h>
+#endif
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+/*!
+ \internal
+*/
+QString Config::configFilename(const QString& name, Domain d)
+{
+ switch (d) {
+ case File:
+ return name;
+ case User: {
+ QDir dir = (QString(getenv("HOME")) + "/Settings");
+ if ( !dir.exists() )
+ mkdir(dir.path().local8Bit(),0700);
+ return dir.path() + "/" + name + ".conf";
+ }
+ }
+ return name;
+}
+
+/*!
+ \class Config config.h
+ \brief The Config class provides for saving application cofniguration state.
+
+ You should keep a Config in existence only while you do not want others
+ to be able to change the state. There is no locking currently, but there
+ may be in the future.
+*/
+
+/*!
+ \enum Config::ConfigGroup
+ \internal
+*/
+
+/*!
+ \enum Config::Domain
+
+ \value File
+ \value User
+
+ See Config for details.
+*/
+
+/*!
+ Constructs a config that will load or create a configuration with the
+ given \a name in the given \a domain.
+
+ You must call setGroup() before doing much else with the Config.
+
+ In the default Domain, \e User,
+ the configuration is user-specific. \a name should not contain "/" in
+ this case, and in general should be the name of the C++ class that is
+ primarily responsible for maintaining the configuration.
+
+ In the File Domain, \a name is an absolute filename.
+*/
+Config::Config( const QString &name, Domain domain )
+ : filename( configFilename(name,domain) )
+{
+ git = groups.end();
+ read();
+
+ lang = getenv("LANG");
+ int i = lang.find(".");
+ if ( i > 0 )
+ lang = lang.left( i );
+ i = lang.find( "_" );
+ if ( i > 0 )
+ glang = lang.left(i);
+}
+
+/*!
+ Writes any changes to disk and destroys the in-memory object.
+*/
+Config::~Config()
+{
+ if ( changed )
+ write();
+}
+
+/*!
+ Returns whether the current group has an entry called \a key.
+*/
+bool Config::hasKey( const QString &key ) const
+{
+ if ( groups.end() == git )
+ return FALSE;
+ ConfigGroup::ConstIterator it = ( *git ).find( key );
+ return it != ( *git ).end();
+}
+
+/*!
+ Sets the current group for subsequent reading and writing of
+ entries to \a gname. Grouping allows the application to partition the namespace.
+
+ This function must be called prior to any reading or writing
+ of entries.
+
+ The \a gname must not be empty.
+*/
+void Config::setGroup( const QString &gname )
+{
+ QMap< QString, ConfigGroup>::Iterator it = groups.find( gname );
+ if ( it == groups.end() ) {
+ ConfigGroup *grp = new ConfigGroup;
+ git = groups.insert( gname, *grp );
+ changed = TRUE;
+ return;
+ }
+ git = it;
+}
+
+/*!
+ Writes a (\a key, \a value) entry to the current group.
+
+ \sa readEntry()
+*/
+void Config::writeEntry( const QString &key, const QString &value )
+{
+ if ( git == groups.end() ) {
+ qWarning( "no group set" );
+ return;
+ }
+ if ( (*git)[key] != value ) {
+ ( *git ).insert( key, value );
+ changed = TRUE;
+ }
+}
+
+/*!
+ Writes a (\a key, \a num) entry to the current group.
+
+ \sa readNumEntry()
+*/
+void Config::writeEntry( const QString &key, int num )
+{
+ QString s;
+ s.setNum( num );
+ writeEntry( key, s );
+}
+
+#ifdef Q_HAS_BOOL_TYPE
+/*!
+ Writes a (\a key, \a b) entry to the current group.
+
+ \sa readBoolEntry()
+*/
+void Config::writeEntry( const QString &key, bool b )
+{
+ QString s;
+ s.setNum( ( int )b );
+ writeEntry( key, s );
+}
+#endif
+
+/*!
+ Writes a (\a key, \a lst) entry to the current group. The list
+ is separated by \a sep, so the strings must not contain that character.
+
+ \sa readListEntry()
+*/
+void Config::writeEntry( const QString &key, const QStringList &lst, const QChar &sep )
+{
+ QString s;
+ QStringList::ConstIterator it = lst.begin();
+ for ( ; it != lst.end(); ++it )
+ s += *it + sep;
+ writeEntry( key, s );
+}
+
+
+
+/*!
+ Reads a string entry stored with \a key, defaulting to \a deflt if there is no entry.
+*/
+QString Config::readEntry( const QString &key, const QString &deflt )
+{
+ QString res = readEntryDirect( key+"["+lang+"]" );
+ if ( !res.isNull() )
+ return res;
+ if ( !glang.isEmpty() ) {
+ res = readEntryDirect( key+"["+glang+"]" );
+ if ( !res.isNull() )
+ return res;
+ }
+ return readEntryDirect( key, deflt );
+}
+
+/*!
+ \internal
+*/
+QString Config::readEntryDirect( const QString &key, const QString &deflt )
+{
+ if ( git == groups.end() ) {
+ //qWarning( "no group set" );
+ return deflt;
+ }
+ ConfigGroup::Iterator it = ( *git ).find( key );
+ if ( it != ( *git ).end() )
+ return *it;
+ else
+ return deflt;
+}
+
+/*!
+ Reads a numeric entry stored with \a key, defaulting to \a deflt if there is no entry.
+*/
+int Config::readNumEntry( const QString &key, int deflt )
+{
+ QString s = readEntry( key );
+ if ( s.isEmpty() )
+ return deflt;
+ else
+ return s.toInt();
+}
+
+/*!
+ Reads a bool entry stored with \a key, defaulting to \a deflt if there is no entry.
+*/
+bool Config::readBoolEntry( const QString &key, bool deflt )
+{
+ QString s = readEntry( key );
+ if ( s.isEmpty() )
+ return deflt;
+ else
+ return (bool)s.toInt();
+}
+
+/*!
+ Reads a string list entry stored with \a key, and with \a sep as the separator.
+*/
+QStringList Config::readListEntry( const QString &key, const QChar &sep )
+{
+ QString s = readEntry( key );
+ if ( s.isEmpty() )
+ return QStringList();
+ else
+ return QStringList::split( sep, s );
+}
+
+/*!
+ Removes all entries from the current group.
+*/
+void Config::clearGroup()
+{
+ if ( git == groups.end() ) {
+ qWarning( "no group set" );
+ return;
+ }
+ if ( !(*git).isEmpty() ) {
+ ( *git ).clear();
+ changed = TRUE;
+ }
+}
+
+/*!
+ \internal
+*/
+void Config::write( const QString &fn )
+{
+ if ( !fn.isEmpty() )
+ filename = fn;
+
+ QFile f( filename );
+ if ( !f.open( IO_WriteOnly ) ) {
+ qWarning( "could not open for writing `%s'", filename.latin1() );
+ git = groups.end();
+ return;
+ }
+
+ QTextStream s( &f );
+#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
+ // The below should work, but doesn't in Qt 2.3.0
+ s.setCodec( QTextCodec::codecForMib( 106 ) );
+#else
+ s.setEncoding( QTextStream::UnicodeUTF8 );
+#endif
+ QMap< QString, ConfigGroup >::Iterator g_it = groups.begin();
+ for ( ; g_it != groups.end(); ++g_it ) {
+ s << "[" << g_it.key() << "]" << "\n";
+ ConfigGroup::Iterator e_it = ( *g_it ).begin();
+ for ( ; e_it != ( *g_it ).end(); ++e_it )
+ s << e_it.key() << " = " << *e_it << "\n";
+ }
+
+ f.close();
+}
+
+/*!
+ Returns whether the Config is in a valid state.
+*/
+bool Config::isValid() const
+{
+ return groups.end() != git;
+}
+
+/*!
+ \internal
+*/
+void Config::read()
+{
+ changed = FALSE;
+
+ if ( !QFileInfo( filename ).exists() ) {
+ git = groups.end();
+ return;
+ }
+
+ QFile f( filename );
+ if ( !f.open( IO_ReadOnly ) ) {
+ git = groups.end();
+ return;
+ }
+
+ QTextStream s( &f );
+#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
+ // The below should work, but doesn't in Qt 2.3.0
+ s.setCodec( QTextCodec::codecForMib( 106 ) );
+#else
+ s.setEncoding( QTextStream::UnicodeUTF8 );
+#endif
+
+ QString line;
+ while ( !s.atEnd() ) {
+ line = s.readLine();
+ if ( !parse( line ) ) {
+ git = groups.end();
+ return;
+ }
+ }
+
+ f.close();
+}
+
+/*!
+ \internal
+*/
+bool Config::parse( const QString &l )
+{
+ QString line = l.stripWhiteSpace();
+ if ( line[ 0 ] == QChar( '[' ) ) {
+ QString gname = line;
+ gname = gname.remove( 0, 1 );
+ if ( gname[ (int)gname.length() - 1 ] == QChar( ']' ) )
+ gname = gname.remove( gname.length() - 1, 1 );
+ ConfigGroup *grp = new ConfigGroup;
+ git = groups.insert( gname, *grp );
+ } else if ( !line.isEmpty() ) {
+ if ( git == groups.end() )
+ return FALSE;
+ int eq = line.find( '=' );
+ if ( eq == -1 )
+ return FALSE;
+ QString key = line.left(eq).stripWhiteSpace();
+ QString value = line.mid(eq+1).stripWhiteSpace();
+ ( *git ).insert( key, value );
+ }
+ return TRUE;
+}
diff --git a/noncore/games/kpacman/config.h b/noncore/games/kpacman/config.h
new file mode 100644
index 0000000..3c26b5d
--- a/dev/null
+++ b/noncore/games/kpacman/config.h
@@ -0,0 +1,74 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Designer.
+**
+** 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 CONFIG_H
+#define CONFIG_H
+
+// ##### could use QSettings with Qt 3.0
+
+#include <qmap.h>
+#include <qstringlist.h>
+
+class ConfigPrivate;
+class Config
+{
+public:
+ typedef QMap< QString, QString > ConfigGroup;
+
+ enum Domain { File, User };
+ Config( const QString &name, Domain domain=User );
+ ~Config();
+
+ bool isValid() const;
+ bool hasKey( const QString &key ) const;
+
+ void setGroup( const QString &gname );
+ void writeEntry( const QString &key, const QString &value );
+ void writeEntry( const QString &key, int num );
+#ifdef Q_HAS_BOOL_TYPE
+ void writeEntry( const QString &key, bool b );
+#endif
+ void writeEntry( const QString &key, const QStringList &lst, const QChar &sep );
+
+ QString readEntry( const QString &key, const QString &deflt = QString::null );
+ QString readEntryDirect( const QString &key, const QString &deflt = QString::null );
+ int readNumEntry( const QString &key, int deflt = -1 );
+ bool readBoolEntry( const QString &key, bool deflt = FALSE );
+ QStringList readListEntry( const QString &key, const QChar &sep );
+
+ void clearGroup();
+
+ void write( const QString &fn = QString::null );
+
+protected:
+ void read();
+ bool parse( const QString &line );
+
+ QMap< QString, ConfigGroup > groups;
+ QMap< QString, ConfigGroup >::Iterator git;
+ QString filename;
+ QString lang;
+ QString glang;
+ bool changed;
+ ConfigPrivate *d;
+ static QString configFilename(const QString& name, Domain);
+};
+
+#endif
diff --git a/noncore/games/kpacman/energizer.cpp b/noncore/games/kpacman/energizer.cpp
new file mode 100644
index 0000000..ca08f3b
--- a/dev/null
+++ b/noncore/games/kpacman/energizer.cpp
@@ -0,0 +1,61 @@
+#include "energizer.h"
+
+Energizer::Energizer(Board *b)
+{
+ board = b;
+ setOn();
+ actualPosition = OUT;
+ maxPixmaps = 0;
+}
+
+void Energizer::setMaxPixmaps(int max)
+{
+ maxPixmaps = max;
+}
+
+void Energizer::setOff()
+{
+ actualState = off;
+}
+
+void Energizer::setOn()
+{
+ actualState = on;
+ actualPix = 0;
+}
+
+void Energizer::setPosition(int pos)
+{
+ board->reset(actualPosition, energizer);
+ actualPosition = pos;
+ board->set(actualPosition, energizer);
+}
+
+energizerState Energizer::state()
+{
+ return actualState;
+}
+
+int Energizer::position()
+{
+ return actualPosition;
+}
+
+bool Energizer::move()
+{
+ if (actualPosition == OUT)
+ return FALSE;
+
+ if (++actualPix >= maxPixmaps)
+ actualPix = 0;
+
+ return TRUE;
+}
+
+int Energizer::pix()
+{
+ if (actualPosition == OUT || actualState == off)
+ return -1;
+
+ return actualPix;
+}
diff --git a/noncore/games/kpacman/energizer.h b/noncore/games/kpacman/energizer.h
new file mode 100644
index 0000000..377cd02
--- a/dev/null
+++ b/noncore/games/kpacman/energizer.h
@@ -0,0 +1,30 @@
+#ifndef ENERGIZER_H
+#define ENERGIZER_H
+
+#include "board.h"
+
+enum energizerState { on, off };
+
+class Energizer {
+public:
+ Energizer(Board *b);
+ void setMaxPixmaps(int max);
+ void setOff();
+ void setOn();
+ void setPosition(int pos);
+ energizerState state();
+ int position();
+ bool move();
+ int pix();
+
+private:
+ Board *board;
+
+ energizerState actualState; // the state of energizer
+
+ int actualPix; // last Pixmap-index
+ int maxPixmaps; // Number of Pixmaps (1..)
+ int actualPosition; // actual position on board
+};
+
+#endif // ENERGIZER_H
diff --git a/noncore/games/kpacman/fruit.cpp b/noncore/games/kpacman/fruit.cpp
new file mode 100644
index 0000000..e6ad2d5
--- a/dev/null
+++ b/noncore/games/kpacman/fruit.cpp
@@ -0,0 +1,176 @@
+#include <stdlib.h>
+
+#include "fruit.h"
+
+Fruit::Fruit(Board *b)
+{
+ board = b;
+ maxPixmaps = 0;
+ setLevel(0, 0, 0, 0);
+}
+
+void Fruit::setEaten(int duration)
+{
+ actualState = eaten;
+ timeLeft = duration;
+ actualDirection = X;
+}
+
+void Fruit::setLevel(int level, int wDuration, int fDuration, int ticks)
+{
+ actualLevel = level;
+ waitDuration = wDuration;
+ fruitDuration = fDuration;
+ pauseDuration = ticks;
+ pause = 0;
+ actualState = inactive;
+ timeLeft = waitDuration;
+ lastPosition = OUT;
+ setPosition(OUT);
+ setMovement(OUT, OUT, 0);
+ actualDirection = X;
+ setMaxPixmaps(maxPixmaps);
+}
+
+void Fruit::setMaxPixmaps(int max)
+{
+ maxPixmaps = max;
+ if (actualLevel-1 < maxPixmaps)
+ actualPix = actualLevel == 0 ? 0 : actualLevel-1;
+ else if (maxPixmaps > 0)
+ actualPix = rand() % maxPixmaps;
+ else
+ actualPix = -1;
+}
+
+void Fruit::setMovement(int entry, int tunnel, int iq)
+{
+ homePosition = board->position(fruithome);
+ entryPosition = entry;
+ tunnelPosition = tunnel;
+ IQ = iq;
+}
+
+void Fruit::setPosition(int pos)
+{
+ board->reset(lastPosition, fruit);
+ actualPosition = lastPosition = pos;
+ board->set(actualPosition, fruit);
+}
+
+void Fruit::setDirection(int dir)
+{
+ actualDirection = dir;
+}
+
+fruitState Fruit::state()
+{
+ return actualState;
+}
+
+int Fruit::position()
+{
+ return actualPosition;
+}
+
+int Fruit::direction()
+{
+ return actualDirection;
+}
+
+bool Fruit::move(bool activate)
+{
+ if (timeLeft > 0) {
+ timeLeft--;
+ }
+
+ if (actualDirection == X || actualState == inactive) {
+ if (timeLeft == 0 || (activate && actualState == inactive)) {
+ if (actualState == inactive) {
+ if (entryPosition == OUT || tunnelPosition == OUT) {
+ setPosition(board->position(fruithome));
+ } else {
+ setPosition(entryPosition);
+ actualDirection = 0;
+ while (!board->isWay(actualPosition, actualDirection, empty) ||
+ board->isJump(actualPosition, actualDirection))
+ actualDirection++;
+ }
+ timeLeft = fruitDuration;
+ setMaxPixmaps(maxPixmaps);
+ actualState = active;
+ } else {
+ actualState = inactive;
+ setPosition(OUT);
+ timeLeft = waitDuration;
+ actualDirection = X;
+ }
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ if (pause-- > 0)
+ return FALSE;
+ else
+ pause = pauseDuration;
+
+ if (actualPosition == OUT)
+ return FALSE;
+
+ if (actualDirection == X)
+ return TRUE;
+
+ int d = actualDirection;
+
+ if (rand() % (int) ((190-IQ)/10) == 0)
+ if (timeLeft > 0) // coming home or leaving again
+ d = board->closeup(actualPosition, d, homePosition);
+ else
+ d = board->closeup(actualPosition, d, tunnelPosition);
+ else
+ do // try new direction, but not the opposite
+ d = rand() % 4; // direction, to prevent hectic movement.
+ while (d == board->turn(actualDirection));
+
+ while ((!board->isWay(actualPosition, d, empty) &&
+ !board->isWay(actualPosition, d, tunnel)) ||
+ d == board->turn(actualDirection)) {
+ if (d != actualDirection) // if new direction is not possible,
+ d = actualDirection; // try current direction first.
+ else
+ d = rand() % 4;
+ }
+
+ actualDirection = d;
+ actualPosition = board->move(actualPosition, actualDirection);
+
+ if (actualPosition == homePosition) {
+ timeLeft = 0;
+ }
+
+ if (board->isTunnel(actualPosition)) {
+ setPosition(OUT);
+ timeLeft = waitDuration;
+ actualState = inactive;
+ actualDirection = X;
+ if (board->tunnels() > 0) {
+ entryPosition = board->position(tunnel, rand() % board->tunnels());
+ tunnelPosition = board->position(tunnel, rand() % board->tunnels());
+ }
+ }
+
+ if (actualPosition != lastPosition) {
+ setPosition(actualPosition);
+ }
+
+ return TRUE;
+}
+
+int Fruit::pix()
+{
+ if (actualPosition == OUT || actualState == inactive)
+ return -1;
+ else
+ return actualPix;
+}
diff --git a/noncore/games/kpacman/fruit.h b/noncore/games/kpacman/fruit.h
new file mode 100644
index 0000000..fbbd9c0
--- a/dev/null
+++ b/noncore/games/kpacman/fruit.h
@@ -0,0 +1,53 @@
+#ifndef FRUIT_H
+#define FRUIT_H
+
+#include <stdlib.h>
+
+#include "board.h"
+
+enum fruitState { inactive, active, eaten };
+
+class Fruit {
+public:
+ Fruit(Board *b);
+ void setEaten(int duration);
+ void setLevel(int level, int wDuration, int fDuration, int ticks = -1);
+ void setMaxPixmaps(int max);
+ void setMovement(int entry, int tunnel, int iq);
+ void setPosition(int pos);
+ void setDirection(int dir);
+ fruitState state();
+ int position();
+ int direction();
+ bool move(bool activate=FALSE);
+ int pix();
+
+private:
+ Board *board;
+
+ int IQ; // Intelligence of movement (0 = dumb..180=smart)
+
+ fruitState actualState; // the state of fruit
+
+ int pauseDuration; // number of ticks before next movement
+ int pause; // actual ticks before movement (0 = move)
+
+ int timeLeft; // Ticks remaining of current state
+
+ int waitDuration; // Time before fruit appears
+ int fruitDuration; // Length of active-time in ticks
+
+ int actualDirection; // actual direction of the fruit
+ int actualPosition; // actual position on board
+ int lastPosition; // the last position of the fruit
+ int actualLevel; // level for kind of fruit and score
+ int actualPix;
+ int maxPixmaps; // Number of Pixmaps (1..)
+
+ int entryPosition; // where to come in
+ int homePosition; // where to go, on the way in
+ int tunnelPosition; // where to exit
+};
+
+#endif // FRUIT_H
+
diff --git a/noncore/games/kpacman/keys.cpp b/noncore/games/kpacman/keys.cpp
new file mode 100644
index 0000000..c609373
--- a/dev/null
+++ b/noncore/games/kpacman/keys.cpp
@@ -0,0 +1,203 @@
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <kapp.h>
+#include <kconfig.h>
+#include <klocale.h>
+#include <kstddirs.h>
+#include <kaccel.h>
+
+#include <keys.h>
+#include <keys.moc>
+#elif defined( QPE_PORT )
+#include <qaccel.h>
+#include <qpe/qpeapplication.h>
+#include "config.h"
+#include "keys.h"
+#endif
+
+#include <qpushbt.h>
+#include <qlabel.h>
+#include <qframe.h>
+#include <qkeycode.h>
+#include <qpixmap.h>
+#include <qstring.h>
+
+Keys::Keys( QWidget *parent, const char *name)
+ : QDialog( parent, name, TRUE )
+{
+ //KStandardDirs *dirs = KGlobal::dirs();
+
+ QPushButton *okButton = new QPushButton(this);
+ okButton->setText(i18n("Ok"));
+ okButton->setFixedSize(okButton->size());
+ connect( okButton, SIGNAL(clicked()),this, SLOT(ok()) );
+ okButton->move(20,210);
+
+ QPushButton *defaultButton = new QPushButton(this);
+ defaultButton->setText(i18n("Defaults"));
+ defaultButton->setFixedSize(defaultButton->size());
+ connect( defaultButton, SIGNAL(clicked()),this, SLOT(defaults()) );
+ defaultButton->move(140,210);
+
+ QPushButton *cancelButton = new QPushButton(this);
+ cancelButton->setText(i18n("Cancel"));
+ cancelButton->setFixedSize(cancelButton->size());
+ connect( cancelButton, SIGNAL(clicked()),this, SLOT(reject()) );
+ cancelButton->move(260,210);
+
+ QFrame *separator = new QFrame(this);
+ separator->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+ separator->setGeometry( 20, 190, 340, 4 );
+
+ for ( int x = 0; x < 4; x++) {
+ QLabel *l = new QLabel(this);
+ l->setAlignment(AlignCenter);
+ labels[x] = l;
+ }
+
+ labels[0]->setGeometry(120, 20, 140, 20 );
+ labels[1]->setGeometry(120,160, 140, 20 );
+ labels[2]->setGeometry( 20, 92, 100, 20 );
+ labels[3]->setGeometry(265, 92, 100, 20 );
+
+ QString pixPath;
+
+ QPushButton *up = new QPushButton(this);
+ pixPath = FIND_APP_DATA( "pics/up.xpm" );
+ up->setPixmap( QPixmap(pixPath));
+ up->setFixedSize(up->pixmap()->size());
+ connect( up, SIGNAL(clicked()),this, SLOT(butUp()) );
+ up->move(180, 50);
+
+ QPushButton *down = new QPushButton(this);
+ pixPath = FIND_APP_DATA( "pics/down.xpm");
+ down->setPixmap( QPixmap(pixPath));
+ down->setFixedSize(down->pixmap()->size());
+ connect( down, SIGNAL(clicked()),this, SLOT(butDown()) );
+ down->move(180, 130);
+
+ QPushButton *left = new QPushButton(this);
+ pixPath = FIND_APP_DATA( "pics/left.xpm");
+ left->setPixmap( QPixmap(pixPath));
+ left->setFixedSize(left->pixmap()->size());
+ connect( left, SIGNAL(clicked()),this, SLOT(butLeft()) );
+ left->move(140, 90);
+
+ QPushButton *right = new QPushButton(this);
+ pixPath = FIND_APP_DATA( "pics/right.xpm");
+ right->setPixmap( QPixmap(pixPath));
+ right->setFixedSize(right->pixmap()->size());
+ connect( right, SIGNAL(clicked()),this, SLOT(butRight()) );
+ right->move(220, 90);
+
+
+ setCaption(i18n("Change Direction Keys"));
+ setFixedSize(380, 260);
+ lab = 0;
+ init();
+}
+
+void Keys::keyPressEvent( QKeyEvent *e )
+{
+ uint kCode = e->key() & ~(SHIFT | CTRL | ALT);
+ QString string = KAccel::keyToString(kCode);
+
+ if (lab != 0) {
+ if ( string.isNull() )
+ lab->setText(i18n("Undefined key"));
+ else
+ lab->setText(string);
+ }
+ else if ( lab == 0 && e->key() == Key_Escape)
+ reject();
+}
+
+void Keys::butUp()
+{
+ getKey(0);
+}
+
+void Keys::butDown()
+{
+ getKey(1);
+}
+
+void Keys::butLeft()
+{
+ getKey(2);
+}
+
+void Keys::butRight()
+{
+ getKey(3);
+}
+
+void Keys::getKey(int i)
+{
+ if ( lab != 0)
+ focusOut(lab);
+
+ focusIn(labels[i]);
+}
+
+void Keys::focusOut(QLabel *l)
+{
+ l->setFrameStyle( QFrame::NoFrame );
+ l->setBackgroundColor(backgroundColor());
+ l->repaint();
+}
+
+void Keys::focusIn(QLabel *l)
+{
+ lab = l;
+ lab->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ lab->setBackgroundColor(white);
+ lab->repaint();
+}
+
+void Keys::defaults()
+{
+ if ( lab != 0)
+ focusOut(lab);
+
+ lab = 0;
+
+ labels[0]->setText("Up");
+ labels[1]->setText("Down");
+ labels[2]->setText("Left");
+ labels[3]->setText("Right");
+}
+
+void Keys::init()
+{
+ APP_CONFIG_BEGIN( cfg );
+ QString up("Up");
+ up = cfg->readEntry("upKey", (const char*) up);
+ labels[0]->setText(up);
+
+ QString down("Down");
+ down = cfg->readEntry("downKey", (const char*) down);
+ labels[1]->setText(down);
+
+ QString left("Left");
+ left = cfg->readEntry("leftKey", (const char*) left);
+ labels[2]->setText(left);
+
+ QString right("Right");
+ right = cfg->readEntry("rightKey", (const char*) right);
+ labels[3]->setText(right);
+ APP_CONFIG_END( cfg );
+}
+
+void Keys::ok()
+{
+ APP_CONFIG_BEGIN( cfg );
+ cfg->writeEntry("upKey", (const char*) labels[0]->text() );
+ cfg->writeEntry("downKey", (const char*) labels[1]->text() );
+ cfg->writeEntry("leftKey", (const char*) labels[2]->text() );
+ cfg->writeEntry("rightKey",(const char*) labels[3]->text() );
+ APP_CONFIG_END( cfg );
+ accept();
+}
diff --git a/noncore/games/kpacman/keys.h b/noncore/games/kpacman/keys.h
new file mode 100644
index 0000000..c0c9d82
--- a/dev/null
+++ b/noncore/games/kpacman/keys.h
@@ -0,0 +1,48 @@
+#ifndef KEYS_H
+#define KEYS_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <kapp.h>
+#include <kaccel.h>
+#endif
+
+#include <qdialog.h>
+#include <qlabel.h>
+#include <qstring.h>
+
+class Keys : public QDialog
+{
+ Q_OBJECT
+public:
+ Keys( QWidget *parent=0, const char *name=0 );
+
+private slots:
+ void butRight();
+ void butLeft();
+ void butUp();
+ void butDown();
+
+ void getKey(int);
+ void defaults();
+ void focusIn(QLabel *);
+ void focusOut(QLabel *);
+
+ void ok();
+
+protected:
+ void keyPressEvent( QKeyEvent * );
+
+private:
+ void init();
+
+ QLabel *labels[4];
+ QLabel *lab;
+};
+
+#endif // KEYS_H
diff --git a/noncore/games/kpacman/kpacman.cpp b/noncore/games/kpacman/kpacman.cpp
new file mode 100644
index 0000000..4077085
--- a/dev/null
+++ b/noncore/games/kpacman/kpacman.cpp
@@ -0,0 +1,369 @@
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <kpacman.h>
+#include <kpacman.moc>
+#include <kcolordlg.h>
+#elif defined( QPE_PORT )
+#include <qmenubar.h>
+#include "config.h"
+#include <qapplication.h>
+#include "kpacman.h"
+#endif
+
+#include <qkeycode.h>
+#include <qcolor.h>
+#include <qstring.h>
+#include <qpopmenu.h>
+#include <qmsgbox.h>
+
+Kpacman::Kpacman(QWidget *parent, const char *name)
+ : KTMainWindow(parent, name)
+{
+ schemesPopup = new QList<QPopupMenu>;
+ schemesPopup->setAutoDelete(TRUE);
+
+ menu();
+
+ view = new KpacmanWidget( this, QString(name)+"widget");
+
+#ifndef QWS
+ setFixedSize(view->width(), view->height());
+#else
+ setCaption( "Kpacman" );
+#endif
+
+ view->referee->setFocus();
+
+ connect(view->referee, SIGNAL(setScore(int, int)),
+ view->score, SLOT(setScore(int, int)));
+ connect(view->referee, SIGNAL(setPoints(int)),
+ view->score, SLOT(set(int)));
+ connect(view->referee, SIGNAL(setLifes(int)),
+ view->status, SLOT(setLifes(int)));
+ connect(view->referee, SIGNAL(setLevel(int)),
+ view->status, SLOT(setLevel(int)));
+ connect(view->referee, SIGNAL(forcedHallOfFame(bool)),
+ this, SLOT(forcedHallOfFame(bool)));
+ connect(view->referee, SIGNAL(togglePaused()), this, SLOT(togglePaused()));
+ connect(view->referee, SIGNAL(toggleNew()), this, SLOT(toggleNew()));
+
+ connect(view->score, SIGNAL(toggleNew()), this, SLOT(toggleNew()));
+ connect(view->score, SIGNAL(forcedHallOfFame(bool)),
+ this, SLOT(forcedHallOfFame(bool)));
+
+ APP_CONFIG_BEGIN( cfg );
+ focusOutPause = !cfg->readBoolEntry("FocusOutPause", TRUE);
+ focusInContinue = !cfg->readBoolEntry("FocusInContinue", TRUE);
+ hideMouseCursor = !cfg->readBoolEntry("HideMouseCursor", TRUE);
+ APP_CONFIG_END( cfg );
+
+ toggleFocusOutPause();
+ toggleFocusInContinue();
+ toggleHideMouseCursor();
+
+#ifndef QWS
+ menuBar->show();
+ view->show();
+ setMenu(menuBar);
+ setView(view);
+#else
+ setCentralWidget( view );
+#endif
+}
+
+Kpacman::~Kpacman()
+{
+ APP_CONFIG_BEGIN( cfg );
+ cfg->writeEntry("FocusOutPause", focusOutPause);
+ cfg->writeEntry("FocusInContinue", focusInContinue);
+ cfg->writeEntry("HideMouseCursor", hideMouseCursor);
+ APP_CONFIG_END( cfg );
+ delete _menuBar;
+}
+
+void Kpacman::menu()
+{
+ gamePopup = new QPopupMenu();
+ CHECK_PTR( gamePopup );
+ newID = gamePopup->insertItem(i18n("&New"), this, SLOT(newKpacman()),Key_F2);
+ pauseID = gamePopup->insertItem(i18n("&Pause"),
+ this, SLOT(pauseKpacman()), Key_F3);
+ hofID = gamePopup->insertItem(i18n("&Hall of fame"),
+ this, SLOT(toggleHallOfFame()), Key_F4);
+ gamePopup->insertSeparator();
+ gamePopup->insertItem(i18n("&Quit"), this, SLOT(quitKpacman()), CTRL+Key_Q);
+ gamePopup->setCheckable(TRUE);
+
+ optionsPopup = new QPopupMenu();
+ CHECK_PTR(optionsPopup);
+
+ modesPopup = new QPopupMenu();
+ CHECK_PTR(modesPopup);
+
+ hideMouseCursorID = optionsPopup->insertItem(i18n("&Hide Mousecursor"),
+ this, SLOT(toggleHideMouseCursor()),
+ CTRL+Key_H);
+ optionsPopup->insertSeparator();
+
+ if (lookupSchemes() > 0) {
+ optionsPopup->insertItem(i18n("&Select graphic scheme"), modesPopup);
+ optionsPopup->insertSeparator();
+ }
+
+ focusOutPauseID = optionsPopup->insertItem(i18n("&Pause in Background"),
+ this, SLOT(toggleFocusOutPause()));
+ focusInContinueID = optionsPopup->insertItem(i18n("&Continue in Foreground"),
+ this, SLOT(toggleFocusInContinue()));
+ optionsPopup->insertSeparator();
+
+ optionsPopup->insertItem(i18n("Change &keys..."), this, SLOT(confKeys()));
+
+#ifndef QWS
+ QString aboutText = i18n("@PACKAGE@ - @VERSION@\n\n"
+ "Joerg Thoennissen (joe@dsite.de)\n\n"
+ "A pacman game for the KDE Desktop\n\n"
+ "The program based on the source of ksnake\n"
+ "by Michel Filippi (mfilippi@sade.rhein-main.de).\n"
+ "The design was strongly influenced by the pacman\n"
+ "(c) 1980 MIDWAY MFG.CO.\n\n"
+ "I like to thank my girlfriend Elke Krueers for\n"
+ "the last 10 years of her friendship.\n");
+ aboutText.replace(QRegExp("@PACKAGE@"), PACKAGE);
+ aboutText.replace(QRegExp("@VERSION@"), VERSION);
+ QPopupMenu *helpPopup = helpMenu(aboutText, FALSE);
+#endif
+
+ //_menuBar = new KMenuBar(this);
+ //CHECK_PTR( _menuBar );
+ //_menuBar->insertItem(i18n("&Game"), gamePopup);
+ //_menuBar->insertItem(i18n("&Options"), optionsPopup);
+ //_menuBar->insertSeparator();
+#ifndef QWS
+ _menuBar->insertItem(i18n("&Help"), helpPopup);
+#endif
+}
+
+int Kpacman::lookupSchemes()
+{
+ APP_CONFIG_BEGIN( cfg );
+ int ModeCount = cfg->readNumEntry("ModeCount", -1);
+ int Mode = cfg->readNumEntry("Mode", -1);
+ int SchemeCount = cfg->readNumEntry("SchemeCount");
+ int Scheme = cfg->readNumEntry("Scheme", -1);
+
+ if (SchemeCount == 0 || Scheme == -1) {
+ QMessageBox::warning(this, i18n("Configuration Error"),
+ i18n("There are no schemes defined,\n"
+ "or no scheme is selected."));
+ APP_CONFIG_END( cfg );
+ return 0;
+ }
+
+ connect(modesPopup, SIGNAL(activated(int)), this, SLOT(schemeChecked(int)));
+ modeID.resize(ModeCount > 0 ? ModeCount : 0);
+
+ if (!schemesPopup->isEmpty())
+ schemesPopup->clear();
+
+ SAVE_CONFIG_GROUP( cfg, oldgroup );
+
+ QString ModeGroup;
+ QString ModeName;
+
+ for (int m = 0; m < ModeCount; m++) {
+ ModeGroup.sprintf("Mode %d", m);
+ cfg->setGroup(ModeGroup);
+
+ ModeName = cfg->readEntry("Description", ModeGroup);
+
+ QPopupMenu *p = new QPopupMenu;
+ p->setCheckable(TRUE);
+ connect(p, SIGNAL(activated(int)), this, SLOT(schemeChecked(int)));
+ schemesPopup->append(p);
+
+ modeID[m] = modesPopup->insertItem(ModeName, schemesPopup->at(m));
+ modesPopup->setItemEnabled(modeID[m], FALSE);
+ modesPopup->setItemChecked(modeID[m], m == Mode);
+ }
+
+ schemeID.resize(SchemeCount);
+ schemeMode.resize(SchemeCount);
+
+ QString SchemeGroup;
+ QString SchemeName;
+ int SchemeMode;
+
+ for (int i = 0; i < SchemeCount; i++) {
+ SchemeGroup.sprintf("Scheme %d", i);
+ cfg->setGroup(SchemeGroup);
+
+ SchemeName = cfg->readEntry("Description", SchemeGroup);
+ SchemeMode = cfg->readNumEntry("Mode", -1);
+
+ schemeMode[i] = SchemeMode;
+ if (SchemeMode == -1) {
+ schemeID[i] = modesPopup->insertItem(SchemeName);
+ modesPopup->setItemChecked(schemeID[i], i == Scheme);
+ } else {
+ schemeID[i] = schemesPopup->at(SchemeMode)->insertItem(SchemeName);
+ schemesPopup->at(SchemeMode)->
+ setItemChecked(schemeID[i], i == Scheme);
+ modesPopup->setItemEnabled(modeID[SchemeMode], TRUE);
+ }
+ }
+
+ RESTORE_CONFIG_GROUP( cfg, oldgroup );
+
+ APP_CONFIG_END( cfg );
+ return SchemeCount;
+}
+
+void Kpacman::quitKpacman()
+{
+ APP_QUIT();
+}
+
+void Kpacman::newKpacman()
+{
+ if (!gamePopup->isItemEnabled(hofID))
+ gamePopup->setItemEnabled(hofID, TRUE);
+
+ if (gamePopup->isItemChecked(hofID))
+ toggleHallOfFame();
+
+ if (gamePopup->isItemChecked(pauseID))
+ pauseKpacman();
+
+ view->referee->play();
+}
+
+void Kpacman::pauseKpacman()
+{
+ view->referee->pause();
+ view->score->setPause(gamePopup->isItemChecked(pauseID));
+}
+
+void Kpacman::toggleHallOfFame()
+{
+ gamePopup->setItemChecked(hofID, !gamePopup->isItemChecked(hofID));
+ view->referee->toggleHallOfFame();
+
+ if (gamePopup->isItemChecked(hofID)) {
+ view->referee->lower();
+ view->status->lower();
+ } else {
+ view->status->raise();
+ view->referee->raise();
+ view->referee->setFocus();
+ }
+}
+
+/*
+ * Disable or enable the "Hall of fame"-menuitem if the referee says so.
+ * This is done, to disable turning off the "hall of fame"-display, in the automated
+ * sequence of displaying the introduction, the demonstration (or playing) and the
+ * hall of fame.
+ * If on == TRUE then also lower the referee and the status widgets.
+ */
+void Kpacman::forcedHallOfFame(bool on)
+{
+ if (!on && !gamePopup->isItemChecked(hofID))
+ return;
+
+ gamePopup->setItemEnabled(hofID, !on);
+ gamePopup->setItemChecked(hofID, on);
+
+ view->referee->toggleHallOfFame();
+ if (on) {
+ view->referee->lower();
+ view->status->lower();
+ } else {
+ view->status->raise();
+ view->referee->raise();
+ view->referee->setFocus();
+ view->referee->intro();
+ }
+}
+
+void Kpacman::togglePaused()
+{
+ static bool checked = FALSE;
+ checked = !checked;
+ gamePopup->setItemChecked( pauseID, checked );
+ view->score->setPause(gamePopup->isItemChecked(pauseID));
+}
+
+/*
+ * This disables the "New Game" menuitem to prevent interruptions of the current
+ * play.
+ */
+void Kpacman::toggleNew()
+{
+ gamePopup->setItemEnabled(newID, !gamePopup->isItemEnabled(newID));
+}
+
+void Kpacman::toggleHideMouseCursor()
+{
+ hideMouseCursor = !hideMouseCursor;
+ optionsPopup->setItemChecked(hideMouseCursorID, hideMouseCursor);
+ if (hideMouseCursor)
+ view->setCursor(blankCursor);
+ else
+ view->setCursor(arrowCursor);
+}
+
+void Kpacman::toggleFocusOutPause()
+{
+ focusOutPause = !focusOutPause;
+ optionsPopup->setItemChecked(focusOutPauseID, focusOutPause);
+ view->referee->setFocusOutPause(focusOutPause);
+}
+
+void Kpacman::toggleFocusInContinue()
+{
+ focusInContinue = !focusInContinue;
+ optionsPopup->setItemChecked(focusInContinueID, focusInContinue);
+ view->referee->setFocusInContinue(focusInContinue);
+}
+
+void Kpacman::confKeys()
+{
+ Keys *keys = new Keys();
+ if (keys->exec() == QDialog::Accepted) {
+ view->referee->initKeys();
+ view->score->initKeys();
+ }
+ delete keys;
+}
+
+void Kpacman::schemeChecked(int id)
+{
+ int mode = 0, scheme = -1;
+
+ for (uint s = 0; s < schemeID.size(); s++) {
+ if (schemeID[s] == id) {
+ scheme = s;
+ mode = schemeMode[s];
+ }
+ if (schemeMode[s] == -1) {
+ modesPopup->setItemChecked(schemeID[s], schemeID[s] == id);
+ } else {
+ modesPopup->setItemChecked(modeID[schemeMode[s]], schemeMode[s] == mode);
+ schemesPopup->at(schemeMode[s])->setItemChecked(schemeID[s], schemeID[s] == id);
+ }
+ }
+
+ APP_CONFIG_BEGIN( cfg );
+ cfg->writeEntry("Scheme", scheme);
+ cfg->writeEntry("Mode", mode);
+ APP_CONFIG_END( cfg );
+
+ view->setScheme(scheme, mode);
+ view->updateGeometry();
+ updateGeometry();
+ update();
+ repaint(TRUE);
+ show();
+}
diff --git a/noncore/games/kpacman/kpacman.h b/noncore/games/kpacman/kpacman.h
new file mode 100644
index 0000000..d7de9de
--- a/dev/null
+++ b/noncore/games/kpacman/kpacman.h
@@ -0,0 +1,95 @@
+#ifndef KPACMAN_H
+#define KPACMAN_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <kapp.h>
+#include <klocale.h>
+#include <ktmainwindow.h>
+#include <kmenubar.h>
+#elif defined( QPE_PORT )
+#include <qmainwindow.h>
+class QMenuBar;
+#endif
+
+#include <qregexp.h>
+
+#include "kpacmanwidget.h"
+
+#include <qpopmenu.h>
+
+#include <qlist.h>
+#include <qfileinf.h>
+
+#if defined( KDE2_PORT )
+#include <referee.h>
+#include <status.h>
+#include <score.h>
+#include <keys.h>
+#elif defined( QPE_PORT )
+#include "referee.h"
+#include "status.h"
+#include "score.h"
+#include "keys.h"
+#endif
+
+class Kpacman : public KTMainWindow
+{
+ Q_OBJECT
+public:
+ Kpacman(QWidget *parent = 0, const char *name = 0);
+ virtual ~Kpacman();
+
+public slots:
+ void forcedHallOfFame(bool);
+
+private slots:
+ void newKpacman();
+ void pauseKpacman();
+ void toggleHallOfFame();
+ void toggleNew();
+ void togglePaused();
+ void quitKpacman();
+
+ void schemeChecked(int);
+ void toggleFocusOutPause();
+ void toggleFocusInContinue();
+ void toggleHideMouseCursor();
+ void confKeys();
+
+protected:
+
+private:
+ KpacmanWidget *view;
+
+ void menu();
+
+ int lookupSchemes();
+
+ KMenuBar *_menuBar;
+ QPopupMenu *gamePopup;
+ QPopupMenu *optionsPopup;
+ QPopupMenu *modesPopup;
+ QList<QPopupMenu> *schemesPopup;
+
+ int newID;
+ int pauseID;
+ int hofID;
+ QArray<int> modeID;
+ QArray<int> schemeID;
+ QArray<int> schemeMode;
+ int focusOutPauseID;
+ int focusInContinueID;
+ int hideMouseCursorID;
+
+ bool focusOutPause;
+ bool focusInContinue;
+ bool hideMouseCursor;
+};
+
+#endif // KPACMAN_H
diff --git a/noncore/games/kpacman/kpacman.moc.cpp b/noncore/games/kpacman/kpacman.moc.cpp
new file mode 100644
index 0000000..804e8c8
--- a/dev/null
+++ b/noncore/games/kpacman/kpacman.moc.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+** Kpacman meta object code from reading C++ file 'kpacman.h'
+**
+** Created: Sat Jan 19 13:52:36 2002
+** by: The Qt MOC ($Id$)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#define Q_MOC_OUTPUT_REVISION 9
+#elif Q_MOC_OUTPUT_REVISION != 9
+#error "Moc format conflict - please regenerate all moc files"
+#endif
+
+#include "kpacman.h"
+#include <qmetaobject.h>
+#include <qapplication.h>
+
+
+
+const char *Kpacman::className() const
+{
+ return "Kpacman";
+}
+
+QMetaObject *Kpacman::metaObj = 0;
+
+void Kpacman::initMetaObject()
+{
+ if ( metaObj )
+ return;
+ if ( qstrcmp(QWidget::className(), "QWidget") != 0 )
+ badSuperclassWarning("Kpacman","QWidget");
+ (void) staticMetaObject();
+}
+
+#ifndef QT_NO_TRANSLATION
+
+QString Kpacman::tr(const char* s)
+{
+ return qApp->translate( "Kpacman", s, 0 );
+}
+
+QString Kpacman::tr(const char* s, const char * c)
+{
+ return qApp->translate( "Kpacman", s, c );
+}
+
+#endif // QT_NO_TRANSLATION
+
+QMetaObject* Kpacman::staticMetaObject()
+{
+ if ( metaObj )
+ return metaObj;
+ (void) QWidget::staticMetaObject();
+#ifndef QT_NO_PROPERTIES
+#endif // QT_NO_PROPERTIES
+ QMetaData::Access *slot_tbl_access = 0;
+ metaObj = QMetaObject::new_metaobject(
+ "Kpacman", "QWidget",
+ 0, 0,
+ 0, 0,
+#ifndef QT_NO_PROPERTIES
+ 0, 0,
+ 0, 0,
+#endif // QT_NO_PROPERTIES
+ 0, 0 );
+ metaObj->set_slot_access( slot_tbl_access );
+#ifndef QT_NO_PROPERTIES
+#endif // QT_NO_PROPERTIES
+ return metaObj;
+}
diff --git a/noncore/games/kpacman/kpacman.pro b/noncore/games/kpacman/kpacman.pro
new file mode 100644
index 0000000..6577e5b
--- a/dev/null
+++ b/noncore/games/kpacman/kpacman.pro
@@ -0,0 +1,42 @@
+TEMPLATE = app
+#CONFIG = qt warn_on debug
+CONFIG = qt warn_on release
+#TMAKE_CXXFLAGS +=
+HEADERS = kpacmanwidget.h \
+ referee.h \
+ status.h \
+ painter.h \
+ score.h \
+ pacman.h \
+ monster.h \
+ keys.h \
+ fruit.h \
+ energizer.h \
+ board.h \
+ bitfont.h \
+ kpacman.h \
+ bitmaps.h \
+ colors.h \
+ config.h \
+ portable.h
+SOURCES = kpacmanwidget.cpp \
+ referee.cpp \
+ status.cpp \
+ painter.cpp \
+ score.cpp \
+ pacman.cpp \
+ monster.cpp \
+ keys.cpp \
+ fruit.cpp \
+ energizer.cpp \
+ board.cpp \
+ bitfont.cpp \
+ kpacman.cpp \
+ config.cpp \
+ main.cpp
+
+#INCLUDEPATH +=
+#DEPENDPATH +=
+LIBS += -lqpe -ljpeg
+DESTDIR = $(OPIEDIR)/bin
+TARGET = kpacman
diff --git a/noncore/games/kpacman/kpacmanwidget.cpp b/noncore/games/kpacman/kpacmanwidget.cpp
new file mode 100644
index 0000000..330c88e
--- a/dev/null
+++ b/noncore/games/kpacman/kpacmanwidget.cpp
@@ -0,0 +1,162 @@
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <kapp.h>
+#include <kconfig.h>
+#include <kstddirs.h>
+#include <kpacmanwidget.h>
+#include <kpacmanwidget.moc>
+#elif defined( QPE_PORT )
+#include <qpe/qpeapplication.h>
+#include "config.h"
+#include "kpacmanwidget.h"
+#endif
+
+#include <qmessagebox.h>
+
+#include "bitfont.h"
+#include "score.h"
+#include "referee.h"
+#include "status.h"
+
+KpacmanWidget::KpacmanWidget( QWidget *parent, const char *name)
+ : QWidget( parent, name )
+{
+ bitfont = NULL;
+ fontName = "";
+
+ scheme = mode = -1;
+ confScheme();
+
+ score = new Score(this, name, scheme, mode, bitfont);
+ referee = new Referee( this, name, scheme, mode, bitfont);
+ status = new Status(this, name, scheme, mode);
+
+#ifndef QWS
+ setFixedSize(referee->width(), bitfont->height()*3 + referee->height() + status->height());
+#else
+ setBackgroundColor( black );
+#endif
+}
+
+KpacmanWidget::~KpacmanWidget()
+{
+}
+
+void KpacmanWidget::confMisc(bool defGroup)
+{
+ APP_CONFIG_BEGIN( cfg );
+ //KStandardDirs *dirs = KGlobal::dirs();
+ QString findPath;
+
+ if (defGroup || cfg->hasKey("Font")) {
+ fontName = cfg->readEntry("Font");
+
+ if (fontName.left(1) != "/" && fontName.left(1) != "~")
+ fontName.insert(0, "fonts/");
+ if (fontName.right(1) == "/")
+ fontName.append("font.xbm");
+
+ //findPath = dirs->findResource("appdata", fontName);
+ findPath = FIND_APP_DATA( fontName );
+ if (!findPath.isEmpty())
+ fontName = findPath;
+
+ bitfontFirstChar = cfg->readNumEntry("FontFirstChar", 0x0e);
+ bitfontLastChar = cfg->readNumEntry("FontLastChar", 0x5f);
+ }
+ APP_CONFIG_END( cfg );
+}
+
+void KpacmanWidget::confScheme()
+{
+ APP_CONFIG_BEGIN( cfg );
+ QString lastFontName = fontName;
+ SAVE_CONFIG_GROUP( cfg, oldgroup );
+ QString newgroup;
+
+ // if not set, read mode and scheme from the configfile
+ if (mode == -1 && scheme == -1) {
+ scheme = cfg->readNumEntry("Scheme", -1);
+ mode = cfg->readNumEntry("Mode", -1);
+
+ // if mode is not set in the defGroup-group, lookup the scheme group
+ if (scheme != -1 || mode == -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ cfg->setGroup(newgroup);
+
+ mode = cfg->readNumEntry("Mode", -1);
+ RESTORE_CONFIG_GROUP( cfg, oldgroup );
+ }
+ }
+
+ confMisc();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ cfg->setGroup(newgroup);
+
+ confMisc(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ cfg->setGroup(newgroup);
+
+ confMisc(FALSE);
+ }
+
+ if (lastFontName != fontName) {
+
+ if (bitfont != 0)
+ delete bitfont;
+
+ bitfont = new Bitfont(fontName, bitfontFirstChar, bitfontLastChar);
+ if (bitfont->width() == 0 || bitfont->height() == 0) {
+ QString msg = i18n("The bitfont could not be contructed.\n\n"
+ "The file '@FONTNAME@' does not exist,\n"
+ "or is of an unknown format.");
+ msg.replace(QRegExp("@FONTNAME@"), fontName);
+ // QMessageBox::critical(this, i18n("Initialization Error"), msg);
+ printf("%s\n", msg.data());
+ }
+ }
+
+ RESTORE_CONFIG_GROUP( cfg, oldgroup );
+ APP_CONFIG_END( cfg );
+}
+
+void KpacmanWidget::setScheme(int Scheme, int Mode)
+{
+ mode = Mode;
+ scheme = Scheme;
+
+ confScheme();
+
+ score->setScheme(Scheme, Mode, bitfont);
+ referee->setScheme(Scheme, Mode, bitfont);
+ status->setScheme(Scheme, Mode);
+
+#ifndef QWS
+ setFixedSize(referee->width(),
+ bitfont->height()*3 + referee->height() + status->height());
+#endif
+
+ score->repaint(FALSE);
+ referee->repaint(FALSE);
+ status->repaint(FALSE);
+}
+
+void KpacmanWidget::resizeEvent( QResizeEvent * )
+{
+ referee->setGeometry(0, bitfont->height()*3, referee->width(), referee->height());
+ referee->setBackgroundColor(BLACK);
+
+ status->setGeometry(0, bitfont->height()*3+referee->height(), referee->width(),
+ status->height());
+ status->setBackgroundColor(BLACK);
+
+ score->setGeometry(0, 0, referee->width(), bitfont->height()*3+referee->height()+status->height());
+ score->setBackgroundColor(BLACK);
+}
diff --git a/noncore/games/kpacman/kpacmanwidget.h b/noncore/games/kpacman/kpacmanwidget.h
new file mode 100644
index 0000000..13b4a15
--- a/dev/null
+++ b/noncore/games/kpacman/kpacmanwidget.h
@@ -0,0 +1,50 @@
+#ifndef KPACMANWIDGET_H
+#define KPACMANWIDGET_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <kapp.h>
+#endif
+
+#include <qwidget.h>
+#include <qregexp.h>
+
+#include "score.h"
+#include "referee.h"
+#include "status.h"
+#include "painter.h"
+
+class KpacmanWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ KpacmanWidget ( QWidget *parent = 0, const char *name = 0);
+ virtual ~KpacmanWidget();
+
+ void setScheme(int scheme=-1, int mode=-1);
+ Score *score;
+ Referee *referee;
+ Status *status;
+
+protected:
+ void confScheme();
+ void confMisc(bool defGroup=TRUE);
+ void resizeEvent( QResizeEvent * );
+
+private:
+ Bitfont *bitfont;
+ uchar bitfontFirstChar;
+ uchar bitfontLastChar;
+
+ QString fontName;
+
+ int scheme;
+ int mode;
+};
+
+#endif // KPACMANWIDGET_H
diff --git a/noncore/games/kpacman/main.cpp b/noncore/games/kpacman/main.cpp
new file mode 100644
index 0000000..76afb57
--- a/dev/null
+++ b/noncore/games/kpacman/main.cpp
@@ -0,0 +1,66 @@
+/***************************************************************************
+ main.cpp - description
+ -------------------
+ begin : Sam Jan 19 13:37:57 CET 2002
+ copyright : (C) 2002 by Jörg Thönnissen
+ email : joe@dsite.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <klocale.h>
+#elif defined( QPE_PORT )
+#include <qpe/qpeapplication.h>
+#endif
+
+#include "kpacman.h"
+
+#ifdef KDE2_PORT
+static const char *description =
+ I18N_NOOP("Kpacman");
+// INSERT A DESCRIPTION FOR YOUR APPLICATION HERE
+
+
+static KCmdLineOptions options[] =
+{
+ { 0, 0, 0 }
+ // INSERT YOUR COMMANDLINE OPTIONS HERE
+};
+#endif
+
+int main(int argc, char *argv[])
+{
+#if defined( KDE2_PORT )
+ KAboutData aboutData( "kpacman", I18N_NOOP("Kpacman"),
+ VERSION, description, KAboutData::License_GPL,
+ "(c) 2002, Jörg Thönnissen", 0, 0, "joe@dsite.de");
+ aboutData.addAuthor("Jörg Thönnissen",0, "joe@dsite.de");
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
+ KApplication a;
+#elif defined( QPE_PORT )
+ QPEApplication a( argc, argv );
+#endif
+ Kpacman *kpacman = new Kpacman( NULL, "Kpacman" );
+ a.setMainWidget(kpacman);
+#if defined( KDE2_PORT )
+ a.setTopWidget(kpacman);
+ kpacman->show();
+#elif defined( QPE_PORT )
+ kpacman->showMaximized();
+#endif
+
+ return a.exec();
+}
diff --git a/noncore/games/kpacman/monster.cpp b/noncore/games/kpacman/monster.cpp
new file mode 100644
index 0000000..2f402b4
--- a/dev/null
+++ b/noncore/games/kpacman/monster.cpp
@@ -0,0 +1,262 @@
+#include "monster.h"
+#include "board.h"
+
+Monster::Monster(Board *b, int mid)
+{
+ board = b;
+ ID = mid;
+
+ setREM(0);
+ setHarmless(0, 0, 0);
+ setArrested(0, 0);
+ setFreedom(board->position(prisonexit));
+ if (mid == 0)
+ setPrison(board->position(prisonentry));
+ else
+ setPrison(board->position(monsterhome, mid));
+
+ actualPosition = lastPosition = OUT;
+ feetPosition = 0;
+ IQ = 0;
+ maxBodyPixmaps = 0;
+ maxEyesPixmaps = 0;
+}
+
+void Monster::setMaxPixmaps(int maxBody, int maxEyes)
+{
+ if (feetPosition >= (maxBody/10))
+ feetPosition = 0;
+ maxBodyPixmaps = maxBody;
+ maxEyesPixmaps = maxEyes;
+}
+
+void Monster::setArrested(int ticks, int duration)
+{
+ actualState = dangerous;
+ pauseDuration = ticks;
+ pause = 0;
+ arrestDuration = arrestLeft = duration;
+ arrestPause = ticks;
+ harmlessLeft = 0;
+}
+
+void Monster::setDangerous(int ticks, int iq)
+{
+ actualState = dangerous;
+ pauseDuration = ticks;
+ pause = 0;
+ dangerousPause = ticks;
+ harmlessLeft = 0;
+ IQ = iq;
+}
+
+void Monster::setHarmless(int ticks, int hDuration, int wDuration)
+{
+ actualState = harmless;
+ pauseDuration = ticks;
+ pause = 0;
+ harmlessDuration = harmlessLeft = hDuration;
+ warningDuration = wDuration;
+}
+
+void Monster::setREM(int ticks)
+{
+ actualState = rem;
+ pauseDuration = ticks;
+ pause = 0;
+}
+
+void Monster::setPosition(int pos)
+{
+ board->reset(lastPosition, monster, ID); // reset old position on the board
+ actualPosition = lastPosition = pos; // set position of monster
+ board->set(actualPosition, monster, ID);
+ feetPosition = 0;
+}
+
+void Monster::setPrison(int pos)
+{
+ prisonPosition = pos;
+}
+
+void Monster::setFreedom(int pos)
+{
+ freedomPosition = pos;
+}
+
+void Monster::setDirection(int dir)
+{
+ if (dir == X)
+ lastDirection = actualDirection;
+ actualDirection = dir;
+}
+
+monsterState Monster::state()
+{
+ return actualState;
+}
+
+int Monster::position()
+{
+ return actualPosition;
+}
+
+int Monster::direction()
+{
+ return actualDirection;
+}
+
+int Monster::id()
+{
+ return ID;
+}
+
+bool Monster::move()
+{
+ if (arrestLeft > 1)
+ arrestLeft--;
+
+ if (harmlessLeft > 0) {
+ harmlessLeft--;
+ if (harmlessLeft == 0 && actualState == harmless) {
+ actualState = dangerous;
+ pauseDuration = dangerousPause;
+ }
+ }
+
+ if (pause-- > 0)
+ return FALSE;
+ else
+ pause = pauseDuration;
+
+ if (actualPosition == OUT)
+ return FALSE;
+
+ if (actualDirection == X) {
+ if (++feetPosition >= (maxBodyPixmaps/10))
+ feetPosition = 0;
+ return TRUE;
+ }
+
+ lastPosition = actualPosition;
+ int d = actualDirection;
+
+ if (arrestLeft > 1) { // during the arrest, only up and down
+ if (!board->isWay(actualPosition, d, empty) &&
+ !board->isWay(actualPosition, d, tunnel))
+ d = board->turn(actualDirection);
+ }
+
+ if (arrestLeft == 1) { // going out of the prison
+ if (((d == W || d == E) &&
+ board->x(actualPosition) == board->x(freedomPosition)) ||
+ ((d == S || d == N) &&
+ board->y(actualPosition) == board->y(freedomPosition)) ||
+ board->isWay(actualPosition, d, brick) ||
+ board->isWay(actualPosition, d, prison)) {
+ d = board->closeup(actualPosition, d, freedomPosition);
+ }
+ while (board->isWay(actualPosition, d, brick) ||
+ board->isWay(actualPosition, d, prison)) {
+ if (d == actualDirection)
+ d = rand() % 4;
+ else
+ d = actualDirection;
+ }
+ if (actualState == dangerous)
+ pauseDuration = dangerousPause;
+
+ }
+
+ if (arrestLeft == 0)
+ if (actualState == rem) { // on the way to prison
+
+ d = board->closeup(actualPosition, d, prisonPosition);
+
+ while (board->isWay(actualPosition, d, brick) ||
+ board->isWay(actualPosition, d, prison)) {
+ if (d != actualDirection) // if new direction is not possible,
+ d = actualDirection; // try current direction first.
+ else
+ d = rand() % 4;
+ }
+
+ } else { // dangerous or harmless movement
+ if (rand() % (int) ((190-IQ)/10) == 0) {
+ d = board->closeup(actualPosition, d, board->position(pacman));
+ if (actualState == harmless)
+ d = board->turn(d);
+ } else
+ do // try new direction, but not the opposite
+ d = rand() % 4; // direction, to prevent hectic movement.
+ while (d == board->turn(actualDirection));
+
+ while ((!board->isWay(actualPosition, d, empty) &&
+ !board->isWay(actualPosition, d, tunnel)) ||
+ d == board->turn(actualDirection)) {
+ if (d != actualDirection) // if new direction is not possible,
+ d = actualDirection; // try current direction first.
+ else
+ d = rand() % 4;
+ }
+ }
+
+ actualDirection = d;
+ actualPosition = board->move(actualPosition, actualDirection);
+
+ if (arrestLeft == 1 && actualPosition == freedomPosition)
+ arrestLeft = 0;
+
+ if (actualState == rem && actualPosition == prisonPosition) {
+ actualState = dangerous;
+ pauseDuration = arrestPause;
+ arrestLeft = arrestDuration+1;
+ actualDirection = S;
+ }
+
+ if (actualPosition != lastPosition) {
+ board->reset(lastPosition, monster, ID);
+ board->set(actualPosition, monster, ID);
+ }
+
+ if (++feetPosition >= (maxBodyPixmaps/10))
+ feetPosition = 0;
+
+ return TRUE;
+}
+
+int Monster::body()
+{
+ if (actualState == rem || actualPosition == OUT)
+ return -1;
+ else
+ if (actualState == harmless)
+ if (harmlessLeft > warningDuration ||
+ harmlessLeft % (int) (warningDuration/4.5) > (int) (warningDuration/9))
+ return ((maxBodyPixmaps/10)*8)+feetPosition;
+ else
+ return ((maxBodyPixmaps/10)*9)+feetPosition;
+ else
+ return ((maxBodyPixmaps/10)*ID)+feetPosition;
+}
+
+int Monster::eyes()
+{
+ if (actualState == harmless || actualPosition == OUT)
+ return -1;
+ else
+ switch (actualDirection) {
+ case N : return 0;
+ case E : return 1;
+ case S : return 2;
+ case W : return 3;
+ case X : switch (lastDirection) {
+ case N : return 0;
+ case E : return 1;
+ case S : return 2;
+ default : return 3;
+ }
+ default : return -1;
+ }
+}
+
diff --git a/noncore/games/kpacman/monster.h b/noncore/games/kpacman/monster.h
new file mode 100644
index 0000000..b5d7f36
--- a/dev/null
+++ b/noncore/games/kpacman/monster.h
@@ -0,0 +1,62 @@
+#ifndef MONSTER_H
+#define MONSTER_H
+
+#include <stdlib.h>
+#include <qpixmap.h>
+#include <qwidget.h>
+
+#include "board.h"
+
+enum monsterState { dangerous, harmless, rem, arrested };
+
+class Monster {
+public:
+ Monster(Board *b, int mid = 0);
+ void setMaxPixmaps(int maxBody, int maxEyes);
+ void setArrested(int ticks, int duration);
+ void setDangerous(int ticks, int IQ);
+ void setHarmless(int ticks, int hDuration, int wDuration);
+ void setREM(int ticks);
+ void setPosition(int pos);
+ void setPrison(int pos);
+ void setFreedom(int pos);
+ void setDirection(int dir);
+ monsterState state();
+ int position();
+ int direction();
+ int id();
+ bool move();
+ int body();
+ int eyes();
+private:
+ Board *board;
+ int ID; // ID of monster (0 = 1st, 1 = 2nd ... 7 = last)
+ int IQ; // Intelligence of movement (0 = dumb..180 = smart)
+
+ monsterState actualState; // The state of the monster
+
+ int pauseDuration; // Number of ticks before movement
+ int pause; // actual ticks before moevment (0 = move)
+ int dangerousPause; // pause in dangerous-state
+
+ int harmlessDuration; // Length of harmless-time in ticks
+ int harmlessLeft; // rest of the time in harmless-state
+ int warningDuration; // warningtime before monster get dangerous again
+
+ int arrestDuration; // Length of arrest in ticks
+ int arrestLeft; // time left of arrest
+ int arrestPause; // pause in arrest-state
+
+ int actualDirection; // actual direction of monster
+ int lastDirection; // last direction, before no movement (X)
+ int actualPosition; // actual position on board
+ int lastPosition; // the last position of the monster
+ int feetPosition; // left, right, left, right, ...
+ int maxBodyPixmaps;
+ int maxEyesPixmaps;
+ int prisonPosition; // where to go, if arrested
+ int freedomPosition; // where to go, if released from prison
+};
+
+#endif // MONSTER_H
+
diff --git a/noncore/games/kpacman/opie-kpacman.control b/noncore/games/kpacman/opie-kpacman.control
new file mode 100644
index 0000000..814604e
--- a/dev/null
+++ b/noncore/games/kpacman/opie-kpacman.control
@@ -0,0 +1,11 @@
+Files: bin/kpacman apps/Games/kpacman.desktop pics/kpacman.png share/kpacman
+Package: opie-kpacman
+Version: 0.3.1
+Depends: opie-base ($QPE_VERSION)
+Priority: optional
+Section: opie/games
+Maintainer: Catalin Climov <catalin@climov.com>
+Architecture: arm
+License: GPL
+Description: Kpacman
+ A Pacman clone for Qtopia.
diff --git a/noncore/games/kpacman/opie-kpacman.postinst b/noncore/games/kpacman/opie-kpacman.postinst
new file mode 100755
index 0000000..ead1ef8
--- a/dev/null
+++ b/noncore/games/kpacman/opie-kpacman.postinst
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+if [ ! -f $HOME/Settings/kpacman.conf ]
+then
+ cp $QPEDIR/share/kpacman/kpacman.conf $HOME/Settings/
+fi
diff --git a/noncore/games/kpacman/pacman.cpp b/noncore/games/kpacman/pacman.cpp
new file mode 100644
index 0000000..40f60a8
--- a/dev/null
+++ b/noncore/games/kpacman/pacman.cpp
@@ -0,0 +1,147 @@
+#include "pacman.h"
+#include "board.h"
+
+Pacman::Pacman(Board *b)
+{
+ board = b;
+ setDemo(FALSE);
+ setAlive(0);
+ actualPosition = lastPosition = OUT;
+ mouthPosition = 0;
+ lastPix = 0;
+ maxPixmaps = 0;
+}
+
+void Pacman::setMaxPixmaps(int max)
+{
+ if (actualDirection == X && lastPix >= 0) {
+ actualDirection = lastPix / (maxPixmaps/4);
+ if (max < maxPixmaps)
+ mouthPosition = 0;
+ else
+ mouthPosition = lastPix % (maxPixmaps/4);
+ maxPixmaps = max;
+
+ lastPix = pix();
+
+ actualDirection = X;
+ } else
+ maxPixmaps = max;
+}
+
+void Pacman::setAlive(int ticks)
+{
+ actualState = alive;
+ pauseDuration = ticks;
+ pause = 0;
+}
+
+void Pacman::setPosition(int pos)
+{
+ board->reset(lastPosition, pacman);
+ actualPosition = lastPosition = pos;
+ board->set(actualPosition, pacman);
+ mouthPosition = 0;
+}
+
+void Pacman::setDirection(int dir, bool forced)
+{
+ if (forced ||
+ board->isWay(actualPosition, dir, empty) ||
+ board->isWay(actualPosition, dir, tunnel)) {
+ if (dir == X)
+ lastPix = pix();
+ actualDirection = dir;
+ nextDirection = X;
+ } else
+ nextDirection = dir;
+}
+
+void Pacman::setDemo(bool yes)
+{
+ demo = yes;
+}
+
+pacmanState Pacman::state()
+{
+ return actualState;
+}
+
+int Pacman::position()
+{
+ return actualPosition;
+}
+
+int Pacman::direction()
+{
+ return actualDirection;
+}
+
+bool Pacman::move()
+{
+ if (pause-- > 0)
+ return FALSE;
+ else
+ pause = pauseDuration;
+
+ if (actualDirection == X || actualPosition == OUT)
+ return FALSE;
+
+ lastPosition = actualPosition;
+
+ if (demo) {
+ int d = actualDirection;
+
+ do // try new direction, but not the opposite
+ d = rand() % 4; // direction, to prevent hectic movement.
+ while (d == board->turn(actualDirection));
+
+ while (!board->isWay(actualPosition, d, empty) &&
+ !board->isWay(actualPosition, d, tunnel)) {
+ if (d != actualDirection) // if new actualDirection is not possible,
+ d = actualDirection; // try current actualDirection first.
+ else
+ d = rand() % 4;
+ }
+
+ actualDirection = d;
+ actualPosition = board->move(actualPosition, actualDirection);
+
+ } else {
+
+ if (nextDirection != X)
+ if (board->isWay(actualPosition, nextDirection, empty) ||
+ board->isWay(actualPosition, nextDirection, tunnel)) {
+ actualDirection = nextDirection;
+ nextDirection = X;
+ }
+
+ if (board->isWay(actualPosition, actualDirection, empty) ||
+ board->isWay(actualPosition, actualDirection, tunnel))
+ actualPosition = board->move(actualPosition, actualDirection);
+ }
+
+ if (actualPosition != lastPosition) {
+ board->reset(lastPosition, pacman);
+ board->set(actualPosition, pacman);
+
+ if (++mouthPosition >= (maxPixmaps/4))
+ mouthPosition = 0;
+ }
+ return TRUE;
+}
+
+int Pacman::pix()
+{
+ if (actualPosition != OUT && maxPixmaps > 0)
+ switch (actualDirection) {
+ case N : return ((maxPixmaps/4)*0)+mouthPosition;
+ case E : return ((maxPixmaps/4)*1)+mouthPosition;
+ case S : return ((maxPixmaps/4)*2)+mouthPosition;
+ case W : return ((maxPixmaps/4)*3)+mouthPosition;
+ case X : return lastPix;
+ }
+
+ return -1;
+}
+
diff --git a/noncore/games/kpacman/pacman.h b/noncore/games/kpacman/pacman.h
new file mode 100644
index 0000000..e81fdd2
--- a/dev/null
+++ b/noncore/games/kpacman/pacman.h
@@ -0,0 +1,47 @@
+#ifndef PACMAN_H
+#define PACMAN_H
+
+#include <stdlib.h>
+#include <qpixmap.h>
+#include <qwidget.h>
+
+#include "board.h"
+
+enum pacmanState { alive };
+
+class Pacman {
+public:
+ Pacman(Board *b);
+ void init(bool Demo = FALSE);
+ void setMaxPixmaps(int max);
+ void setAlive(int ticks);
+ void setPosition(int pos);
+ void setDirection(int dir, bool forced = FALSE);
+ void setDemo(bool yes);
+ pacmanState state();
+ int position();
+ int direction();
+ bool move();
+ int pix();
+
+private:
+ Board *board;
+
+ pacmanState actualState; // the state of pacman
+ bool demo; // real life or just demo
+
+ int pauseDuration; // number of ticks before next movement
+ int pause; // actual ticks before movement (0=move)
+
+ int actualDirection; // actual direction of pacman
+ int nextDirection; // where he wants to go
+ int lastPix; // last Pixmap-index before no movement
+ int maxPixmaps; // Number of Pixmaps (1..)
+ int actualPosition; // actual position on board
+ int lastPosition; // the last position of pacman
+ int mouthPosition; // eating
+
+};
+
+#endif // PACMAN_H
+
diff --git a/noncore/games/kpacman/painter.cpp b/noncore/games/kpacman/painter.cpp
new file mode 100644
index 0000000..16fed55
--- a/dev/null
+++ b/noncore/games/kpacman/painter.cpp
@@ -0,0 +1,972 @@
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <kapp.h>
+#include <kconfig.h>
+#include <kstddirs.h>
+#elif defined( QPE_PORT )
+#include <qpe/qpeapplication.h>
+#include "config.h"
+#endif
+
+#include <qcolor.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qbitmap.h>
+#include <qrect.h>
+#include <qstring.h>
+
+#include <qmessagebox.h>
+#include <qfileinfo.h>
+
+#include "painter.h"
+#include "board.h"
+
+Painter::Painter( Board *b, QWidget *parent, int Scheme, int Mode, Bitfont *font)
+{
+ w = parent;
+ board = b;
+
+ pointPix = NULL;
+ wallPix = NULL;
+ prisonPix = NULL;
+ energizerPix = NULL;
+ fruitPix = NULL;
+ pacmanPix = NULL;
+ dyingPix = NULL;
+ eyesPix = NULL;
+ monsterPix = NULL;
+ fruitScorePix = NULL;
+ monsterScorePix = NULL;
+
+ lastPointPixmapName = "";
+ lastWallPixmapName = "";
+ lastPrisonPixmapName = "";
+ lastEnergizerPixmapName = "";
+ lastFruitPixmapName = "";
+ lastPacmanPixmapName = "";
+ lastDyingPixmapName = "";
+ lastEyesPixmapName = "";
+ lastMonsterPixmapName = "";
+ lastFruitScorePixmapName = "";
+ lastMonsterScorePixmapName = "";
+
+ bitfont = font;
+
+ scheme = Scheme;
+ mode = Mode;
+ level = 0;
+
+ confScheme();
+}
+
+QList<QPixmap> *Painter::loadPixmap(QWidget*, QString pixmapName,
+ QList<QPixmap> *pixmaps)
+{
+ if (pixmaps == NULL) {
+ pixmaps = new QList<QPixmap>;
+ pixmaps->setAutoDelete(TRUE);
+ }
+
+ if (!pixmaps->isEmpty())
+ pixmaps->clear();
+
+ QPixmap PIXMAP(pixmapName);
+ if (PIXMAP.isNull() || PIXMAP.mask() == NULL) {
+ QString msg = i18n("The pixmap could not be contructed.\n\n"
+ "The file '@PIXMAPNAME@' does not exist,\n"
+ "or is of an unknown format.");
+ msg.replace(QRegExp("@PIXMAPNAME@"), pixmapName);
+ // QMessageBox::critical(parent, i18n("Initialization Error"), msg);
+ printf("%s\n", msg.data());
+ return 0;
+ }
+
+ int height = PIXMAP.height();
+ int width = (height == 0) ? 0 : PIXMAP.width()/(PIXMAP.width()/height);
+
+ QBitmap BITMAP;
+ QBitmap MASK;
+
+ BITMAP = *PIXMAP.mask();
+ MASK.resize(width, height);
+
+ for (int x = 0; x < PIXMAP.width()/width; x++) {
+ QPixmap *pixmap = new QPixmap(width, height);
+ pixmaps->append(pixmap);
+ bitBlt(pixmap, 0, 0, &PIXMAP, x*width, 0, width, height, QPixmap::CopyROP, TRUE);
+ bitBlt(&MASK, 0, 0, &BITMAP, x*width, 0, width, height, QPixmap::CopyROP, TRUE);
+ pixmap->setMask(MASK);
+ }
+
+ return pixmaps;
+}
+
+QList<QPixmap> *Painter::textPixmap(QStrList &str, QList<QPixmap> *pixmaps,
+ QColor fg, QColor bg)
+{
+ if (pixmaps == NULL) {
+ pixmaps = new QList<QPixmap>;
+ pixmaps->setAutoDelete(TRUE);
+ }
+
+ if (!pixmaps->isEmpty())
+ pixmaps->clear();
+
+ for (uint s = 0; s < str.count(); s++) {
+ QPixmap *pixmap = new QPixmap(bitfont->text(str.at(s), fg, bg));
+ pixmaps->append(pixmap);
+ }
+
+ return pixmaps;
+}
+
+QList<QPixmap> *Painter::textPixmap(QString str, QList<QPixmap> *pixmaps,
+ QColor fg, QColor bg)
+{
+ if (pixmaps == NULL) {
+ pixmaps = new QList<QPixmap>;
+ pixmaps->setAutoDelete(TRUE);
+ }
+
+ if (!pixmaps->isEmpty())
+ pixmaps->clear();
+
+ QPixmap *pixmap = new QPixmap(bitfont->text(str, fg, bg));
+ pixmaps->append(pixmap);
+
+ return pixmaps;
+}
+
+/* Return the point of the upperleft pixel of the block representing that position
+ * on the board.
+ */
+QPoint Painter::point(int pos)
+{
+ return QPoint((board->x(pos)-1)*BlockWidth, (board->y(pos)-1)*BlockHeight);
+}
+
+
+QRect Painter::rect(int pos, PixMap pix, uint i)
+{
+ if (pos == OUT)
+ return QRect();
+
+ QPixmap *PIXMAP = NULL;
+ switch (pix) {
+ case PacmanPix : PIXMAP = pacmanPix->
+ at(checkRange(i, pacmanPix->count()-1));
+ break;
+ case DyingPix : PIXMAP = dyingPix->
+ at(checkRange(i, dyingPix->count()-1));
+ break;
+ case MonsterPix : PIXMAP = monsterPix->
+ at(checkRange(i, monsterPix->count()-1));
+ break;
+ case EyesPix : PIXMAP = eyesPix->
+ at(checkRange(i, eyesPix->count()-1));
+ break;
+ case FruitPix : PIXMAP = fruitPix->
+ at(checkRange(i, fruitPix->count()-1));
+ break;
+ case PointPix : PIXMAP = pointPix->
+ at(checkRange(i, pointPix->count()-1));
+ break;
+ case EnergizerPix : PIXMAP = energizerPix->
+ at(checkRange(i, energizerPix->count()-1));
+ break;
+ case FruitScorePix : PIXMAP = fruitScorePix->
+ at(checkRange(i, fruitScorePix->count()-1));
+ break;
+ case MonsterScorePix : PIXMAP = monsterScorePix->
+ at(checkRange(i,monsterScorePix->count()-1));
+ break;
+ default : PIXMAP = wallPix->
+ at(checkRange(i, wallPix->count()-1));
+ }
+ if (PIXMAP == NULL)
+ return QRect();
+
+ QRect rect = PIXMAP->rect();
+ QPoint point = this->point(pos);
+ rect.moveCenter(QPoint(point.x()-1, point.y()-1));
+
+ return rect;
+}
+
+QRect Painter::rect(int pos, QString str, int align)
+{
+ if (pos == OUT) // return an empty rect if the position
+ return QRect(); // is invalid
+ QPoint point = this->point(pos);
+ QRect rect = bitfont->rect(str);
+
+ rect.moveCenter(QPoint(point.x()-1, point.y()-1));
+
+ int dx = 0;
+ int dy = 0;
+
+ if (align & QLabel::AlignLeft || align & QLabel::AlignRight) {
+ dx = (str.length()-1) * (bitfont->width()/2);
+ if (align & QLabel::AlignRight)
+ dx *= -1;
+ }
+
+ if (align & QLabel::AlignTop || align & QLabel::AlignBottom) {
+ dy = bitfont->height()/2;
+ if (align & QLabel::AlignBottom)
+ dy *= -1;
+ }
+
+ if (dx != 0 || dy != 0)
+ rect.moveBy(dx, dy);
+
+ return rect;
+}
+
+QRect Painter::rect(QRect r1, QRect r2)
+{
+ QRect rect;
+ rect.setLeft(r1.left() < r2.left() ? r1.left() : r2.left());
+ rect.setTop(r1.top() < r2.top() ? r1.top() : r2.top());
+ rect.setRight(r1.right() > r2.right() ? r1.right() : r2.right());
+ rect.setBottom(r1.bottom() > r2.bottom() ? r1.bottom() : r2.bottom());
+
+ return rect;
+}
+
+void Painter::erase(int pos, PixMap pix, uint i)
+{
+ if (pos == OUT)
+ return;
+ QRect rect = this->rect(pos, pix, i);
+ bitBlt(&roomPix, rect.x(), rect.y(), &backPix,
+ rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+int Painter::maxPixmaps(PixMap pix)
+{
+ switch (pix) {
+ case WallPix : return (int) wallPix->count();
+ case PrisonPix : return (int) prisonPix->count();
+ case PointPix : return (int) pointPix->count();
+ case EnergizerPix : return (int) energizerPix->count();
+ case FruitPix : return (int) fruitPix->count();
+ case PacmanPix : return (int) pacmanPix->count();
+ case DyingPix : return (int) dyingPix->count();
+ case EyesPix : return (int) eyesPix->count();
+ case MonsterPix : return (int) monsterPix->count();
+ case FruitScorePix : return (int) fruitScorePix->count();
+ case MonsterScorePix : return (int) monsterScorePix->count();
+ default : return 0;
+ }
+}
+
+void Painter::draw(QPoint point, DrawWidget where, QPixmap pix)
+{
+ switch (where) {
+ case Widget : bitBlt(w, point.x(), point.y(), &pix);
+ break;
+ case RoomPix : bitBlt(&roomPix, point.x(), point.y(), &pix);
+ break;
+ case BackPix : bitBlt(&backPix, point.x(), point.y(), &pix);
+ break;
+ }
+}
+
+void Painter::draw(QRect rect, DrawWidget where, QPixmap pix)
+{
+ draw(QPoint(rect.x(), rect.y()), where, pix);
+}
+
+void Painter::draw(int pos, DrawWidget where, PixMap pix, uint i)
+{
+ QPixmap *PIXMAP = NULL;
+ switch (pix) {
+ case PacmanPix : PIXMAP = pacmanPix->
+ at(checkRange(i, pacmanPix->count()-1));
+ break;
+ case DyingPix : PIXMAP = dyingPix->
+ at(checkRange(i, dyingPix->count()-1));
+ break;
+ case MonsterPix : PIXMAP = monsterPix->
+ at(checkRange(i, monsterPix->count()-1));
+ break;
+ case EyesPix : PIXMAP = eyesPix->
+ at(checkRange(i, eyesPix->count()-1));
+ break;
+ case FruitPix : PIXMAP = fruitPix->
+ at(checkRange(i, fruitPix->count()-1));
+ break;
+ case EnergizerPix : PIXMAP = energizerPix->
+ at(checkRange(i, energizerPix->count()-1));
+ break;
+ case FruitScorePix : PIXMAP = fruitScorePix->
+ at(checkRange(i, fruitScorePix->count()-1));
+ break;
+ case MonsterScorePix : PIXMAP = monsterScorePix->
+ at(checkRange(i,monsterScorePix->count()-1));
+ break;
+ default : ;
+ }
+
+ if (PIXMAP == NULL)
+ return;
+
+ QRect rect = PIXMAP->rect();
+ QPoint point = this->point(pos);
+ rect.moveCenter(QPoint(point.x()-1, point.y()-1));
+
+ switch (where) {
+ case Widget : bitBlt(w, rect.x(), rect.y(), PIXMAP);
+ break;
+ case RoomPix : bitBlt(&roomPix, rect.x(), rect.y(), PIXMAP);
+ break;
+ case BackPix : bitBlt(&backPix, rect.x(), rect.y(), PIXMAP);
+ break;
+ }
+}
+
+QPixmap Painter::draw(int pos, DrawWidget where,
+ QString str, QColor fg, QColor bg, int align)
+{
+ QPixmap TEXT = bitfont->text(str, fg, bg);
+
+ QRect rect = this->rect(pos, str, align);
+ QPixmap SAVE = QPixmap(rect.width(), rect.height());
+
+ switch (where) {
+ case Widget : bitBlt(&SAVE, 0, 0, w, rect.x(), rect.y());
+ bitBlt(w, rect.x(), rect.y(), &TEXT);
+ break;
+ case RoomPix : bitBlt(&SAVE, 0, 0, &roomPix, rect.x(), rect.y());
+ bitBlt(&roomPix, rect.x(), rect.y(), &TEXT);
+ break;
+ case BackPix : bitBlt(&SAVE, 0, 0, &backPix, rect.x(), rect.y());
+ bitBlt(&backPix, rect.x(), rect.y(), &TEXT);
+ break;
+ }
+
+ return SAVE;
+}
+
+QRect Painter::draw(int col, int row, DrawWidget where,
+ QString str, QColor fg, QColor bg, int align)
+{
+ QPixmap TEXT = bitfont->text(str, fg, bg);
+
+ QRect rect = this->rect(row*BoardWidth+col, str, align);
+ draw(rect, where, TEXT);
+
+ return rect;
+}
+
+void Painter::initPixmaps()
+{
+ if (lastPointPixmapName != pointPixmapName.at(level)) {
+ pointPix = loadPixmap(w, pointPixmapName.at(level), pointPix);
+ lastPointPixmapName = pointPixmapName.at(level);
+ }
+ if (lastPrisonPixmapName != prisonPixmapName.at(level)) {
+ prisonPix = loadPixmap(w, prisonPixmapName.at(level), prisonPix);
+ lastPrisonPixmapName = prisonPixmapName.at(level);
+ }
+ if (lastEnergizerPixmapName != energizerPixmapName.at(level)) {
+ energizerPix = loadPixmap(w, energizerPixmapName.at(level), energizerPix);
+ lastEnergizerPixmapName = energizerPixmapName.at(level);
+ }
+ if (lastFruitPixmapName != fruitPixmapName.at(level)) {
+ fruitPix = loadPixmap(w, fruitPixmapName.at(level), fruitPix);
+ lastFruitPixmapName = fruitPixmapName.at(level);
+ }
+ if (lastPacmanPixmapName != pacmanPixmapName.at(level)) {
+ pacmanPix = loadPixmap(w, pacmanPixmapName.at(level), pacmanPix);
+ lastPacmanPixmapName = pacmanPixmapName.at(level);
+ }
+ if (lastDyingPixmapName != dyingPixmapName.at(level)) {
+ dyingPix = loadPixmap(w, dyingPixmapName.at(level), dyingPix);
+ lastDyingPixmapName = dyingPixmapName.at(level);
+ }
+ if (lastEyesPixmapName != eyesPixmapName.at(level)) {
+ eyesPix = loadPixmap(w, eyesPixmapName.at(level), eyesPix);
+ lastEyesPixmapName = eyesPixmapName.at(level);
+ }
+ if (lastMonsterPixmapName != monsterPixmapName.at(level)) {
+ monsterPix = loadPixmap(w, monsterPixmapName.at(level), monsterPix);
+ lastMonsterPixmapName = monsterPixmapName.at(level);
+ }
+
+ if (lastFruitScorePixmapName != fruitScorePixmapName.at(level) ||
+ (const char *) *fruitScorePixmapName.at(level) == '\0') {
+ if ((const char *) *fruitScorePixmapName.at(level) == '\0') {
+ fruitScorePix = textPixmap(fruitScoreString, fruitScorePix, PINK);
+ } else {
+ fruitScorePix = loadPixmap(w, fruitScorePixmapName.at(level),
+ fruitScorePix);
+ lastFruitScorePixmapName = fruitScorePixmapName.at(level);
+ }
+ }
+
+ if (lastMonsterScorePixmapName != monsterScorePixmapName.at(level) ||
+ (const char *) *monsterScorePixmapName.at(level) == '\0') {
+ if ((const char *) *monsterScorePixmapName.at(level) == '\0') {
+ monsterScorePix = textPixmap(monsterScoreString, monsterScorePix, CYAN);
+ } else {
+ monsterScorePix = loadPixmap(w, monsterScorePixmapName.at(level),
+ monsterScorePix);
+ lastMonsterScorePixmapName = monsterScorePixmapName.at(level);
+ }
+ }
+
+ if (lastWallPixmapName != wallPixmapName.at(level)) {
+ wallPix = loadPixmap(w, wallPixmapName.at(level), wallPix);
+ if (wallPix->isEmpty()) {
+ BlockWidth = 0;
+ BlockHeight = 0;
+ } else {
+ BlockWidth = wallPix->at(0)->width();
+ BlockHeight = wallPix->at(0)->height();
+ }
+ lastWallPixmapName = wallPixmapName.at(level);
+ }
+}
+
+void Painter::initbackPixmaps()
+{
+ backgroundColor = BLACK;
+
+ backPix.resize((BoardWidth-3)*BlockWidth, (BoardHeight-3)*BlockHeight );
+ backPix.fill(backgroundColor);
+}
+
+void Painter::initRoomPixmap()
+{
+ roomPix.resize((BoardWidth-3)*BlockWidth, (BoardHeight-3)*BlockHeight );
+ bitBlt(&roomPix,0,0, &backPix);
+
+ for (unsigned int x = 0; x < board->size(); x++) {
+ if (board->isBrick(x))
+ drawBrick(x);
+ if (board->isPrison(x) || board->isGate(x))
+ drawPrison(x);
+ if (board->isPoint(x))
+ drawPoint(x);
+ }
+}
+
+void Painter::drawBrick(int pos)
+{
+ int border = 0;
+ if (board->isBrick(board->move(pos, N ))) border |= (1 << 0);
+ if (board->isBrick(board->move(pos, NE))) border |= (1 << 1);
+ if (board->isBrick(board->move(pos, E ))) border |= (1 << 2);
+ if (board->isBrick(board->move(pos, SE))) border |= (1 << 3);
+ if (board->isBrick(board->move(pos, S ))) border |= (1 << 4);
+ if (board->isBrick(board->move(pos, SW))) border |= (1 << 5);
+ if (board->isBrick(board->move(pos, W ))) border |= (1 << 6);
+ if (board->isBrick(board->move(pos, NW))) border |= (1 << 7);
+
+ if (board->isOut(board->move(pos, N ))) border |= (1 << 8);
+ if (board->isOut(board->move(pos, NE))) border |= (1 << 9);
+ if (board->isOut(board->move(pos, E ))) border |= (1 << 10);
+ if (board->isOut(board->move(pos, SE))) border |= (1 << 11);
+ if (board->isOut(board->move(pos, S ))) border |= (1 << 12);
+ if (board->isOut(board->move(pos, SW))) border |= (1 << 13);
+ if (board->isOut(board->move(pos, W ))) border |= (1 << 14);
+ if (board->isOut(board->move(pos, NW))) border |= (1 << 15);
+
+ switch (border & 0xFF) {
+ case 31 : border = 0; break;
+ case 159 : border = 0; break;
+ case 63 : border = 0; break;
+ case 191 : border = 0; break;
+ case 241 : border = 1; break;
+ case 249 : border = 1; break;
+ case 243 : border = 1; break;
+ case 251 : border = 1; break;
+ case 124 : border = 2; break;
+ case 252 : border = 2; break;
+ case 126 : border = 2; break;
+ case 199 : border = 3; break;
+ case 231 : border = 3; break;
+ case 207 : border = 3; break;
+ case 28 : if ((border >> 8) > 0)
+ border = 24;
+ else
+ border = 4;
+ break;
+ case 112 : if ((border >> 8) > 0)
+ border = 27;
+ else
+ border = 5;
+ break;
+ case 7 : if ((border >> 8) > 0)
+ border = 25;
+ else
+ border = 6;
+ break;
+ case 193 : if ((border >> 8) > 0)
+ border = 26;
+ else
+ border = 7;
+ break;
+ case 247 : if ((border & (1 << 11)) > 0)
+ border = 23;
+ else
+ border = 8;
+ break;
+ case 119 : if ((border & (1 << 15)) > 0)
+ border = 8;
+ if ((border & (1 << 11)) > 0)
+ border = 11;
+ break;
+ case 223 : if ((border & (1 << 13)) > 0)
+ border = 20;
+ else
+ border = 9;
+ break;
+ case 221 : if ((border & (1 << 13)) > 0)
+ border = 10;
+ if ((border & (1 << 9)) > 0)
+ border = 9;
+ break;
+ case 253 : if ((border & (1 << 9)) > 0)
+ border = 21;
+ else
+ border = 10;
+ break;
+ case 127 : if ((border & (1 << 15)) > 0)
+ border = 22;
+ else
+ border = 11;
+ break;
+ case 30 : border = 12; break;
+ case 240 : border = 13; break;
+ case 15 : border = 14; break;
+ case 225 : border = 15; break;
+ case 135 : border = 16; break;
+ case 195 : border = 17; break;
+ case 60 : border = 18; break;
+ case 120 : border = 19; break;
+ case 255 : border = 28; break;
+ default : border = -1;
+ }
+ if (border != -1 && border < (int) wallPix->count()) {
+ QRect rect = this->rect(pos, WallPix);
+ bitBlt(&roomPix, rect.x(), rect.y(), wallPix->at((uint) border));
+ }
+}
+
+void Painter::drawPrison(int pos)
+{
+ int border = 0;
+ if (board->isPrison(board->move(pos, N ))) border |= (1 << 0);
+ if (board->isPrison(board->move(pos, NE))) border |= (1 << 1);
+ if (board->isPrison(board->move(pos, E ))) border |= (1 << 2);
+ if (board->isPrison(board->move(pos, SE))) border |= (1 << 3);
+ if (board->isPrison(board->move(pos, S ))) border |= (1 << 4);
+ if (board->isPrison(board->move(pos, SW))) border |= (1 << 5);
+ if (board->isPrison(board->move(pos, W ))) border |= (1 << 6);
+ if (board->isPrison(board->move(pos, NW))) border |= (1 << 7);
+
+ if (board->isGate(board->move(pos, N ))) border |= (1 << 8);
+ if (board->isGate(board->move(pos, NE))) border |= (1 << 9);
+ if (board->isGate(board->move(pos, E ))) border |= (1 << 10);
+ if (board->isGate(board->move(pos, SE))) border |= (1 << 11);
+ if (board->isGate(board->move(pos, S ))) border |= (1 << 12);
+ if (board->isGate(board->move(pos, SW))) border |= (1 << 13);
+ if (board->isGate(board->move(pos, W ))) border |= (1 << 14);
+ if (board->isGate(board->move(pos, NW))) border |= (1 << 15);
+
+ switch (border & 0xFF) {
+ case 31 : border = 0; break;
+ case 159 : border = 0; break;
+ case 63 : border = 0; break;
+ case 241 : border = 1; break;
+ case 249 : border = 1; break;
+ case 243 : border = 1; break;
+ case 124 : border = 2; break;
+ case 252 : border = 2; break;
+ case 126 : border = 2; break;
+ case 199 : border = 3; break;
+ case 231 : border = 3; break;
+ case 207 : border = 3; break;
+ case 28 : if ((border >> 8) != 0)
+ border = 12;
+ else
+ border = 4;
+ break;
+ case 112 : if ((border >> 8) != 0)
+ border = 13;
+ else
+ border = 5;
+ break;
+ case 7 : if ((border >> 8) != 0)
+ border = 14;
+ else
+ border = 6;
+ break;
+ case 193 : if ((border >> 8) != 0)
+ border = 15;
+ else
+ border = 7;
+ break;
+ case 247 : border = 8; break;
+ case 223 : border = 9; break;
+ case 253 : border = 10; break;
+ case 127 : border = 11; break;
+ default : border = -1;
+ }
+ if (board->isGate(pos)) {
+ if (board->isGate(board->move(pos, N)))
+ border = 17;
+ else
+ border = 16;
+ }
+
+ if (border != -1 && border < (int) prisonPix->count()) {
+ QRect rect = this->rect(pos, PrisonPix);
+ bitBlt(&roomPix, rect.x(), rect.y(), prisonPix->at((uint) border));
+ }
+}
+
+void Painter::drawPoint(int pos)
+{
+ if (!pointPix->isEmpty()) {
+ QRect rect = this->rect(pos, PointPix);
+ bitBlt(&roomPix, rect.x(), rect.y(), pointPix->at(0));
+ }
+}
+
+QString Painter::decodeHexOctString(QString s)
+{
+ QString value;
+ QString valids;
+ int pos, xpos = 0, opos = 0;
+ int v, len, leadin;
+ const char *ptr;
+ uchar c;
+
+ while (((xpos = s.find(QRegExp("\\\\x[0-9a-fA-F]+"), xpos)) != -1) ||
+ ((opos = s.find(QRegExp("\\\\[0-7]+"), opos)) != -1)) {
+ if (xpos != -1) {
+ valids = "0123456789abcdef";
+ leadin = 2;
+ pos = xpos;
+ } else {
+ valids = "01234567";
+ leadin = 1;
+ pos = opos;
+ }
+
+ c = '\0';
+ len = 0;
+ value = s.mid(pos+leadin, 3);
+ ptr = (const char *) value;
+
+ while (*ptr != '\0' && (v = valids.find(*ptr++, 0, FALSE)) != -1) {
+ c = (c * valids.length()) + v;
+ len++;
+ }
+
+ value.fill(c, 1);
+ s.replace(pos, len+leadin, value);
+ }
+
+ return s;
+}
+
+void Painter::fillScoreString(QStrList &list, QArray<int> &values)
+{
+ if( !list.isEmpty())
+ list.clear();
+
+ QString s;
+
+ for (uint i = 0; i < values.size(); i++) {
+
+ if (values[i] < 10 || values[i] > 10000)
+ s = "?";
+ else if (values[i] == 1600)
+ s = "\x1a\x1b";
+ else if (values[i] < 100) {
+ s = "\x0e";
+ s.insert(0, char (values[i] / 10 + 0x10));
+ } else if (values[i] < 1000) {
+ s = "\x0f";
+ s.insert(0, char (values[i] / 100 + 0x10));
+ } else {
+ s = "\x0f\x10";
+ s.insert(0, char (values[i] / 1000 + 0x10));
+ }
+
+ list.append(s.data());
+ }
+}
+
+void Painter::fillArray(QArray<int> &array, QString values, int max)
+{
+ array.resize(max);
+ int last = 0;
+ bool ok;
+ QString value;
+
+ for (uint i = 0; i < array.size(); i++) {
+ if (values.find(',') < 0 && values.length() > 0) {
+ value = values;
+ values = "";
+ }
+ if (values.find(',') >= 0) {
+ value = values.left(values.find(','));
+ values.remove(0,values.find(',')+1);
+ }
+ array[i] = value.toInt(&ok);
+ if (ok)
+ last = array[i];
+ else
+ array[i] = last;
+ }
+}
+
+void Painter::fillStrList(QStrList &list, QString values, int max)
+{
+ if (!list.isEmpty())
+ list.clear();
+
+ QString last = "";
+ QString value;
+
+ for (uint i = 0; i < (uint) max; i++) {
+ if (values.find(',') < 0 && values.length() > 0) {
+ value = values;
+ values = "";
+ }
+ if (values.find(',') >= 0) {
+ value = values.left(values.find(','));
+ values.remove(0,values.find(',')+1);
+ }
+ if (!value.isEmpty())
+ last = decodeHexOctString(value);
+ list.append(last);
+ }
+}
+
+void Painter::fillPixmapName(QStrList &pixmapName)
+{
+ QStrList list = pixmapName;
+
+ if (!pixmapName.isEmpty())
+ pixmapName.clear();
+
+ QString pixmap;
+
+ QFileInfo fileInfo;
+
+ for (uint i = 0; i < list.count(); i++) {
+ pixmap = list.at(i);
+
+ if (pixmap.left(1) != "/" && pixmap.left(1) != "~")
+ pixmap = FIND_APP_DATA( pixmapDirectory+pixmap );
+
+ fileInfo.setFile(pixmap);
+ if (!fileInfo.isReadable() || !fileInfo.isFile())
+ pixmap = "";
+
+ pixmapName.append(pixmap);
+ }
+}
+
+void Painter::confLevels(bool defGroup)
+{
+ APP_CONFIG_BEGIN( cfg );
+ if (defGroup || cfg->hasKey("Levels"))
+ maxLevel = cfg->readNumEntry("Levels", 13);
+ APP_CONFIG_END( cfg );
+}
+
+void Painter::confMisc(bool defGroup)
+{
+ APP_CONFIG_BEGIN( cfg );
+ if (defGroup || cfg->hasKey("PixmapDirectory")) {
+ pixmapDirectory = cfg->readEntry("PixmapDirectory");
+
+ if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~")
+ pixmapDirectory.insert(0, "pics/");
+ if (pixmapDirectory.right(1) != "/")
+ pixmapDirectory.append("/");
+ }
+
+ if (defGroup || cfg->hasKey("PointPixmapName"))
+ fillStrList(pointPixmapName,
+ cfg->readEntry("PointPixmapName", "point.xpm"), maxLevel+1);
+ if (defGroup || cfg->hasKey("WallPixmapName"))
+ fillStrList(wallPixmapName,
+ cfg->readEntry("WallPixmapName", "wall.xpm"), maxLevel+1);
+ if (defGroup || cfg->hasKey("PrisonPixmapName"))
+ fillStrList(prisonPixmapName,
+ cfg->readEntry("PrisonPixmapName", "prison.xpm"), maxLevel+1);
+ if (defGroup || cfg->hasKey("EnergizerPixmapName"))
+ fillStrList(energizerPixmapName,
+ cfg->readEntry("EnergizerPixmapName", "switch.xpm"),maxLevel+1);
+ if (defGroup || cfg->hasKey("FruitPixmapName"))
+ fillStrList(fruitPixmapName,
+ cfg->readEntry("FruitPixmapName", "fruit.xpm"), maxLevel+1);
+ if (defGroup || cfg->hasKey("PacmanPixmapName"))
+ fillStrList(pacmanPixmapName,
+ cfg->readEntry("PacmanPixmapName", "pacman.xpm"), maxLevel+1);
+ if (defGroup || cfg->hasKey("DyingPixmapName"))
+ fillStrList(dyingPixmapName,
+ cfg->readEntry("DyingPixmapName", "dying.xpm"), maxLevel+1);
+ if (defGroup || cfg->hasKey("EyesPixmapName"))
+ fillStrList(eyesPixmapName,
+ cfg->readEntry("EyesPixmapName", "eyes.xpm"), maxLevel+1);
+ if (defGroup || cfg->hasKey("MonsterPixmapName"))
+ fillStrList(monsterPixmapName,
+ cfg->readEntry("MonsterPixmapName", "monster.xpm"), maxLevel+1);
+
+ if (defGroup || cfg->hasKey("FruitScorePixmapName"))
+ fillStrList(fruitScorePixmapName,
+ cfg->readEntry("FruitScorePixmapName"), maxLevel+1);
+ if (defGroup || cfg->hasKey("MonsterScorePixmapName"))
+ fillStrList(monsterScorePixmapName,
+ cfg->readEntry("MonsterScorePixmapName"), maxLevel+1);
+ APP_CONFIG_END( cfg );
+}
+
+void Painter::confScoring(bool defGroup)
+{
+ APP_CONFIG_BEGIN( cfg );
+ if (defGroup || cfg->hasKey("FruitScore"))
+ fillArray(fruitScore,
+ cfg->readEntry("FruitScore",
+ "100,300,500,,700,,1000,,2000,,3000,,5000"),
+ maxLevel+1);
+ if (defGroup || cfg->hasKey("MonsterScore"))
+ fillArray(monsterScore,
+ cfg->readEntry("MonsterScore", "200,400,800,1600"), 4);
+
+ if (defGroup || cfg->hasKey("FruitScoreString"))
+ fillStrList(fruitScoreString,
+ cfg->readEntry("FruitScoreString"), maxLevel+1);
+ if (defGroup || cfg->hasKey("MonsterScoreString"))
+ fillStrList(monsterScoreString,
+ cfg->readEntry("MonsterScoreString"), 4);
+ APP_CONFIG_END( cfg );
+}
+
+void Painter::confScheme()
+{
+ APP_CONFIG_BEGIN( cfg );
+ SAVE_CONFIG_GROUP( cfg, oldgroup );
+ QString newgroup;
+
+ // if not set, read mode and scheme from the configfile
+ if (mode == -1 && scheme == -1) {
+ scheme = cfg->readNumEntry("Scheme", -1);
+ mode = cfg->readNumEntry("Mode", -1);
+
+ // if mode is not set in the defGroup-group, lookup the scheme group
+ if (scheme != -1 || mode == -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ cfg->setGroup(newgroup);
+
+ mode = cfg->readNumEntry("Mode", -1);
+ RESTORE_CONFIG_GROUP( cfg, oldgroup );
+ }
+ }
+
+ confLevels();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ cfg->setGroup(newgroup);
+
+ confLevels(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ cfg->setGroup(newgroup);
+
+ confLevels(FALSE);
+ }
+
+ RESTORE_CONFIG_GROUP( cfg, oldgroup );
+
+ confMisc();
+ confScoring();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ cfg->setGroup(newgroup);
+
+ confMisc(FALSE);
+ confScoring(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ cfg->setGroup(newgroup);
+
+ confMisc(FALSE);
+ confScoring(FALSE);
+ }
+
+ if ((const char *) *fruitScoreString.at(0) == '\0')
+ fillScoreString(fruitScoreString, fruitScore);
+ if ((const char *) *monsterScoreString.at(0) == '\0')
+ fillScoreString(monsterScoreString, monsterScore);
+
+ fillPixmapName(pointPixmapName);
+ fillPixmapName(wallPixmapName);
+ fillPixmapName(prisonPixmapName);
+ fillPixmapName(energizerPixmapName);
+ fillPixmapName(fruitPixmapName);
+ fillPixmapName(pacmanPixmapName);
+ fillPixmapName(dyingPixmapName);
+ fillPixmapName(eyesPixmapName);
+ fillPixmapName(monsterPixmapName);
+ fillPixmapName(fruitScorePixmapName);
+ fillPixmapName(monsterScorePixmapName);
+
+ initPixmaps();
+ initbackPixmaps();
+ initRoomPixmap();
+
+ RESTORE_CONFIG_GROUP( cfg, oldgroup );
+ APP_CONFIG_END( cfg );
+}
+
+void Painter::setScheme(int Scheme, int Mode, Bitfont *font)
+{
+ bitfont = font;
+
+ mode = Mode;
+ scheme = Scheme;
+
+ confScheme();
+}
+
+void Painter::setLevel(int Level)
+{
+ level = Level;
+
+ initPixmaps();
+ initbackPixmaps();
+ initRoomPixmap();
+}
+
+int Painter::checkRange(int value, int max, int min)
+{
+ if (value < min) {
+ printf("Painter::checkRange (value = %d, max = %d, min = %d)\n",
+ value, max, min);
+ return min;
+ } else if (value > max) {
+ printf("Painter::checkRange (value = %d, max = %d, min = %d)\n",
+ value, max, min);
+ return max;
+ } else
+ return value;
+}
diff --git a/noncore/games/kpacman/painter.h b/noncore/games/kpacman/painter.h
new file mode 100644
index 0000000..3a4eae2
--- a/dev/null
+++ b/noncore/games/kpacman/painter.h
@@ -0,0 +1,148 @@
+#ifndef PAINTER_H
+#define PAINTER_H
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <kapp.h>
+#include <klocale.h>
+#endif
+
+#include <qpixmap.h>
+#include <qbitmap.h>
+#include <qlabel.h>
+#include <qcolor.h>
+#include <qlist.h>
+#include <qstrlist.h>
+#include <qregexp.h>
+
+#include "board.h"
+#include "bitfont.h"
+#include "colors.h"
+
+enum PixMap { PacmanPix, DyingPix, MonsterPix, EyesPix, FruitPix,
+ PointPix, EnergizerPix, WallPix, PrisonPix,
+ FruitScorePix, MonsterScorePix };
+enum DrawWidget { Widget, RoomPix, BackPix };
+
+class Painter
+{
+public:
+ Painter (Board *, QWidget *parent=0, int scheme=-1, int mode=-1,Bitfont *font=0);
+ QPixmap levelPix() { return roomPix; }
+
+ void setScheme(int scheme=-1, int mode=-1, Bitfont *font=0);
+ void setLevel(int level=0);
+
+ QRect rect(int pos, PixMap pix, uint i = 0);
+ QRect rect(int pos, QString str, int align = QLabel::AlignCenter );
+ QRect rect(QRect r1, QRect r2);
+
+ void draw(QPoint point, DrawWidget where, QPixmap pix);
+ void draw(QRect rect, DrawWidget where, QPixmap pix);
+ void draw(int pos, DrawWidget where, PixMap pix, uint i = 0);
+ QPixmap draw(int pos, DrawWidget where, QString str,
+ QColor fg, QColor bg = QColor(), int align = QLabel::AlignCenter);
+ QRect draw(int col, int row, DrawWidget where, QString str,
+ QColor fg, QColor bg = QColor(), int align = QLabel::AlignCenter);
+
+ void drawBrick(int pos);
+ void drawPrison(int pos);
+ void drawPoint(int pos);
+
+ void erase(int pos, PixMap pix, uint i = 0);
+
+ int maxPixmaps(PixMap pix);
+
+protected:
+ QString decodeHexOctString(QString str);
+
+ void fillScoreString(QStrList &, QArray<int> &);
+ void fillArray(QArray<int> &, QString, int);
+ void fillStrList(QStrList &, QString, int);
+ void fillPixmapName(QStrList &);
+
+ void confScheme();
+ void confLevels(bool defGroup=TRUE);
+ void confMisc(bool defGroup=TRUE);
+ void confScoring(bool defGroup=TRUE);
+
+ void initPixmaps();
+ void initRoomPixmap();
+ void initbackPixmaps();
+
+private:
+ QWidget *w;
+ Board *board;
+ Bitfont *bitfont;
+
+ int BlockWidth;
+ int BlockHeight;
+
+ QArray<int> fruitScore;
+ QStrList fruitScoreString;
+ QArray<int> monsterScore;
+ QStrList monsterScoreString;
+
+ QString pixmapDirectory;
+
+ QStrList pointPixmapName;
+ QStrList wallPixmapName;
+ QStrList prisonPixmapName;
+ QStrList energizerPixmapName;
+ QStrList fruitPixmapName;
+ QStrList pacmanPixmapName;
+ QStrList dyingPixmapName;
+ QStrList eyesPixmapName;
+ QStrList monsterPixmapName;
+ QStrList fruitScorePixmapName;
+ QStrList monsterScorePixmapName;
+
+ QString lastPointPixmapName;
+ QString lastWallPixmapName;
+ QString lastPrisonPixmapName;
+ QString lastEnergizerPixmapName;
+ QString lastFruitPixmapName;
+ QString lastPacmanPixmapName;
+ QString lastDyingPixmapName;
+ QString lastEyesPixmapName;
+ QString lastMonsterPixmapName;
+ QString lastFruitScorePixmapName;
+ QString lastMonsterScorePixmapName;
+
+ QList<QPixmap> *loadPixmap(QWidget *parent, QString pixmapName,
+ QList<QPixmap> *pixmaps=0);
+ QList<QPixmap> *textPixmap(QStrList &, QList<QPixmap> *pixmaps=0,
+ QColor fg = BLACK, QColor bg = QColor());
+ QList<QPixmap> *textPixmap(QString str, QList<QPixmap> *pixmaps=0,
+ QColor fg = BLACK, QColor bg = QColor());
+
+ QPoint point(int pos);
+ int checkRange(int value, int max, int min=0);
+
+ QList<QPixmap> *wallPix;
+ QList<QPixmap> *prisonPix;
+ QList<QPixmap> *pointPix;
+ QList<QPixmap> *energizerPix;
+ QList<QPixmap> *fruitPix;
+ QList<QPixmap> *pacmanPix;
+ QList<QPixmap> *dyingPix;
+ QList<QPixmap> *eyesPix;
+ QList<QPixmap> *monsterPix;
+ QList<QPixmap> *fruitScorePix;
+ QList<QPixmap> *monsterScorePix;
+
+ QPixmap roomPix;
+ QPixmap backPix;
+
+ bool plainColor;
+ QColor backgroundColor;
+
+ int maxLevel;
+ int level;
+
+ int scheme;
+ int mode;
+};
+
+#endif // PAINTER_H
diff --git a/noncore/games/kpacman/portable.h b/noncore/games/kpacman/portable.h
new file mode 100644
index 0000000..ff0912b
--- a/dev/null
+++ b/noncore/games/kpacman/portable.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ portable.h - various bits that ease porting kpacman to other platforms.
+ Currently KDE2 and Qtopia ports exist.
+ -------------------
+ begin : Mon Mar 18 12:35:24 EET 2002
+ copyright : (C) 2002 by Catalin Climov
+ email : catalin@climov.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef PORTABLE_H
+#define PORTABLE_H
+
+#ifdef QWS
+#define QPE_PORT
+#else
+#define KDE2_PORT
+#define KDE_PORT
+#endif
+
+#if defined( KDE2_PORT )
+
+#define APP kapp
+
+#define APP_CONFIG_BEGIN( cfgname ) KConfig cfgname = kapp->config()
+#define APP_CONFIG_END( cfgname ) cfgname->sync()
+#define SAVE_CONFIG_GROUP( cfgname, groupname ) QString groupname = configname->group()
+#define RESTORE_CONFIG_GROUP( cfgname, groupname ) configname->setGroup( groupname )
+
+#define FIND_APP_DATA( dataname ) KGlobal::dirs()->findResource( "appdata", dataname )
+
+#elif defined( QPE_PORT )
+
+#define i18n( x ) x
+#define KTMainWindow QMainWindow
+#define KMenuBar QMenuBar
+#define KAccel QAccel
+#define APP qApp
+
+#define APP_CONFIG_BEGIN( cfgname ) Config* cfgname = new Config("kpacman"); cfgname->setGroup("Default");
+#define APP_CONFIG_END( cfgname ) delete cfgname
+#define SAVE_CONFIG_GROUP( cfgname, groupname )
+#define RESTORE_CONFIG_GROUP( cfgname, groupname ) cfgname->setGroup("Default")
+
+#define FIND_APP_DATA( dataname ) (QPEApplication::qpeDir()+"share/kpacman/"+dataname)
+
+#else
+
+#error "Err, I don't know what platform to compile for (KDE2 or Qtopia)"
+
+#endif
+
+#define APP_QUIT() APP->quit()
+
+#endif // PORTABLE_H
diff --git a/noncore/games/kpacman/referee.cpp b/noncore/games/kpacman/referee.cpp
new file mode 100644
index 0000000..567a8ed
--- a/dev/null
+++ b/noncore/games/kpacman/referee.cpp
@@ -0,0 +1,1426 @@
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <kapp.h>
+#include <kconfig.h>
+#include <kstddirs.h>
+#include <kaccel.h>
+#include <referee.h>
+#include <referee.moc>
+#elif defined( QPE_PORT )
+#include <qaccel.h>
+#include <qpe/qpeapplication.h>
+#include "config.h"
+#include "referee.h"
+#endif
+
+#include <qdatetm.h>
+#include <stdlib.h>
+#include <qtimer.h>
+#include <qevent.h>
+#include <qcolor.h>
+#include <qkeycode.h>
+#include <qfileinfo.h>
+
+#include "board.h"
+#include "pacman.h"
+#include "monster.h"
+#include "fruit.h"
+#include "painter.h"
+
+Referee::Referee( QWidget *parent, const char *name, int Scheme, int Mode, Bitfont *font)
+ : QWidget( parent, name )
+{
+ gameState.resize(12);
+ gameTimer = 0;
+ energizerTimer = 0;
+
+ focusedPause = FALSE;
+ setFocusPolicy(QWidget::StrongFocus);
+
+ initKeys();
+
+ scheme = Scheme;
+ mode = Mode;
+ confScheme();
+
+ board = new Board(BoardWidth*BoardHeight);
+
+ pix = new Painter(board, this, scheme, mode, font);
+ setFixedSize(pix->levelPix().size());
+
+ pacman = new Pacman(board);
+
+ fruit = new Fruit(board);
+
+ monsters = new QList<Monster>;
+ monsters->setAutoDelete(TRUE);
+
+ monsterRect = new QList<QRect>;
+ monsterRect->setAutoDelete(TRUE);
+
+ energizers = new QList<Energizer>;
+ energizers->setAutoDelete(TRUE);
+
+ energizerRect = new QList<QRect>;
+ energizerRect->setAutoDelete(TRUE);
+
+ pacmanRect.setRect(0, 0, 0, 0);
+ fruitRect.setRect(0, 0, 0, 0);
+
+ QTime midnight( 0, 0, 0 );
+ srand( midnight.secsTo(QTime::currentTime()) );
+
+ lifes = 0;
+ points = 0;
+
+ emit setLifes(lifes);
+ emit setPoints(points);
+
+ intro();
+}
+
+void Referee::paintEvent( QPaintEvent *e)
+{
+ if (gameState.testBit(HallOfFame))
+ return;
+
+ QRect rect = e->rect();
+
+ if (!rect.isEmpty()) {
+ QPixmap p = pix->levelPix();
+ bitBlt(this, rect.x(), rect.y(),
+ &p, rect.x(), rect.y(), rect.width(), rect.height());
+ }
+
+ if ((gameState.testBit(GameOver) || gameState.testBit(Demonstration)) &&
+ rect.intersects(pix->rect(board->position(fruithome), i18n("GAME OVER"))))
+ pix->draw(board->position(fruithome), Widget, i18n("GAME OVER"), RED);
+
+ for (Energizer *e = energizers->first(); e != 0; e = energizers->next()) {
+ if (e && e->state() == on &&
+ rect.intersects(pix->rect(e->position(), EnergizerPix)) &&
+ !(e->position() == pacman->position() && gameState.testBit(Scoring))) {
+ if (e->pix() != -1)
+ pix->draw(e->position(), Widget, EnergizerPix, e->pix());
+ }
+ }
+
+ if (!gameState.testBit(Init)) {
+
+ if (!gameState.testBit(Dying) && (fruit->pix() != -1))
+ if (fruit->state() != active) {
+ if (rect.intersects(pix->rect(fruit->position(), FruitScorePix, fruit->pix())))
+ pix->draw(fruit->position(), Widget, FruitScorePix, fruit->pix());
+ } else {
+ if (rect.intersects(pix->rect(fruit->position(), FruitPix, fruit->pix())))
+ pix->draw(fruit->position(), Widget, FruitPix, fruit->pix());
+ }
+
+ for (Monster *m = monsters->first(); m != 0; m = monsters->next())
+ if (m && m->state() == harmless &&
+ rect.intersects(pix->rect(m->position(), MonsterPix)) &&
+ !(m->position() == pacman->position() && gameState.testBit(Scoring))) {
+ if (m->body() != -1)
+ pix->draw(m->position(), Widget, MonsterPix, m->body());
+ if (m->eyes() != -1)
+ pix->draw(m->position(), Widget, EyesPix, m->eyes());
+ }
+
+ if (!gameState.testBit(Scoring) && !gameState.testBit(LevelDone) &&
+ rect.intersects(pix->rect(pacman->position(), PacmanPix)) && pacman->pix() != -1)
+ pix->draw(pacman->position(), Widget, PacmanPix, pacman->pix());
+
+ for (Monster *m = monsters->first(); m != 0; m = monsters->next())
+ if (m && m->state() != harmless &&
+ rect.intersects(pix->rect(m->position(), MonsterPix)) &&
+ !(m->position() == pacman->position() && gameState.testBit(Scoring))) {
+ if (m->body() != -1)
+ pix->draw(m->position(), Widget, MonsterPix, m->body());
+ if (m->eyes() != -1)
+ pix->draw(m->position(), Widget, EyesPix, m->eyes());
+ }
+ }
+
+ if (gameState.testBit(Scoring) &&
+ rect.intersects(pix->rect(pacman->position(), MonsterScorePix, monstersEaten-1)))
+ pix->draw(pacman->position(), Widget, MonsterScorePix, monstersEaten-1);
+
+ if (gameState.testBit(Init) && gameState.testBit(Dying) &&
+ timerCount < pix->maxPixmaps(DyingPix) &&
+ rect.intersects(pix->rect(pacman->position(), PacmanPix)))
+ pix->draw(pacman->position(), Widget, DyingPix, timerCount);
+
+ if (gameState.testBit(LevelDone) &&
+ rect.intersects(pix->rect(pacman->position(), PacmanPix)))
+ pix->draw(pacman->position(), Widget, PacmanPix, pacman->pix());
+
+ if (gameState.testBit(Player) &&
+ rect.intersects(pix->rect(board->position(monsterhome, 0), i18n("PLAYER ONE"))))
+ pix->draw(board->position(monsterhome, 0), Widget, i18n("PLAYER ONE"), CYAN);
+
+ if (gameState.testBit(Ready) &&
+ rect.intersects(pix->rect(board->position(fruithome), i18n("READY!"))))
+ pix->draw(board->position(fruithome), Widget, i18n("READY!"), YELLOW);
+
+ if (gameState.testBit(Paused) &&
+ rect.intersects(pix->rect((BoardWidth*BoardHeight)/2-BoardWidth, i18n("PAUSED"))))
+ pix->draw((BoardWidth*BoardHeight)/2-BoardWidth, Widget, i18n("PAUSED"), RED, BLACK);
+}
+
+void Referee::timerEvent( QTimerEvent *e )
+{
+ if (gameState.testBit(HallOfFame))
+ return;
+
+ QRect lastRect;
+ int lastPix;
+ bool moved = FALSE;
+ int eated = 0;
+
+ if (e->timerId() == energizerTimer) {
+ for (int e = 0; e < board->energizers(); e++) {
+ lastRect = pix->rect(energizers->at(e)->position(), EnergizerPix);
+ lastPix = energizers->at(e)->pix();
+ if (energizers->at(e)->move()) {
+ moved = TRUE;
+ *energizerRect->at(e) = pix->rect(energizers->at(e)->position(), EnergizerPix);
+ if (lastPix == energizers->at(e)->pix() &&
+ lastRect == pix->rect(energizers->at(e)->position(), EnergizerPix))
+ energizerRect->at(e)->setRect(0, 0, 0, 0);
+ else
+ *energizerRect->at(e) = pix->rect(*energizerRect->at(e), lastRect);
+ }
+ }
+
+ for (int e = 0; e < board->energizers(); e++)
+ if (!energizerRect->at(e)->isNull())
+ repaint(*energizerRect->at(e), FALSE);
+
+ return;
+ }
+
+ timerCount++;
+
+ lastRect = pix->rect(pacman->position(), PacmanPix);
+ lastPix = pacman->pix();
+
+ if (moved = pacman->move()) { // pacman really moved
+ pacmanRect = pix->rect(pacman->position(), PacmanPix);
+ if (lastPix == pacman->pix() &&
+ lastRect == pix->rect(pacman->position(), PacmanPix))
+ pacmanRect.setRect(0, 0, 0, 0); // nothing to do, because the pixmap
+ else // and the position isn't changed.
+ pacmanRect = pix->rect(pacmanRect, lastRect);
+ } else
+ pacmanRect.setRect(0, 0, 0, 0);
+
+ int pos = pacman->position();
+
+ if (moved && board->isMonster(pos) && !gameState.testBit(Dying)) {
+ for (Monster *m = monsters->first(); m != 0; m = monsters->next())
+ if (m && m->position() == pos) {
+ if (m->state() == harmless && !gameState.testBit(Dying)) {
+ m->setREM(remTicks[level]);
+ m->setDirection(X); // prevent movement before eaten()
+ eated++;
+ if (gameState.testBit(Introducing))
+ m->setPosition(OUT);
+ }
+ if (m->state() == dangerous && !gameState.testBit(Dying))
+ killed();
+ }
+ }
+
+ if (moved && !gameState.testBit(Dying)) {
+ if (board->isPoint(pos)) {
+ board->reset(pos, Point);
+ score(pointScore);
+ pix->erase(pos, PointPix);
+ }
+ if (board->isEnergizer(pos)) {
+ for (int e = 0; e < board->energizers();e++) {
+ if (energizers->at(e)->position() == pos) {
+ energizers->at(e)->setOff();
+ energizers->remove(e);
+ energizerRect->remove(e);
+ e = board->energizers();
+ }
+ }
+ board->reset(pos, energizer);
+ score(energizerScore);
+ monstersEaten = 0;
+ for (Monster *m = monsters->first(); m != 0; m = monsters->next())
+ if (m && m->state() != rem) {
+ m->setHarmless(harmlessTicks[level], harmlessDurTicks[level],
+ harmlessWarnTicks[level]);
+ if (gameState.testBit(Introducing))
+ m->setDirection(board->turn(m->direction()));
+ }
+ }
+ if (pos == fruit->position() && fruit->state() == active) {
+ fruit->setEaten(fruitScoreDurTicks[level]);
+ initFruit(FALSE);
+ score(fruitScore[fruit->pix()]);
+ }
+ }
+
+ if (!gameState.testBit(Introducing)) {
+ if (fruit->state() != active && fruit->pix() >= 0)
+ lastRect = pix->rect(fruit->position(), FruitScorePix, fruit->pix());
+ else
+ lastRect = pix->rect(fruit->position(), FruitPix, fruit->pix());
+
+ lastPix = fruit->pix();
+ if (fruit->move()) {
+ if (pos == fruit->position() && fruit->state() == active) {
+ fruit->setEaten(fruitScoreDurTicks[level]);
+ initFruit(FALSE);
+ score(fruitScore[fruit->pix()]);
+ }
+ if (fruit->state() != active && fruit->pix() >= 0)
+ fruitRect = pix->rect(fruit->position(), FruitScorePix, fruit->pix());
+ else
+ fruitRect = pix->rect(fruit->position(), FruitPix, fruit->pix());
+ if (lastPix == fruit->pix() && lastRect == fruitRect)
+ fruitRect.setRect(0, 0, 0, 0);
+ else
+ fruitRect = pix->rect(fruitRect, lastRect);
+ } else
+ fruitRect.setRect(0, 0, 0, 0);
+ } else
+ fruitRect.setRect(0, 0, 0, 0);
+
+ int lastBodyPix;
+ int lastEyesPix;
+
+ for (Monster *m = monsters->first(); m != 0; m = monsters->next())
+ if (m) {
+ lastRect = pix->rect(m->position(), MonsterPix);
+ lastBodyPix = m->body();
+ lastEyesPix = m->eyes();
+ if (m->move()) {
+ moved = TRUE;
+ *monsterRect->at(m->id()) = pix->rect(m->position(), MonsterPix);
+ if (lastBodyPix == m->body() && lastEyesPix == m->eyes() &&
+ lastRect == pix->rect(m->position(), MonsterPix))
+ monsterRect->at(m->id())->setRect(0, 0, 0, 0);
+ else
+ *monsterRect->at(m->id()) = pix->rect(*monsterRect->at(m->id()), lastRect);
+ if (m->position() == pos && !gameState.testBit(Dying)) {
+ if (m->state() == harmless && !gameState.testBit(Dying)) {
+ m->setREM(remTicks[level]);
+ eated++;
+ if (gameState.testBit(Introducing)) {
+ m->setPosition(OUT);
+ m->setDirection(X);
+ }
+ }
+ if (m->state() == dangerous && !gameState.testBit(Dying))
+ killed();
+ }
+ } else
+ monsterRect->at(m->id())->setRect(0, 0, 0, 0);
+ }
+
+ for (int m = 0; m < board->monsters(); m++)
+ if (pacmanRect.intersects(*monsterRect->at(m))) {
+ pacmanRect = pix->rect(pacmanRect, *monsterRect->at(m));
+ monsterRect->at(m)->setRect(0, 0, 0, 0);
+ } else
+ for (int im = m+1; im < board->monsters(); im++)
+ if (monsterRect->at(m)->intersects(*monsterRect->at(im))) {
+ *monsterRect->at(m) = pix->rect(*monsterRect->at(m), *monsterRect->at(im));
+ monsterRect->at(im)->setRect(0, 0, 0, 0);
+ }
+
+ if (!pacmanRect.isNull())
+ repaint(pacmanRect, FALSE);
+
+ if (!fruitRect.isNull())
+ repaint(fruitRect, FALSE);
+
+ for (int m = 0; m < board->monsters(); m++)
+ if (!monsterRect->at(m)->isNull())
+ repaint(*monsterRect->at(m), FALSE);
+
+ if (board->points() == 0 && !gameState.testBit(Dying))
+ levelUp();
+
+ if (eated > 0 && !gameState.testBit(Dying)) {
+ timerCount = eated;
+ eaten();
+ }
+
+ if (gameState.testBit(Introducing) && moved)
+ introPlay();
+}
+
+void Referee::repaintFigures()
+{
+ pacmanRect = pix->rect(pacman->position(), PacmanPix);
+
+ for (int e = 0; e < board->energizers(); e++) {
+ *energizerRect->at(e) = pix->rect(board->position(energizer, e), EnergizerPix);
+
+ if (pacmanRect.intersects(*energizerRect->at(e))) {
+ pacmanRect = pix->rect(pacmanRect, *energizerRect->at(e));
+ energizerRect->at(e)->setRect(0, 0, 0, 0);
+ } else
+ for (int ie = e+1; ie < board->energizers(); ie++)
+ if (energizerRect->at(e)->intersects(*energizerRect->at(ie))) {
+ *energizerRect->at(e) = pix->rect(*energizerRect->at(e), *energizerRect->at(ie));
+ energizerRect->at(ie)->setRect(0, 0, 0, 0);
+ }
+ }
+
+ if (fruit->pix() != -1 && fruit->state() != active)
+ fruitRect = pix->rect(fruit->position(), FruitScorePix, fruit->pix());
+ else
+ fruitRect = pix->rect(fruit->position(), FruitPix, fruit->pix());
+
+ if (pacmanRect.intersects(fruitRect)) {
+ pacmanRect = pix->rect(pacmanRect, fruitRect);
+ fruitRect.setRect(0, 0, 0, 0);
+ }
+
+ for (int m = 0; m < board->monsters(); m++) {
+ *monsterRect->at(m) = pix->rect(board->position(monster, m), MonsterPix);
+
+ if (pacmanRect.intersects(*monsterRect->at(m))) {
+ pacmanRect = pix->rect(pacmanRect, *monsterRect->at(m));
+ monsterRect->at(m)->setRect(0, 0, 0, 0);
+ } else
+ for (int im = m+1; im < board->monsters(); im++)
+ if (monsterRect->at(m)->intersects(*monsterRect->at(im))) {
+ *monsterRect->at(m) = pix->rect(*monsterRect->at(m), *monsterRect->at(im));
+ monsterRect->at(im)->setRect(0, 0, 0, 0);
+ }
+ }
+
+ if (!pacmanRect.isNull())
+ repaint(pacmanRect, FALSE);
+
+ if (!fruitRect.isNull())
+ repaint(fruitRect, FALSE);
+
+ for (int m = 0; m < board->monsters(); m++)
+ if (!monsterRect->at(m)->isNull())
+ repaint(*monsterRect->at(m), FALSE);
+
+ for (int e = 0; e < board->energizers(); e++)
+ if (!energizerRect->at(e)->isNull())
+ repaint(*energizerRect->at(e), FALSE);
+
+}
+
+void Referee::initKeys()
+{
+ APP_CONFIG_BEGIN( cfg );
+ QString up("Up");
+ up = cfg->readEntry("upKey", (const char*) up);
+ UpKey = KAccel::stringToKey(up);
+
+ QString down("Down");
+ down = cfg->readEntry("downKey", (const char*) down);
+ DownKey = KAccel::stringToKey(down);
+
+ QString left("Left");
+ left = cfg->readEntry("leftKey", (const char*) left);
+ LeftKey = KAccel::stringToKey(left);
+
+ QString right("Right");
+ right = cfg->readEntry("rightKey", (const char*) right);
+ RightKey = KAccel::stringToKey(right);
+ APP_CONFIG_END( cfg );
+}
+
+void Referee::fillArray(QArray<int> &array, QString values, int max)
+{
+ if (max < 0)
+ max = values.contains(',')+1;
+
+ array.resize(max);
+ int last = 0;
+ bool ok;
+ QString value;
+
+ for (uint i = 0; i < array.size(); i++) {
+ if (values.find(',') < 0 && values.length() > 0) {
+ value = values;
+ values = "";
+ }
+ if (values.find(',') >= 0) {
+ value = values.left(values.find(','));
+ values.remove(0,values.find(',')+1);
+ }
+ array[i] = value.toInt(&ok);
+ if (ok)
+ last = array[i];
+ else
+ array[i] = last;
+ }
+}
+
+void Referee::fillStrList(QStrList &list, QString values, int max)
+{
+ if (!list.isEmpty())
+ list.clear();
+
+ QString last = "";
+ QString value;
+
+ for (uint i = 0; i < (uint) max; i++) {
+ if (values.find(',') < 0 && values.length() > 0) {
+ value = values;
+ values = "";
+ }
+ if (values.find(',') >= 0) {
+ value = values.left(values.find(','));
+ values.remove(0,values.find(',')+1);
+ }
+ if (!value.isEmpty())
+ last = value;
+
+ list.append(last);
+ }
+}
+
+void Referee::fillMapName()
+{
+ QStrList list = mapName;
+
+ if (!mapName.isEmpty())
+ mapName.clear();
+
+ QString map;
+
+ QFileInfo fileInfo;
+
+ for (uint i = 0; i < list.count(); i++) {
+ map = list.at(i);
+
+ if (map.left(1) != "/" && map.left(1) != "~")
+ map = FIND_APP_DATA( mapDirectory+map );
+
+ fileInfo.setFile(map);
+ if (!fileInfo.isReadable())
+ map = "";
+
+ mapName.append(map);
+ }
+}
+
+void Referee::confLevels(bool defGroup)
+{
+ APP_CONFIG_BEGIN( cfg );
+ if (defGroup || cfg->hasKey("Levels"))
+ maxLevel = cfg->readNumEntry("Levels", 13);
+ APP_CONFIG_END( cfg );
+}
+
+void Referee::confMisc(bool defGroup)
+{
+ APP_CONFIG_BEGIN( cfg );
+ if (defGroup || cfg->hasKey("PixmapDirectory")) {
+ pixmapDirectory = cfg->readEntry("PixmapDirectory");
+
+ if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~")
+ pixmapDirectory.insert(0, "pics/");
+ if (pixmapDirectory.right(1) != "/")
+ pixmapDirectory.append("/");
+ }
+
+ if (defGroup || cfg->hasKey("MapDirectory")) {
+ mapDirectory = cfg->readEntry("MapDirectory");
+
+ if (mapDirectory.left(1) != "/" && mapDirectory.left(1) != "~")
+ mapDirectory.insert(0, "maps/");
+ if (mapDirectory.right(1) != "/")
+ mapDirectory.append("/");
+ }
+
+ if (defGroup || cfg->hasKey("MapName"))
+ fillStrList(mapName, cfg->readEntry("MapName", "map"), maxLevel+1);
+
+ if (defGroup || cfg->hasKey("MonsterIQ"))
+ fillArray(monsterIQ, cfg->readEntry("MonsterIQ", "0,170,180,170,180,170,180"), maxLevel+1);
+ if (defGroup || cfg->hasKey("FruitIQ"))
+ fillArray(fruitIQ, cfg->readEntry("FruitIQ", "0,170,180,170,180,170,180"), maxLevel+1);
+ if (defGroup || cfg->hasKey("FruitIndex"))
+ fillArray(fruitIndex, cfg->readEntry("FruitIndex", "0"), maxLevel+1);
+ APP_CONFIG_END( cfg );
+}
+
+void Referee::confTiming(bool defGroup)
+{
+ APP_CONFIG_BEGIN( cfg );
+ if (defGroup || cfg->hasKey("SpeedMS"))
+ fillArray(speed, cfg->readEntry("SpeedMS", "20"), maxLevel+1);
+ if (defGroup || cfg->hasKey("PacmanTicks"))
+ fillArray(pacmanTicks,cfg->readEntry("PacmanTicks", "3"), maxLevel+1);
+ if (defGroup || cfg->hasKey("RemTicks"))
+ fillArray(remTicks, cfg->readEntry("RemTicks", "1"), maxLevel+1);
+ if (defGroup || cfg->hasKey("DangerousTicks"))
+ fillArray(dangerousTicks, cfg->readEntry("DangerousTicks", "3"), maxLevel+1);
+ if (defGroup || cfg->hasKey("HarmlessTicks"))
+ fillArray(harmlessTicks, cfg->readEntry("HarmlessTicks", "7,6,,5,,4"), maxLevel+1);
+ if (defGroup || cfg->hasKey("HarmlessDurationTicks"))
+ fillArray(harmlessDurTicks, cfg->readEntry("HarmlessDurationTicks", "375,,,300,,250,200,150"), maxLevel+1);
+ if (defGroup || cfg->hasKey("HarmlessWarningTicks"))
+ fillArray(harmlessWarnTicks, cfg->readEntry("HarmlessWarningTicks", "135"), maxLevel+1);
+ if (defGroup || cfg->hasKey("ArrestTicks"))
+ fillArray(arrestTicks, cfg->readEntry("ArrestTicks", "6"), maxLevel+1);
+ if (defGroup || cfg->hasKey("ArrestDurationTicks"))
+ fillArray(arrestDurTicks, cfg->readEntry("ArrestDurationTicks", "200,,,150"), maxLevel+1);
+ if (defGroup || cfg->hasKey("FruitTicks"))
+ fillArray(fruitTicks, cfg->readEntry("FruitTicks", "7,6,,5,,4"), maxLevel+1);
+ if (defGroup || cfg->hasKey("FruitAppearsTicks"))
+ fillArray(fruitAppearsTicks, cfg->readEntry("FruitAppearsTicks", "1000,,1500,2000,2500,3000,3500,4000"), maxLevel+1);
+ if (defGroup || cfg->hasKey("FruitDurationTicks"))
+ fillArray(fruitDurTicks, cfg->readEntry("FruitDurationTicks", "500,,,400,350,300,,250,200,150"), maxLevel+1);
+ if (defGroup || cfg->hasKey("FruitScoreDurationTicks"))
+ fillArray(fruitScoreDurTicks, cfg->readEntry("FruitScoreDurationTicks", "150"), maxLevel+1);
+
+ if (defGroup || cfg->hasKey("MonsterScoreDurationMS"))
+ monsterScoreDurMS = cfg->readNumEntry("MonsterScoreDurationMS", 1000);
+ if (defGroup || cfg->hasKey("PlayerDurationMS"))
+ playerDurMS = cfg->readNumEntry("PlayerDurationMS", 3000);
+ if (defGroup || cfg->hasKey("ReadyDurationMS"))
+ readyDurMS = cfg->readNumEntry("ReadyDurationMS", 2000);
+ if (defGroup || cfg->hasKey("GameOverDurationMS"))
+ gameOverDurMS = cfg->readNumEntry("GameOverDurationMS", 3000);
+ if (defGroup || cfg->hasKey("AfterPauseMS"))
+ afterPauseMS = cfg->readNumEntry("AfterPauseMS", 1000);
+ if (defGroup || cfg->hasKey("DyingPreAnimationMS"))
+ dyingPreAnimationMS = cfg->readNumEntry("DyingPreAnimationMS", 1000);
+ if (defGroup || cfg->hasKey("DyingAnimationMS"))
+ dyingAnimationMS = cfg->readNumEntry("DyingAnimationMS", 100);
+ if (defGroup || cfg->hasKey("DyingPostAnimationMS"))
+ dyingPostAnimationMS = cfg->readNumEntry("DyingPostAnimationMS", 500);
+ if (defGroup || cfg->hasKey("IntroAnimationMS"))
+ introAnimationMS = cfg->readNumEntry("IntroAnimationMS", 800);
+ if (defGroup || cfg->hasKey("IntroPostAnimationMS"))
+ introPostAnimationMS = cfg->readNumEntry("IntroPostAnimationMS", 1000);
+ if (defGroup || cfg->hasKey("LevelUpPreAnimationMS"))
+ levelUpPreAnimationMS = cfg->readNumEntry("LevelUpPreAnimationMS", 2000);
+ if (defGroup || cfg->hasKey("LevelUpAnimationMS"))
+ levelUpAnimationMS = cfg->readNumEntry("LevelUpAnimationMS", 2000);
+ if (defGroup || cfg->hasKey("EnergizerAnimationMS"))
+ energizerAnimationMS = cfg->readNumEntry("EnergizerAnimationMS", 200);
+ APP_CONFIG_END( cfg );
+}
+
+void Referee::confScoring(bool defGroup)
+{
+ APP_CONFIG_BEGIN( cfg );
+ if (defGroup || cfg->hasKey("PointScore"))
+ pointScore = cfg->readNumEntry("PointScore", 10);
+ if (defGroup || cfg->hasKey("EnergizerScore"))
+ energizerScore = cfg->readNumEntry("EnergizerScore", 50);
+ if (defGroup || cfg->hasKey("FruitScore"))
+ fillArray(fruitScore, cfg->readEntry("FruitScore", "100,300,500,,700,,1000,,2000,,3000,,5000"), maxLevel+1);
+ if (defGroup || cfg->hasKey("MonsterScore"))
+ fillArray(monsterScore, cfg->readEntry("MonsterScore", "200,400,800,1600"), 4);
+ if (defGroup || cfg->hasKey("ExtraLifeScore"))
+ fillArray(extraLifeScore, cfg->readEntry("ExtraLifeScore", "10000"), -1);
+ APP_CONFIG_END( cfg );
+}
+
+void Referee::confScheme()
+{
+ APP_CONFIG_BEGIN( cfg );
+ SAVE_CONFIG_GROUP( cfg, oldgroup );
+ QString newgroup;
+
+ // if not set, read mode and scheme from the configfile
+ if (mode == -1 && scheme == -1) {
+ scheme = cfg->readNumEntry("Scheme", -1);
+ mode = cfg->readNumEntry("Mode", -1);
+
+ // if mode is not set in the defGroup-group, lookup the scheme group
+ if (scheme != -1 || mode == -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ cfg->setGroup(newgroup);
+
+ mode = cfg->readNumEntry("Mode", -1);
+ RESTORE_CONFIG_GROUP( cfg, oldgroup );
+ }
+ }
+
+ confLevels();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ cfg->setGroup(newgroup);
+
+ confLevels(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ cfg->setGroup(newgroup);
+
+ confLevels(FALSE);
+ }
+
+ RESTORE_CONFIG_GROUP( cfg, oldgroup );
+
+ confMisc();
+ confTiming();
+ confScoring();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ cfg->setGroup(newgroup);
+
+ confMisc(FALSE);
+ confTiming(FALSE);
+ confScoring(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ cfg->setGroup(newgroup);
+
+ confMisc(FALSE);
+ confTiming(FALSE);
+ confScoring(FALSE);
+ }
+
+ fillMapName();
+
+ RESTORE_CONFIG_GROUP( cfg, oldgroup );
+ APP_CONFIG_END( cfg );
+}
+
+void Referee::setScheme(int Scheme, int Mode, Bitfont *font)
+{
+ mode = Mode;
+ scheme = Scheme;
+
+ confScheme();
+
+ pix->setScheme(scheme, mode, font);
+
+ pacman->setMaxPixmaps(pix->maxPixmaps(PacmanPix));
+ fruit->setMaxPixmaps(pix->maxPixmaps(FruitPix));
+
+ for (Monster *m = monsters->first(); m != 0; m = monsters->next())
+ if (m)
+ m->setMaxPixmaps(pix->maxPixmaps(MonsterPix), pix->maxPixmaps(EyesPix));
+
+ for (Energizer *e = energizers->first(); e != 0; e = energizers->next())
+ if (e)
+ e->setMaxPixmaps(pix->maxPixmaps(EnergizerPix));
+
+ if (gameState.testBit(Introducing))
+ for (int i = 0; i < (gameState.testBit(Init) ? timerCount : 15); i++)
+ introPaint(i);
+
+ setFixedSize(pix->levelPix().size());
+ repaint();
+}
+
+void Referee::keyPressEvent( QKeyEvent *k )
+{
+ uint key = k->key();
+#ifdef QWS
+ // "OK" => new game
+ if ( key == Key_F33 || key == Key_F2 || key == Key_Enter )
+ play();
+ else if ( !gameState.testBit(Playing) && key == Key_Space )
+ play();
+ // "Space" => pause
+ //else if ( key == Key_Space || key == Key_F3 )
+ // pause();
+ // "Menu" => hall of fame
+ //else if ( key == Key_F11 || key == Key_F4 )
+ // toggleHallOfFame();
+#endif
+
+ if (gameState.testBit(Paused) || gameState.testBit(HallOfFame) ||
+ gameState.testBit(Demonstration) || gameState.testBit(Dying) ||
+ gameState.testBit(Ready) || gameState.testBit(LevelDone) ||
+ !gameState.testBit(Playing))
+ return;
+
+ if (key == UpKey)
+ pacman->setDirection(N);
+ else if (key == DownKey)
+ pacman->setDirection(S);
+ else if (key == RightKey)
+ pacman->setDirection(E);
+ else if (key == LeftKey)
+ pacman->setDirection(W);
+
+#ifdef CHEATS
+ else if (key == Key_L) { printf("levelUp()\n"); levelUp(); }
+ else if (key == Key_F) { printf("fruit->move(TRUE)\n"); fruit->move(TRUE); repaint(FALSE); }
+ else if (key == Key_E) { printf("setLifes(++lifes)\n"); emit setLifes(++lifes); }
+#endif
+
+ else {
+ k->ignore();
+ return;
+ }
+ k->accept();
+}
+
+void Referee::score(int p)
+{
+ if (!gameState.testBit(Playing))
+ return;
+
+ if ((points += p) < 0)
+ points = 0;
+
+ emit setPoints(points);
+
+ if (points >= nextExtraLifeScore) {
+ emit setLifes(++lifes);
+ if (extraLifeScoreIndex < (int) extraLifeScore.size()-1)
+ extraLifeScoreIndex++;
+ if (extraLifeScore[extraLifeScoreIndex] < 0)
+ nextExtraLifeScore = extraLifeScore[extraLifeScoreIndex] * -1;
+ else
+ nextExtraLifeScore += extraLifeScore[extraLifeScoreIndex];
+ }
+}
+
+void Referee::eaten()
+{
+ if (gameState.testBit(Ready))
+ return;
+
+ stop();
+
+ if (monstersEaten < 4)
+ monstersEaten++;
+
+ gameState.setBit(Scoring);
+ score(monsterScore[monstersEaten-1]);
+
+ repaint(pix->rect(pix->rect(pacman->position(), MonsterPix),
+ pix->rect(pacman->position(), MonsterScorePix, monstersEaten-1)));
+
+ if (--timerCount > 0)
+ QTimer::singleShot( monsterScoreDurMS, this, SLOT(eaten()));
+ else {
+ for (Monster *m = monsters->first(); m != 0; m = monsters->next())
+ if (m && m->direction() == X && !gameState.testBit(Introducing))
+ m->setDirection(N);
+ if (monstersEaten != 4 || !gameState.testBit(Introducing))
+ QTimer::singleShot( monsterScoreDurMS, this, SLOT(start()));
+ }
+}
+
+void Referee::toggleHallOfFame()
+{
+ gameState.toggleBit(HallOfFame);
+}
+
+void Referee::hallOfFame()
+{
+ if (gameState.testBit(HallOfFame)) // If the HallOfFame is switched on manually, toggle the
+ toggleHallOfFame(); // bit twice.
+
+ emit setLevel(0); // Clear status display for hall of fame
+ emit setScore(level, 0);
+ emit forcedHallOfFame(TRUE);
+}
+
+void Referee::pause()
+{
+ static int pausedTimer = 0;
+
+ if (!gameState.testBit(Paused)) {
+ pausedTimer = gameTimer;
+ stop();
+ stopEnergizer();
+ gameState.setBit(Paused);
+ repaint(pix->rect((BoardWidth*BoardHeight)/2-BoardWidth, i18n("PAUSED")), FALSE);
+ } else {
+ gameState.clearBit(Paused);
+ repaint(pix->rect((BoardWidth*BoardHeight)/2-BoardWidth, i18n("PAUSED")), FALSE);
+ if (pausedTimer) {
+ pausedTimer = 0;
+ start();
+ }
+ }
+ emit togglePaused();
+}
+
+void Referee::intro()
+{
+ stop();
+ stopEnergizer();
+ bool paused = gameState.testBit(Paused);
+
+ gameState.fill(FALSE);
+ gameState.setBit(Introducing);
+ gameState.setBit(Init);
+
+ if (paused)
+ gameState.setBit(Paused);
+
+ level = 0;
+ emit setLevel(level);
+
+ board->init(Intro);
+ pix->setLevel(level);
+
+ initPacman();
+ initFruit();
+ initMonsters();
+ initEnergizers();
+
+ repaint();
+
+ monstersEaten = 0;
+ timerCount = 0;
+ introPlay();
+}
+
+void Referee::introMonster(int id)
+{
+ Monster *m = new Monster(board, id);
+
+ m->setPosition((10+id*6)*BoardWidth+10);
+ m->setDirection(E);
+ m->setDangerous(dangerousTicks[level], monsterIQ[level]);
+ m->setMaxPixmaps(pix->maxPixmaps(MonsterPix), pix->maxPixmaps(EyesPix));
+
+ if (m->body() != -1)
+ pix->draw(m->position(), RoomPix, MonsterPix, m->body());
+ if (m->eyes() != -1)
+ pix->draw(m->position(), RoomPix, EyesPix, m->eyes());
+
+ repaint(pix->rect(m->position(), MonsterPix), FALSE);
+ m->setPosition(OUT);
+}
+
+void Referee::introPaint(int t)
+{
+ QString pts;
+
+ switch (t) {
+ case 0 : repaint(pix->draw(16, 6, RoomPix, i18n("CHARACTER"), WHITE, QColor(), AlignLeft), FALSE);
+ repaint(pix->draw(36, 6, RoomPix, i18n("/"), WHITE, QColor(), AlignLeft), FALSE);
+ repaint(pix->draw(40, 6, RoomPix, i18n("NICKNAME"), WHITE, QColor(), AlignLeft), FALSE);
+ break;
+ case 1 : introMonster(0);
+ break;
+ case 2 : repaint(pix->draw(16, 10, RoomPix, i18n("-SHADOW"), RED, QColor(), AlignLeft), FALSE);
+ break;
+ case 3 : repaint(pix->draw(38, 10, RoomPix, i18n("\"BLINKY\""), RED, QColor(), AlignLeft), FALSE);
+ break;
+ case 4 : introMonster(1);
+ break;
+ case 5 : repaint(pix->draw(16, 16, RoomPix, i18n("-SPEEDY"), PINK, QColor(), AlignLeft), FALSE);
+ break;
+ case 6 : repaint(pix->draw(38, 16, RoomPix, i18n("\"PINKY\""), PINK, QColor(), AlignLeft), FALSE);
+ break;
+ case 7 : introMonster(2);
+ break;
+ case 8 : repaint(pix->draw(16, 22, RoomPix, i18n("-BASHFUL"), CYAN, QColor(), AlignLeft), FALSE);
+ break;
+ case 9 : repaint(pix->draw(38, 22, RoomPix, i18n("\"INKY\""), CYAN, QColor(), AlignLeft), FALSE);
+ break;
+ case 10 : introMonster(3);
+ break;
+ case 11 : repaint(pix->draw(16, 28, RoomPix, i18n("-POKEY"), ORANGE, QColor(), AlignLeft), FALSE);
+ break;
+ case 12 : repaint(pix->draw(38, 28, RoomPix, i18n("\"CLYDE\""), ORANGE, QColor(), AlignLeft), FALSE);
+ break;
+ case 13 : pts.sprintf("%d", pointScore);
+ repaint(pix->draw(28, 44, RoomPix, pts.data(), WHITE, QColor(), AlignRight), FALSE);
+ repaint(pix->draw(31, 44, RoomPix, "\x1C\x1D\x1E", WHITE, QColor(), AlignLeft), FALSE);
+ pts.sprintf("%d", energizerScore);
+ repaint(pix->draw(28, 48, RoomPix, pts.data(), WHITE, QColor(), AlignRight), FALSE);
+ repaint(pix->draw(31, 48, RoomPix, "\x1C\x1D\x1E", WHITE, QColor(), AlignLeft), FALSE);
+ break;
+ case 14 : // "@ 1980 MIDWAY MFG.CO."
+#if defined( KDE2_PORT )
+ repaint(pix->draw(30, 58, RoomPix, "© 1998-2002 J.THÖNNISSEN", PINK), FALSE);
+#elif defined( QPE_PORT )
+ repaint(pix->draw(30, 55, RoomPix, "© 1998-2002 J.THÖNNISSEN", PINK), FALSE);
+ repaint(pix->draw(29, 60, RoomPix, "Qtopia port: Catalin CLIMOV", GREEN), FALSE);
+#endif
+ break;
+ }
+}
+
+void Referee::introPlay()
+{
+ if (!gameState.testBit(Introducing) || gameState.testBit(Ready))
+ return;
+ if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
+ QTimer::singleShot(afterPauseMS, this, SLOT(introPlay()));
+ return;
+ }
+
+ if (!gameState.testBit(Init)) {
+ if (monstersEaten == 4) {
+ stop();
+ QTimer::singleShot(introPostAnimationMS, this, SLOT(demo()));
+ }
+ if (pacman->direction() == W) {
+ int id = -1;
+ if (pacman->position() == 37*BoardWidth-6)
+ id = 0;
+ else
+ if (board->isMonster(37*BoardWidth-6))
+ for (Monster *m = monsters->first(); m != 0; m = monsters->next())
+ if (m && m->position() == 37*BoardWidth-6) {
+ id = m->id();
+ id++;
+ break;
+ }
+
+ if (id >= 0 && id <= 4)
+ for (Monster *m = monsters->first(); m != 0; m = monsters->next())
+ if (m && m->id() == id && m->position() == OUT) {
+ m->setPosition(37*BoardWidth-1);
+ m->setDirection(W);
+ m->setDangerous(dangerousTicks[level], monsterIQ[level]);
+ board->set(37*BoardWidth-1, monsterhome, id);
+ repaint(pix->rect(m->position(), MonsterPix));
+ break;
+ }
+ }
+ return;
+ }
+
+ if (timerCount < 15)
+ introPaint(timerCount);
+
+ switch (timerCount) {
+ case 13 : board->set(44*BoardWidth+22, Point);
+ pix->drawPoint(44*BoardWidth+22);
+ repaint(pix->rect(44*BoardWidth+22, PointPix), FALSE);
+ energizers->at(0)->setPosition(48*BoardWidth+22);
+ energizers->at(0)->setOn();
+ repaint(pix->rect(48*BoardWidth+22, EnergizerPix), FALSE);
+ break;
+ case 14 : energizers->at(1)->setPosition(36*BoardWidth+10);
+ energizers->at(1)->setOn();
+ repaint(pix->rect(36*BoardWidth+10, EnergizerPix), FALSE);
+ for (int pos = 8; pos < BoardWidth; pos++) {
+ board->set(34*BoardWidth+pos, out);
+ board->set(38*BoardWidth+pos, out);
+ }
+ board->set(36*BoardWidth+8, out);
+ break;
+ case 15 : gameState.clearBit(Init);
+ initPacman();
+ pacman->setDemo(TRUE);
+ pacman->setPosition(37*BoardWidth-1);
+ repaintFigures();
+ start();
+ return;
+ }
+
+ if (timerCount++ < 15)
+ QTimer::singleShot(introAnimationMS, this, SLOT(introPlay()));
+}
+
+void Referee::demo()
+{
+ if (gameState.testBit(Ready))
+ return;
+
+ if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
+ QTimer::singleShot(afterPauseMS, this, SLOT(demo()));
+ return;
+ }
+
+ stop();
+ stopEnergizer();
+
+ gameState.fill(FALSE);
+ gameState.setBit(Init);
+ gameState.setBit(Demonstration);
+
+ level = 0;
+ emit setLevel(level);
+
+ board->init(Demo, mapName.at(0));
+ pix->setLevel(level);
+
+ initPacman();
+ initFruit();
+ initMonsters();
+ initEnergizers();
+
+ gameState.clearBit(Init);
+
+ repaint();
+
+ timerCount = 0;
+ QTimer::singleShot(playerDurMS, this, SLOT(start()));
+}
+
+void Referee::play()
+{
+ stop();
+ stopEnergizer();
+
+ gameState.fill(FALSE);
+ gameState.setBit(Init);
+ gameState.setBit(Playing);
+ gameState.setBit(Player);
+ gameState.setBit(Ready);
+
+ lifes = 3;
+ level = 1;
+ points = 0;
+
+ extraLifeScoreIndex = 0;
+ nextExtraLifeScore = extraLifeScore[extraLifeScoreIndex];
+ if (nextExtraLifeScore < 0)
+ nextExtraLifeScore *= -1;
+
+ board->init(Level, mapName.at(level));
+ pix->setLevel(level);
+
+ initPacman();
+ initFruit();
+ initMonsters();
+ initEnergizers();
+
+ repaint();
+ emit toggleNew();
+ emit setLifes(lifes);
+ emit setLevel(level);
+ emit setPoints(points);
+
+ repaint(pix->rect(board->position(monsterhome, 0), i18n("PLAYER ONE")), FALSE);
+ repaint(pix->rect(board->position(fruithome), i18n("READY!")), FALSE);
+
+ timerCount = 0;
+ QTimer::singleShot(playerDurMS, this, SLOT(ready()));
+}
+
+void Referee::ready()
+{
+ if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
+ QTimer::singleShot(afterPauseMS, this, SLOT(ready()));
+ return;
+ }
+
+ if (gameState.testBit(Player)) {
+ emit setLifes(--lifes);
+ gameState.clearBit(Player);
+ gameState.clearBit(Init);
+ repaint(pix->rect(board->position(monsterhome, 0), i18n("PLAYER ONE")), FALSE);
+ repaintFigures();
+ QTimer::singleShot(playerDurMS, this, SLOT(ready()));
+ return;
+ }
+
+ if (gameState.testBit(Ready)) {
+ gameState.clearBit(Ready);
+ repaint(pix->rect(board->position(fruithome), i18n("READY!")), FALSE);
+ start();
+ } else {
+ gameState.setBit(Ready);
+ gameState.clearBit(Init);
+ repaint(pix->rect(board->position(fruithome), i18n("READY!")), FALSE);
+ QTimer::singleShot(readyDurMS, this, SLOT(ready()));
+ }
+}
+
+
+void Referee::levelUp()
+{
+ stop();
+ stopEnergizer();
+
+ gameState.setBit(LevelDone);
+ pacman->setPosition(pacman->position()); // set mouthPosition to "0"
+ repaint(pix->rect(pacman->position(), PacmanPix));
+
+ timerCount = 0;
+ QTimer::singleShot(levelUpPreAnimationMS, this, SLOT(levelUpPlay()));
+}
+
+void Referee::levelUpPlay()
+{
+ if (gameState.testBit(Ready))
+ return;
+
+ if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
+ QTimer::singleShot(afterPauseMS, this, SLOT(levelUpPlay()));
+ return;
+ }
+
+ switch (timerCount) {
+ case 0 : gameState.setBit(Init);
+ setOnEnergizers();
+ repaintFigures();
+ break;
+ case 1 : gameState.clearBit(LevelDone);
+ repaint(pix->rect(pacman->position(), PacmanPix));
+ break;
+ }
+
+ if (timerCount++ < 2) {
+ QTimer::singleShot(levelUpAnimationMS, this, SLOT(levelUpPlay()));
+ return;
+ }
+
+ gameState.clearBit(Init);
+
+ if (gameState.testBit(Demonstration)) {
+ hallOfFame();
+ return;
+ }
+
+ if (level < maxLevel)
+ level++;
+
+ board->init(Level, mapName.at(level));
+ pix->setLevel(level);
+
+ initPacman();
+ initFruit();
+ initMonsters();
+ initEnergizers();
+
+ repaint();
+ emit setLevel(level);
+
+ ready();
+}
+
+void Referee::start()
+{
+ if (gameState.testBit(Ready))
+ return;
+
+ if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
+ QTimer::singleShot(afterPauseMS, this, SLOT(start()));
+ return;
+ }
+
+ if (gameState.testBit(Scoring)) {
+ gameState.clearBit(Scoring);
+ repaint(pix->rect(pix->rect(pacman->position(), MonsterPix),
+ pix->rect(pacman->position(), MonsterScorePix, monstersEaten-1)));
+ }
+
+ if (!gameTimer)
+ gameTimer = startTimer( speed [level] );
+
+ if (!energizerTimer)
+ energizerTimer = startTimer( energizerAnimationMS );
+}
+
+void Referee::start(int t)
+{
+ gameTimer = startTimer(t);
+}
+
+void Referee::stop()
+{
+ if (gameTimer) {
+ killTimer (gameTimer);
+ gameTimer = 0;
+ }
+}
+
+void Referee::stopEnergizer()
+{
+ if (energizerTimer) {
+ killTimer (energizerTimer);
+ energizerTimer = 0;
+ }
+}
+
+void Referee::killed()
+{
+ if (gameState.testBit(Ready))
+ return;
+
+ if (!gameState.testBit(Dying)) {
+ gameState.setBit(Dying);
+
+ pacman->setDirection(X, TRUE);
+ for (Monster *m = monsters->first(); m != 0; m = monsters->next())
+ if (m)
+ m->setDirection(X);
+ QTimer::singleShot(dyingPreAnimationMS, this, SLOT(killed()));
+ } else {
+ stop();
+ if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
+ QTimer::singleShot(afterPauseMS, this, SLOT(killed()));
+ return;
+ }
+
+ gameState.setBit(Init);
+
+ repaintFigures();
+
+ timerCount = 0;
+ killedPlay();
+ }
+}
+
+void Referee::killedPlay()
+{
+ if (!gameState.testBit(Dying) || gameState.testBit(Ready))
+ return;
+ if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
+ QTimer::singleShot(afterPauseMS, this, SLOT(killedPlay()));
+ return;
+ }
+
+ if (timerCount <= pix->maxPixmaps(DyingPix)) {
+ repaint(pix->rect(pacman->position(), PacmanPix), FALSE);
+ if (timerCount >= pix->maxPixmaps(DyingPix)-1 || timerCount == 0)
+ QTimer::singleShot(dyingPostAnimationMS, this, SLOT(killedPlay()));
+ else
+ QTimer::singleShot(dyingAnimationMS, this, SLOT(killedPlay()));
+ timerCount++;
+ } else {
+ gameState.clearBit(Dying);
+ stopEnergizer();
+ if (lifes == 0) {
+ gameState.setBit(GameOver);
+ gameState.clearBit(Playing);
+ for (int e = 0; e < board->energizers(); e++) {
+ energizers->at(e)->setOff();
+ repaint(pix->rect(board->position(energizer, e), EnergizerPix), FALSE);
+ }
+ repaint(pix->rect(board->position(fruithome), i18n("GAME OVER")), FALSE);
+ QTimer::singleShot(gameOverDurMS, this, SLOT(hallOfFame()));
+ } else {
+ gameState.clearBit(Init);
+ initPacman();
+ initFruit();
+ initMonsters();
+ initEnergizers();
+ emit setLifes(--lifes);
+ repaintFigures();
+ ready();
+ }
+ }
+}
+
+void Referee::initPacman()
+{
+ pacman->setMaxPixmaps(pix->maxPixmaps(PacmanPix));
+ pacman->setDemo(gameState.testBit(Demonstration));
+ pacman->setPosition(board->position(pacmanhome));
+ pacman->setDirection(W, TRUE);
+ pacman->setAlive(pacmanTicks[level]);
+}
+
+void Referee::initFruit(bool fullInitialization)
+{
+ if (fullInitialization) {
+ fruit->setMaxPixmaps(pix->maxPixmaps(FruitPix));
+ if (fruitIndex[level] == 0)
+ fruit->setLevel(level, fruitAppearsTicks[level],
+ fruitDurTicks[level], fruitTicks[level]);
+ else if (fruitIndex[level] < 0)
+ fruit->setLevel(pix->maxPixmaps(FruitPix)+1,
+ fruitAppearsTicks[level],
+ fruitDurTicks[level], fruitTicks[level]);
+ else
+ fruit->setLevel(fruitIndex[level], fruitAppearsTicks[level],
+ fruitDurTicks[level], fruitTicks[level]);
+ }
+
+ if (board->tunnels() > 0)
+ fruit->setMovement(board->position(tunnel, rand() % board->tunnels()),
+ board->position(tunnel, rand() % board->tunnels()),
+ fruitIQ[level]);
+}
+
+void Referee::initMonsters()
+{
+ if( !monsters->isEmpty())
+ monsters->clear();
+ if( !monsterRect->isEmpty())
+ monsterRect->clear();
+
+ for (int id = 0; id < (gameState.testBit(Introducing) ? 4 : board->monsters()); id++) {
+ Monster *m = new Monster(board, id);
+ monsters->append(m);
+ QRect *r = new QRect();
+ monsterRect->append(r);
+ if (!gameState.testBit(Introducing)) {
+ m->setFreedom(board->position(prisonexit));
+ m->setDangerous(dangerousTicks[level], monsterIQ[level]);
+ if (id == 0)
+ m->setPrison(board->position(prisonentry));
+ else {
+ m->setPrison(board->position(monsterhome, id));
+ m->setArrested(arrestTicks[level], arrestDurTicks[level]*id);
+ }
+ m->setPosition(board->position(monsterhome, id));
+ switch(id) {
+ case 0 : m->setDirection(W); break;
+ case 1 : m->setDirection(N); break;
+ default : m->setDirection(S);
+ }
+ }
+ m->setMaxPixmaps(pix->maxPixmaps(MonsterPix), pix->maxPixmaps(EyesPix));
+ }
+}
+
+void Referee::initEnergizers()
+{
+ if( !energizers->isEmpty())
+ energizers->clear();
+ if( !energizerRect->isEmpty())
+ energizerRect->clear();
+
+ for (int id = 0; id < (gameState.testBit(Introducing) ? 2 : board->energizers()); id++) {
+ Energizer *e = new Energizer(board);
+ energizers->append(e);
+ QRect *r = new QRect();
+ energizerRect->append(r);
+ if (!gameState.testBit(Introducing)) {
+ e->setPosition(board->position(energizer, id));
+ e->setOn();
+ }
+ e->setMaxPixmaps(pix->maxPixmaps(EnergizerPix));
+ }
+}
+
+void Referee::setOnEnergizers()
+{
+ for (int e = 0; e < board->energizers(); e++) {
+ energizers->at(e)->setOn();
+ }
+}
+
+void Referee::setFocusOutPause(bool FocusOutPause)
+{
+ focusOutPause = FocusOutPause;
+}
+
+void Referee::setFocusInContinue(bool FocusInContinue)
+{
+ focusInContinue = FocusInContinue;
+}
+
+void Referee::focusInEvent(QFocusEvent *)
+{
+ if (focusInContinue && focusedPause &&
+ gameState.testBit(Paused) && gameState.testBit(Playing)) {
+ pause();
+ }
+}
+
+void Referee::focusOutEvent(QFocusEvent *)
+{
+ if (focusOutPause && !gameState.testBit(Paused) && gameState.testBit(Playing)) {
+ focusedPause = TRUE;
+ pause();
+ }
+}
diff --git a/noncore/games/kpacman/referee.h b/noncore/games/kpacman/referee.h
new file mode 100644
index 0000000..f812de4
--- a/dev/null
+++ b/noncore/games/kpacman/referee.h
@@ -0,0 +1,196 @@
+#ifndef REFEREE_H
+#define REFEREE_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <kapp.h>
+#endif
+
+#include <qwidget.h>
+#include <qlist.h>
+#include <qstrlist.h>
+#include <qarray.h>
+#include <qbitarry.h>
+
+#include "board.h"
+#include "pacman.h"
+#include "monster.h"
+#include "fruit.h"
+#include "energizer.h"
+#include "bitfont.h"
+#include "painter.h"
+
+enum { Init, Introducing, Playing, Demonstration, Paused, Player, Ready,
+ Scoring, LevelDone, Dying, GameOver, HallOfFame };
+
+
+class Referee : public QWidget
+{
+ Q_OBJECT
+public:
+ Referee (QWidget *parent=0, const char *name=0, int scheme=-1, int mode=-1, Bitfont *font=0);
+
+ void setSkill(int);
+ void setRoom(int);
+
+public slots:
+ void setScheme(int scheme, int mode, Bitfont *font=0);
+
+ void levelUp();
+ void levelUpPlay();
+
+ void pause();
+ void ready();
+ void intro();
+ void introPlay();
+ void hallOfFame();
+ void demo();
+ void play();
+ void killed();
+ void killedPlay();
+ void eaten();
+ void toggleHallOfFame();
+
+ void setFocusOutPause(bool focusOutPause);
+ void setFocusInContinue(bool focusInContinue);
+ void initKeys();
+
+ void repaintFigures();
+
+private slots:
+ void start();
+ void stop();
+ void stopEnergizer();
+
+signals:
+ void setScore(int, int);
+ void setPoints(int);
+ void setLevel(int);
+ void setLifes(int);
+
+ void toggleNew();
+ void togglePaused();
+ void forcedHallOfFame(bool);
+
+protected:
+ void timerEvent(QTimerEvent *);
+ void paintEvent(QPaintEvent *);
+ void keyPressEvent(QKeyEvent *);
+
+ void focusOutEvent(QFocusEvent *);
+ void focusInEvent(QFocusEvent *);
+
+ void fillArray(QArray<int> &, QString, int);
+ void fillStrList(QStrList &, QString, int);
+ void fillMapName();
+
+ void confScheme();
+ void confLevels(bool defGroup=TRUE);
+ void confMisc(bool defGroup=TRUE);
+ void confTiming(bool defGroup=TRUE);
+ void confScoring(bool defGroup=TRUE);
+
+private:
+ QBitArray gameState;
+ int timerCount;
+ int maxLevel;
+
+ int scheme;
+ int mode;
+
+ QString pixmapDirectory;
+ QString mapDirectory;
+ QStrList mapName;
+
+ QArray<int> speed;
+ QArray<int> monsterIQ;
+ QArray<int> fruitIQ;
+ QArray<int> fruitIndex;
+ QArray<int> pacmanTicks;
+ QArray<int> remTicks;
+ QArray<int> dangerousTicks;
+ QArray<int> harmlessTicks;
+ QArray<int> harmlessDurTicks;
+ QArray<int> harmlessWarnTicks;
+ QArray<int> arrestTicks;
+ QArray<int> arrestDurTicks;
+ QArray<int> fruitTicks;
+ QArray<int> fruitAppearsTicks;
+ QArray<int> fruitDurTicks;
+ QArray<int> fruitScoreDurTicks;
+
+ int monsterScoreDurMS;
+ int playerDurMS;
+ int readyDurMS;
+ int gameOverDurMS;
+ int afterPauseMS;
+ int dyingPreAnimationMS;
+ int dyingAnimationMS;
+ int dyingPostAnimationMS;
+ int introAnimationMS;
+ int introPostAnimationMS;
+ int levelUpPreAnimationMS;
+ int levelUpAnimationMS;
+ int energizerAnimationMS;
+
+ int pointScore;
+ int energizerScore;
+ QArray<int> fruitScore;
+ QArray<int> monsterScore;
+ QArray<int> extraLifeScore;
+
+ int extraLifeScoreIndex;
+ int nextExtraLifeScore;
+
+ int monstersEaten;
+ int points;
+ int lifes;
+ int level;
+
+ bool focusedPause;
+ bool focusOutPause;
+ bool focusInContinue;
+
+ Board *board;
+ Painter *pix;
+ Pacman *pacman;
+ Fruit *fruit;
+
+ QList<Monster> *monsters;
+ QList<QRect> *monsterRect;
+
+ QList<Energizer> *energizers;
+ QList<QRect> *energizerRect;
+
+ QRect pacmanRect;
+ QRect fruitRect;
+
+ void introMonster(int id);
+ void introPaint(int t);
+
+ void initMonsters();
+ void initPacman();
+ void initFruit(bool fullInitialization=TRUE);
+ void initEnergizers();
+
+ void setOnEnergizers();
+
+ int gameTimer;
+ int energizerTimer;
+ void start(int);
+ void init(bool);
+
+ void score(int);
+
+ uint UpKey;
+ uint DownKey;
+ uint RightKey;
+ uint LeftKey;
+};
+
+#endif // REFEREE_H
diff --git a/noncore/games/kpacman/score.cpp b/noncore/games/kpacman/score.cpp
new file mode 100644
index 0000000..6e660e8
--- a/dev/null
+++ b/noncore/games/kpacman/score.cpp
@@ -0,0 +1,642 @@
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <score.h>
+#include <score.moc>
+
+#include <kaccel.h>
+#include <kapp.h>
+#include <kconfig.h>
+#include <kstddirs.h>
+#include <kmessagebox.h>
+#elif defined( QPE_PORT )
+#include <qaccel.h>
+#include "config.h"
+#include "score.h"
+#endif
+
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <qpixmap.h>
+#include <qstring.h>
+#include <qdstream.h>
+#include <qkeycode.h>
+#include <qtimer.h>
+#include <qfileinfo.h>
+
+#include "bitfont.h"
+
+Score::Score(QWidget *parent, const char *name, int Scheme, int Mode, Bitfont *font) : QWidget(parent, name)
+{
+ setFocusPolicy(QWidget::StrongFocus);
+
+ paused = FALSE;
+
+ lastScore = -1;
+ lastPlayer = -1;
+
+ cursorBlinkTimer = 0;
+ cursorBlinkMS = -1;
+ cursor.x = -1;
+ cursor.y = -1;
+ cursor.on = FALSE;
+ cursor.chr = QChar('?');
+
+ initKeys();
+
+ scheme = Scheme;
+ mode = Mode;
+ confScheme();
+
+ bitfont = font;
+
+ highscoreFile.setName(locateHighscoreFilePath().filePath());
+ read();
+
+ for (int p = 0; p < maxPlayer; p++) {
+ playerScore[p] = 0;
+ playerName[p] = getenv("LOGNAME");
+ if (playerName[p].length() < minPlayerNameLength)
+ playerName[p].setExpand(minPlayerNameLength-1, ' ');
+
+ for (uint i = 0; i < playerName[p].length(); i++)
+ if (playerName[p].at(i) < bitfont->firstChar() ||
+ playerName[p].at(i) > bitfont->lastChar())
+ playerName[p].at(i) = playerName[p].at(i).upper();
+ }
+}
+
+Score::~Score()
+{
+ // write();
+}
+
+void Score::paintEvent( QPaintEvent *e)
+{
+ if (rect(1, 0, i18n(" 1UP ")).intersects(e->rect())) {
+ QPixmap pix;
+ QColor fg = BLACK;
+ if (cursor.on || paused || lastPlayer != 0)
+ fg = WHITE;
+ pix = bitfont->text(i18n(" 1UP "), fg, BLACK);
+ bitBlt(this, x(1), y(0), &pix);
+ }
+
+ if (rect(8, 0, i18n(" HIGH SCORE ")).intersects(e->rect())) {
+ QPixmap pix = bitfont->text(i18n(" HIGH SCORE "), WHITE, BLACK);
+ bitBlt(this, x(8), y(0), &pix);
+ }
+
+ if (maxPlayer > 1 && rect(21, 0, i18n(" 2UP ")).intersects(e->rect())) {
+ QPixmap pix;
+ QColor fg = BLACK;
+ if (cursor.on || paused || lastPlayer != 1)
+ fg = WHITE;
+ pix = bitfont->text(i18n(" 2UP "), fg, BLACK);
+ bitBlt(this, x(21), y(0), &pix);
+ }
+
+ QString s;
+
+ s.sprintf("%6d0", playerScore[0]/10);
+ if (rect(0, 1, s).intersects(e->rect())) {
+ QPixmap pix = bitfont->text(s, WHITE, BLACK);
+ bitBlt(this, x(0), y(1), &pix);
+ }
+
+ s.sprintf("%8d0", HighScore/10);
+ if (rect(8, 1, s).intersects(e->rect())) {
+ QPixmap pix = bitfont->text(s, WHITE, BLACK);
+ bitBlt(this, x(8), y(1), &pix);
+ }
+
+ if (lastScore >= 0) {
+ if (rect(1, 4*1.25, i18n(" CONGRATULATIONS ")).intersects(e->rect())) {
+ QPixmap pix = bitfont->text(i18n(" CONGRATULATIONS "), YELLOW, BLACK);
+ bitBlt(this, x(1), y(4*1.25), &pix);
+ }
+ if (rect(1, 6*1.25, i18n(" YOU HAVE ARCHIEVED ")).intersects(e->rect())) {
+ QPixmap pix = bitfont->text(i18n(" YOU HAVE ARCHIEVED "), CYAN, BLACK);
+ bitBlt(this, x(1), y(6*1.25), &pix);
+ }
+ if (rect(1, 7*1.25, i18n(" A SCORE IN THE TOP 10. ")).intersects(e->rect())) {
+ QPixmap pix = bitfont->text(i18n(" A SCORE IN THE TOP 10. "), CYAN, BLACK);
+ bitBlt(this, x(1), y(7*1.25), &pix);
+ }
+ if (rect(1, 8*1.25, i18n(" ")).intersects(e->rect())) {
+ QPixmap pix = bitfont->text(i18n(" "), CYAN, BLACK);
+ bitBlt(this, x(1), y(8*1.25), &pix);
+ }
+ }
+
+ if (rect(1, 9.5*1.25, i18n("RNK SCORE NAME DATE")).intersects(e->rect())) {
+ QPixmap pix = bitfont->text(i18n("RNK SCORE NAME DATE"), WHITE, BLACK);
+ bitBlt(this, x(1), y(9.5*1.25), &pix);
+ }
+
+ for (int i = 0; i < 10; i++) {
+ s.sprintf("%2d%9d %-3.3s %-8.8s",
+ i+1, hallOfFame[i].points, hallOfFame[i].name.utf8().data(),
+ formatDate(hallOfFame[i].moment.date()).data());
+ if (rect(1, (11+i)*1.25, s).intersects(e->rect())) {
+ QPixmap pix = bitfont->text(s, (i == lastScore) ? YELLOW : WHITE, BLACK);
+ bitBlt(this, x(1), y((11+i)*1.25), &pix);
+ }
+ }
+
+ if (cursor.x != -1 && cursor.y != -1 && cursor.on) {
+ if (rect(cursor.x, (cursor.y*1.25), cursor.chr).intersects(e->rect())) {
+ QPixmap pix = bitfont->text(cursor.chr, BLACK, YELLOW);
+ bitBlt(this, x(cursor.x), y(cursor.y*1.25), &pix);
+ }
+ }
+
+ if (paused) {
+
+ QPixmap pix = bitfont->text(i18n("PAUSED"), RED, BLACK);
+ QRect r = bitfont->rect(i18n("PAUSED"));
+ r.moveCenter(QPoint(this->width()/2, this->height()/2));
+
+ bitBlt(this, r.x(), r.y(), &pix);
+ }
+}
+
+void Score::timerEvent(QTimerEvent*)
+{
+ cursor.on = !cursor.on;
+
+ if (paused)
+ return;
+
+ if (cursor.x != -1 && cursor.y != -1)
+ repaint(rect(cursor.x, cursor.y*1.25, cursor.chr), FALSE);
+ scrollRepeat = FALSE;
+
+ if (lastPlayer == 0)
+ repaint(rect(1, 0, i18n(" 1UP ")), FALSE);
+
+ if (lastPlayer == 1)
+ repaint(rect(21, 0, i18n(" 2UP ")), FALSE);
+}
+
+void Score::keyPressEvent(QKeyEvent *k)
+{
+ if (lastScore < 0 || lastPlayer < 0 || lastPlayer >= maxPlayer || paused) {
+ k->ignore();
+ return;
+ }
+
+ int x = cursor.x;
+ int y = cursor.y;
+
+ uint key = k->key();
+
+ if (scrollRepeat && (key == UpKey || key == Key_Up || key == DownKey || key == Key_Down)) {
+ k->ignore();
+ return;
+ }
+
+ if (key != Key_Return) {
+ if (key == RightKey || key == Key_Right)
+ if (++cursor.x > 16)
+ cursor.x = 14;
+ if (key == LeftKey || key == Key_Left)
+ if (--cursor.x < 14)
+ cursor.x = 16;
+ if (key == UpKey || key == Key_Up)
+ if (cursor.chr.unicode() < bitfont->lastChar())
+ cursor.chr = cursor.chr.unicode()+1;
+ else
+ cursor.chr = bitfont->firstChar();
+ if (key == DownKey || key == Key_Down)
+ if (cursor.chr.unicode() > bitfont->firstChar())
+ cursor.chr = cursor.chr.unicode()-1;
+ else
+ cursor.chr = bitfont->lastChar();
+
+ if (cursor.x == x && cursor.y == y &&
+ cursor.chr == hallOfFame[lastScore].name.at(cursor.x-14)) {
+ uint ascii = k->ascii();
+
+ if (ascii < bitfont->firstChar() || ascii > bitfont->lastChar())
+ ascii = toupper(ascii);
+
+ if (ascii >= bitfont->firstChar() && ascii <= bitfont->lastChar()) {
+ cursor.chr = ascii;
+ hallOfFame[lastScore].name.at(cursor.x-14) = cursor.chr;
+ if (++cursor.x > 16)
+ cursor.x = 14;
+ }
+ }
+ }
+
+ if (key == Key_Return) {
+ playerName[lastPlayer] = hallOfFame[lastScore].name;
+ write();
+ read();
+ lastScore = -1;
+ cursor.x = -1;
+ cursor.y = -1;
+// killTimers();
+ emit toggleNew();
+ end();
+ }
+
+ if (x != cursor.x || y != cursor.y) {
+ if (cursor.x != -1)
+ cursor.chr = hallOfFame[lastScore].name.at(cursor.x-14);
+ scrollRepeat = FALSE;
+ repaint(rect(x, y*1.25, cursor.chr), FALSE);
+ } else
+ hallOfFame[lastScore].name.at(cursor.x-14) = cursor.chr;
+
+ if (key == UpKey || key == Key_Up || key == DownKey || key == Key_Down)
+ scrollRepeat = TRUE;
+ else
+ repaint(rect(cursor.x, cursor.y*1.25, cursor.chr), FALSE);
+}
+
+void Score::initKeys()
+{
+ APP_CONFIG_BEGIN( cfg );
+ QString up("Up");
+ up = cfg->readEntry("upKey", (const char*) up);
+ UpKey = KAccel::stringToKey(up);
+
+ QString down("Down");
+ down = cfg->readEntry("downKey", (const char*) down);
+ DownKey = KAccel::stringToKey(down);
+
+ QString left("Left");
+ left = cfg->readEntry("leftKey", (const char*) left);
+ LeftKey = KAccel::stringToKey(left);
+
+ QString right("Right");
+ right = cfg->readEntry("rightKey", (const char*) right);
+ RightKey = KAccel::stringToKey(right);
+ APP_CONFIG_END( cfg );
+}
+
+void Score::confTiming(bool defGroup)
+{
+ APP_CONFIG_BEGIN( cfg );
+ if (defGroup || cfg->hasKey("CursorBlinkMS"))
+ cursorBlinkMS = cfg->readNumEntry("CursorBlinkMS", 250);
+ if (defGroup || cfg->hasKey("HallOfFameMS"))
+ hallOfFameMS = cfg->readNumEntry("HallOfFameMS", 7000);
+ if (defGroup || cfg->hasKey("AfterPauseMS"))
+ afterPauseMS = cfg->readNumEntry("AfterPauseMS", 1000);
+ APP_CONFIG_END( cfg );
+}
+
+void Score::confScheme()
+{
+ APP_CONFIG_BEGIN( cfg );
+ SAVE_CONFIG_GROUP( cfg, oldgroup );
+ QString newgroup;
+
+ // if not set, read mode and scheme from the configfile
+ if (mode == -1 && scheme == -1) {
+ scheme = cfg->readNumEntry("Scheme", -1);
+ mode = cfg->readNumEntry("Mode", -1);
+
+ // if mode is not set in the defGroup-group, lookup the scheme group
+ if (scheme != -1 || mode == -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ cfg->setGroup(newgroup);
+
+ mode = cfg->readNumEntry("Mode", -1);
+ RESTORE_CONFIG_GROUP( cfg, oldgroup );
+ }
+ }
+
+ int oldCursorBlinkMS = cursorBlinkMS;
+
+ confTiming();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ cfg->setGroup(newgroup);
+
+ confTiming(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ cfg->setGroup(newgroup);
+
+ confTiming(FALSE);
+ }
+
+ if (cursorBlinkMS != oldCursorBlinkMS) {
+ if (cursorBlinkTimer)
+ killTimer(cursorBlinkTimer);
+ cursorBlinkTimer = startTimer(cursorBlinkMS);
+ }
+
+ RESTORE_CONFIG_GROUP( cfg, oldgroup );
+ APP_CONFIG_END( cfg );
+}
+
+void Score::setScheme(int Scheme, int Mode, Bitfont *font)
+{
+ mode = Mode;
+ scheme = Scheme;
+
+ confScheme();
+
+ bitfont = font;
+
+ for (int p = 0; p < maxPlayer; p++)
+ for (uint i = 0; i < playerName[p].length(); i++)
+ if (playerName[p].at(i) < bitfont->firstChar() ||
+ playerName[p].at(i) > bitfont->lastChar())
+ playerName[p].at(i) = playerName[p].at(i).upper();
+
+ for (int i = 0; i < 10; i++)
+ for (uint j = 0; j < hallOfFame[i].name.length(); j++)
+ if (hallOfFame[i].name.at(j) < bitfont->firstChar() ||
+ hallOfFame[i].name.at(j) > bitfont->lastChar())
+ hallOfFame[i].name.at(j) = hallOfFame[i].name.at(j).upper();
+
+ if (cursor.chr.unicode() < bitfont->firstChar() ||
+ cursor.chr.unicode() > bitfont->lastChar())
+ cursor.chr = cursor.chr.upper();
+}
+
+void Score::set(int score)
+{
+ set(score, 0);
+}
+
+void Score::set(int score, int player)
+{
+ if (player < 0 || player >= maxPlayer)
+ return;
+
+ lastPlayer = player;
+ playerScore[lastPlayer] = score;
+
+ QString s;
+
+ s.sprintf("%6d0", playerScore[lastPlayer]/10);
+ repaint(rect(0, 1, s), FALSE);
+
+ if (score > HighScore) {
+ HighScore = score;
+ s.sprintf("%8d0", HighScore/10);
+ repaint(rect(8, 1, s), FALSE);
+ }
+}
+
+/*
+ * Set the score for player after the game if over. If the score is in the
+ * high scores then the hall of fame is updated (shifted) and the scoreboard
+ * is shown.
+ */
+
+void Score::setScore(int level, int player)
+{
+ lastScore = -1;
+
+ if (player < 0 || player >= maxPlayer || level == 0) {
+ if (level != 0)
+ emit toggleNew();
+ QTimer::singleShot(hallOfFameMS, this, SLOT(end()));
+ return;
+ }
+
+ lastPlayer = player;
+
+ for (int i = 0; i < 10; i++)
+ if ( playerScore[lastPlayer] > hallOfFame[i].points) {
+ lastScore = i;
+ break;
+ }
+
+ if (lastScore < 0) {
+ emit toggleNew();
+ QTimer::singleShot(hallOfFameMS, this, SLOT(end()));
+ return;
+ }
+
+ for (int i = 9; i > lastScore && i > 0; i--)
+ hallOfFame[i] = hallOfFame[i-1];
+
+ hallOfFame[lastScore].points = playerScore[lastPlayer];
+ hallOfFame[lastScore].levels = level;
+ hallOfFame[lastScore].moment = QDateTime::currentDateTime();
+ hallOfFame[lastScore].name = playerName[lastPlayer];
+
+ cursor.x = 14;
+ cursor.y = 11+lastScore;
+ cursor.chr = hallOfFame[lastScore].name.at(cursor.x-14);
+
+// startTimer(cursorBlinkMS);
+ setFocus();
+}
+
+/*
+ * Read the highscores, if no file or a file shorter than 4 bytes (versions before 0.2.4 stores only
+ * the points of one highscore) exists - the highscores were initialized with default values.
+ */
+void Score::read()
+{
+ if (highscoreFile.exists() && highscoreFile.size() > 4) {
+ if (highscoreFile.open(IO_ReadOnly)) {
+ QDataStream s(&highscoreFile);
+ char *name;
+ for (int i = 0; i < 10; i++) {
+ s >> hallOfFame[i].points >> hallOfFame[i].levels >> hallOfFame[i].duration >>
+ hallOfFame[i].moment >> name;
+ hallOfFame[i].name = QString::fromLatin1(name);
+ delete(name);
+ }
+ highscoreFile.close();
+ }
+ } else {
+ for (int i = 0; i < 10; i++) {
+ hallOfFame[i].points = 5000;
+ hallOfFame[i].levels = 0;
+ hallOfFame[i].duration = QTime();
+ hallOfFame[i].moment = QDateTime();
+ hallOfFame[i].name = "???";
+ }
+ // write();
+ }
+
+ for (int i = 0; i < 10; i++)
+ for (uint j = 0; j < hallOfFame[i].name.length(); j++)
+ if (hallOfFame[i].name.at(j) < bitfont->firstChar() ||
+ hallOfFame[i].name.at(j) > bitfont->lastChar())
+ hallOfFame[i].name.at(j) = hallOfFame[i].name.at(j).upper();
+
+ HighScore = hallOfFame[0].points;
+}
+
+void Score::write()
+{
+#ifndef QWS
+ if (!highscoreFile.exists() && highscoreFile.name() == systemHighscoreFileInfo.filePath())
+ KMessageBox::information(0,
+ i18n("You're going to create the highscore-file\n"
+ "'%1'\n"
+ "for your maschine, that should be used systemwide.\n"
+ "\n"
+ "To grant access to the other users, set the appropriate rights (a+w)\n"
+ "on that file or ask your systemadministator for that favor.\n"
+ "\n"
+ "To use a different directory or filename for the highscores,"
+ "specify them in the configfile (kpacmanrc:highscoreFilePath)."
+ ).arg(systemHighscoreFileInfo.filePath()));
+
+ if (highscoreFile.name() == privateHighscoreFileInfo.filePath())
+ KMessageBox::information(0,
+ i18n("You're using a private highscore-file, that's mostly because of\n"
+ "missing write-access to the systemwide file\n"
+ "'%1' .\n"
+ "\n"
+ "Ask your systemadministrator for granting you access to that file,\n"
+ "by setting the appropriate rights (a+w) on it.\n"
+ "\n"
+ "To use a different directory or filename for the highscores,"
+ "specify them in the configfile (kpacmanrc:highscoreFilePath)."
+ ).arg(systemHighscoreFileInfo.filePath()),
+ QString::null, "PrivateHighscore");
+#endif
+ if (highscoreFile.open(IO_WriteOnly)) {
+ QDataStream s(&highscoreFile);
+ for (int i = 0; i < 10; i++)
+ s << hallOfFame[i].points << hallOfFame[i].levels << hallOfFame[i].duration <<
+ hallOfFame[i].moment << hallOfFame[i].name.latin1();
+ highscoreFile.close();
+ }
+}
+
+void Score::setPause(bool Paused)
+{
+ paused = Paused;
+
+ QRect r = bitfont->rect(i18n("PAUSED"));
+ r.moveCenter(QPoint(this->width()/2, this->height()/2));
+ repaint(r, TRUE);
+
+ // repaint 1UP or 2UP
+ repaint(FALSE);
+}
+
+void Score::end()
+{
+ if (paused) {
+ QTimer::singleShot(afterPauseMS, this, SLOT(end()));
+ return;
+ }
+
+ // repaint 1UP or 2UP
+ lastPlayer = -1;
+ repaint(FALSE);
+
+ emit forcedHallOfFame(FALSE);
+}
+
+/*
+ * Return the date in a formatted QString. The format can be changed using internationalization
+ * of the string "YY/MM/DD". Invalid QDate's where returned as "00/00/00".
+ */
+QString Score::formatDate(QDate date)
+{
+ QString s = i18n("@YY@/@MM@/@DD@");
+
+ QString dd;
+ dd.sprintf("%02d", date.isValid() ? date.year() % 100 : 0);
+ s.replace(QRegExp("@YY@"), dd);
+ dd.sprintf("%02d", date.isValid() ? date.month() : 0);
+ s.replace(QRegExp("@MM@"), dd);
+ dd.sprintf("%02d", date.isValid() ? date.day() : 0);
+ s.replace(QRegExp("@DD@"), dd);
+
+ return s;
+}
+
+QRect Score::rect(int col, float row, QString str, int align)
+{
+ QRect r = bitfont->rect(str);
+ r.moveBy(x(col), y(row));
+
+ int dx = 0;
+ int dy = 0;
+
+ if (align & AlignLeft || align & AlignRight) {
+ dx = (str.length()-1) * (bitfont->width()/2);
+ if (align & AlignRight)
+ dx *= -1;
+ }
+
+ if (align & AlignTop || align & AlignBottom) {
+ dy = bitfont->height()/2;
+ if (align & AlignBottom)
+ dy *= -1;
+ }
+
+ if (dx != 0 || dy != 0)
+ r.moveBy(dx, dy);
+
+ return r;
+}
+
+int Score::x(int col)
+{
+ return col*bitfont->width();
+}
+
+int Score::y(float row)
+{
+ return (int) (row*(bitfont->height()+bitfont->height()/4));
+}
+
+/**
+ * Ermittelt die zu benutzende "highscore"-Datei, in die auch geschrieben werden kann.
+ * Über den "highscoreFilePath"-KConfig-Eintrag, kann abweichend von der Standardlokation
+ * der Standort der "highscore"-Datei spezifiziert werden.
+ * Wenn die systemweite "highscore"-Datei nicht beschrieben werden kann, wird mit einer
+ * privaten Datei gearbeitet.
+ */
+QFileInfo Score::locateHighscoreFilePath()
+{
+#ifndef QWS
+ QFileInfo systemHighscoreDirPath;
+ QStringList systemHighscoreDirs;
+
+ // Schreibfähige "private" highscore-Datei ermitteln für den fallback.
+ privateHighscoreFileInfo.setFile(KGlobal::dirs()->saveLocation("appdata")+highscoreName);
+
+ // FilePath aus der Konfigurationsdatei benutzen
+ systemHighscoreFileInfo.setFile(cfg->readEntry("HighscoreFilePath"));
+
+ // Kein Wert aus der Konfiguration erhalten, dann die "system"-Datei suchen.
+ if (systemHighscoreFileInfo.filePath().isEmpty())
+ systemHighscoreDirs = KGlobal::dirs()->resourceDirs("appdata");
+ else
+ systemHighscoreDirs = QStringList(systemHighscoreFileInfo.filePath());
+
+ for (QStringList::Iterator i = systemHighscoreDirs.begin(); i != systemHighscoreDirs.end(); ++i) {
+
+ systemHighscoreFileInfo.setFile(*i);
+ if (systemHighscoreFileInfo.fileName().isEmpty())
+ systemHighscoreFileInfo.setFile(systemHighscoreFileInfo.dirPath()+"/"+highscoreName);
+
+ // privateHighscoreFileInfo für die "system" Suche ignorieren
+ if (systemHighscoreFileInfo.filePath() != privateHighscoreFileInfo.filePath())
+ if (!systemHighscoreFileInfo.exists()) {
+ systemHighscoreDirPath.setFile(systemHighscoreFileInfo.dirPath());
+ if (systemHighscoreDirPath.exists() && systemHighscoreDirPath.isWritable())
+ return systemHighscoreFileInfo;
+ } else
+ if (systemHighscoreFileInfo.isWritable())
+ return systemHighscoreFileInfo;
+ }
+#endif
+ return privateHighscoreFileInfo;
+}
diff --git a/noncore/games/kpacman/score.h b/noncore/games/kpacman/score.h
new file mode 100644
index 0000000..87f24b9
--- a/dev/null
+++ b/noncore/games/kpacman/score.h
@@ -0,0 +1,129 @@
+#ifndef SCORE_H
+#define SCORE_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <kapp.h>
+#endif
+
+#include <qwidget.h>
+#include <qstring.h>
+#include <qpoint.h>
+#include <qrect.h>
+#include <qfile.h>
+
+#include <qfileinfo.h>
+#include <qdatetime.h>
+
+#include "painter.h"
+#include "bitfont.h"
+
+#define maxPlayer 1
+#define minPlayerNameLength 3
+#define highscoreName "highscore"
+
+class Score : public QWidget
+{
+ Q_OBJECT
+public:
+ Score (QWidget *parent=0, const char *name=0, int scheme=-1, int mode=-1, Bitfont *font=0);
+ ~Score();
+
+public slots:
+ void setScheme(int scheme, int mode, Bitfont *font=0);
+
+ void set(int score);
+ void set(int score, int player);
+ void setScore(int level, int player);
+ void setPause(bool paused);
+
+ void initKeys();
+
+private slots:
+ void read();
+ void write();
+ void end();
+
+signals:
+ void toggleNew();
+ void forcedHallOfFame(bool);
+
+protected:
+ void timerEvent(QTimerEvent *);
+ void paintEvent(QPaintEvent *);
+ void keyPressEvent(QKeyEvent *);
+
+ void focusInEvent(QFocusEvent *) { ; }
+ void focusOutEvent(QFocusEvent *) { ; }
+
+ void confScheme();
+ void confTiming(bool defGroup=TRUE);
+
+private:
+ Bitfont *bitfont;
+
+ QRect rect(int col, float row, QString str, int align = AlignCenter);
+ int x(int col);
+ int y(float row);
+
+ QString formatDate(QDate date);
+
+ /**
+ * Ermittelt die zu benutzende "highscore"-Datei, in die auch geschrieben werden kann.
+ * Über den "highscoreFilePath"-KConfig-Eintrag, kann abweichend von der Standardlokation
+ * der Standort der "highscore"-Datei spezifiziert werden.
+ * Wenn die systemweite "globale" Datei nicht beschrieben werden kann, wird mit einer
+ * privaten Datei gearbeitet.
+ */
+ QFileInfo locateHighscoreFilePath();
+
+ int cursorBlinkMS;
+ int hallOfFameMS;
+ int afterPauseMS;
+
+ bool paused;
+
+ uint UpKey;
+ uint DownKey;
+ uint RightKey;
+ uint LeftKey;
+
+ int lastScore;
+ int lastPlayer;
+ int HighScore;
+ int playerScore[maxPlayer];
+ QString playerName[maxPlayer];
+
+ struct {
+ int x;
+ int y;
+ QChar chr;
+ bool on;
+ } cursor;
+
+ int cursorBlinkTimer;
+ bool scrollRepeat;
+
+ struct {
+ int points;
+ int levels;
+ QTime duration;
+ QDateTime moment;
+ QString name;
+ } hallOfFame[10];
+
+ QFileInfo systemHighscoreFileInfo;
+ QFileInfo privateHighscoreFileInfo;
+
+ QFile highscoreFile;
+
+ int scheme;
+ int mode;
+};
+
+#endif // SCORE_H
diff --git a/noncore/games/kpacman/status.cpp b/noncore/games/kpacman/status.cpp
new file mode 100644
index 0000000..00d1f22
--- a/dev/null
+++ b/noncore/games/kpacman/status.cpp
@@ -0,0 +1,367 @@
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <kapp.h>
+#include <klocale.h>
+#include <kstddirs.h>
+#include <status.h>
+#include <status.moc>
+#elif defined( QPE_PORT )
+#include <qpe/qpeapplication.h>
+#include "config.h"
+#include "status.h"
+#endif
+
+#include <qpixmap.h>
+#include <qbitmap.h>
+#include <qstring.h>
+#include <qmsgbox.h>
+#include <qfileinfo.h>
+
+Status::Status( QWidget *parent, const char *name, int Scheme, int Mode ) :
+ QWidget( parent, name )
+{
+ actualLifes = 0;
+ actualLevel = 0;
+
+ lifesPix = NULL;
+ levelPix = NULL;
+
+ scheme = Scheme;
+ mode = Mode;
+ level = 0;
+
+ confScheme();
+}
+
+QList<QPixmap> *Status::loadPixmap(QWidget *parent, QString pixmapName,
+ QList<QPixmap> *pixmaps)
+{
+ if (pixmaps == NULL) {
+ pixmaps = new QList<QPixmap>;
+ pixmaps->setAutoDelete(TRUE);
+ }
+
+ if (!pixmaps->isEmpty())
+ pixmaps->clear();
+
+ QPixmap PIXMAP(pixmapName);
+ if (PIXMAP.isNull() || PIXMAP.mask() == NULL) {
+ QString msg = i18n("The pixmap could not be contructed.\n\n"
+ "The file '@PIXMAPNAME@' does not exist,\n"
+ "or is of an unknown format.");
+ msg.replace(QRegExp("@PIXMAPNAME@"), pixmapName);
+ QMessageBox::information(parent, i18n("Initialization Error"),
+ (const char *) msg);
+ return 0;
+ }
+
+ int height = PIXMAP.height();
+ int width = (height == 0) ? 0 : PIXMAP.width()/(PIXMAP.width()/height);
+
+ QBitmap BITMAP;
+ QBitmap MASK;
+
+ BITMAP = *PIXMAP.mask();
+ MASK.resize(width, height);
+
+ for (int x = 0; x < PIXMAP.width()/width; x++) {
+ QPixmap *pixmap = new QPixmap(width, height);
+ pixmaps->append(pixmap);
+ bitBlt(pixmap, 0, 0, &PIXMAP, x*width, 0, width, height, CopyROP, TRUE);
+ bitBlt(&MASK, 0, 0, &BITMAP, x*width, 0, width, height, CopyROP, TRUE);
+ pixmap->setMask(MASK);
+ }
+
+ return pixmaps;
+}
+
+void Status::paintEvent( QPaintEvent *)
+{
+ for (int x = 0; x < actualLifes && !lifesPix->isEmpty(); x++)
+ bitBlt(this, lifesPix->at(0)->width()+(lifesPix->at(0)->width()*x),
+ (height()-lifesPix->at(0)->height())/2,
+ lifesPix->at(0), 0, 0,
+ lifesPix->at(0)->width(), lifesPix->at(0)->height());
+
+ for (int x = 0; x < actualLevel && !levelPix->isEmpty(); x++) {
+ erase((width()-levelPix->at(x)->width()*2)-(levelPix->at(x)->width()*levelPos[x]),
+ (height()-levelPix->at(x)->height())/2,
+ levelPix->at(x)->width(), levelPix->at(x)->height());
+ bitBlt(this, (width()-levelPix->at(x)->width()*2)-(levelPix->at(x)->width()*levelPos[x]),
+ (height()-levelPix->at(x)->height())/2,
+ levelPix->at(x), 0, 0,
+ levelPix->at(x)->width(), levelPix->at(x)->height());
+ }
+}
+
+void Status::initPixmaps()
+{
+ if (lastLifesPixmapName != lifesPixmapName.at(level)) {
+ lifesPix = loadPixmap(this, lifesPixmapName.at(level), lifesPix);
+ lastLifesPixmapName = lifesPixmapName.at(level);
+ }
+ if (lastLevelPixmapName != levelPixmapName.at(level)) {
+ levelPix = loadPixmap(this, levelPixmapName.at(level), levelPix);
+ lastLevelPixmapName = levelPixmapName.at(level);
+ }
+}
+
+QString Status::decodeHexOctString(QString s)
+{
+ QString value;
+ QString valids;
+ int pos, xpos = 0, opos = 0;
+ int v, len, leadin;
+ const char *ptr;
+ uchar c;
+
+ while (((xpos = s.find(QRegExp("\\\\x[0-9a-fA-F]+"), xpos)) != -1) ||
+ ((opos = s.find(QRegExp("\\\\[0-7]+"), opos)) != -1)) {
+ if (xpos != -1) {
+ valids = "0123456789abcdef";
+ leadin = 2;
+ pos = xpos;
+ } else {
+ valids = "01234567";
+ leadin = 1;
+ pos = opos;
+ }
+
+ c = '\0';
+ len = 0;
+ value = s.mid(pos+leadin, 3);
+ ptr = (const char *) value;
+
+ while (*ptr != '\0' && (v = valids.find(*ptr++, 0, FALSE)) != -1) {
+ c = (c * valids.length()) + v;
+ len++;
+ }
+
+ value.fill(c, 1);
+ s.replace(pos, len+leadin, value);
+ }
+
+ return s;
+}
+
+void Status::fillArray(QArray<int> &array, QString values, int max)
+{
+ array.resize(max);
+ int last = 0;
+ bool ok;
+ QString value;
+
+ for (uint i = 0; i < array.size(); i++) {
+ if (values.find(',') < 0 && values.length() > 0) {
+ value = values;
+ values = "";
+ }
+ if (values.find(',') >= 0) {
+ value = values.left(values.find(','));
+ values.remove(0,values.find(',')+1);
+ }
+ array[i] = value.toInt(&ok);
+ if (ok)
+ last = array[i];
+ else
+ array[i] = last;
+ }
+}
+
+void Status::fillStrList(QStrList &list, QString values, int max)
+{
+ if (!list.isEmpty())
+ list.clear();
+
+ QString last = "";
+ QString value;
+
+ for (uint i = 0; i < (uint) max; i++) {
+ if (values.find(',') < 0 && values.length() > 0) {
+ value = values;
+ values = "";
+ }
+ if (values.find(',') >= 0) {
+ value = values.left(values.find(','));
+ values.remove(0,values.find(',')+1);
+ }
+ if (!value.isEmpty())
+ last = decodeHexOctString(value);
+ list.append(last);
+ }
+}
+
+void Status::fillPixmapName(QStrList &pixmapName)
+{
+ QStrList list = pixmapName;
+
+ if (!pixmapName.isEmpty())
+ pixmapName.clear();
+
+ QString pixmap;
+
+ QFileInfo fileInfo;
+
+ for (uint i = 0; i < list.count(); i++) {
+ pixmap = list.at(i);
+
+ if (pixmap.left(1) != "/" && pixmap.left(1) != "~")
+ pixmap = FIND_APP_DATA( pixmapDirectory+pixmap );
+
+ fileInfo.setFile(pixmap);
+ if (!fileInfo.isReadable() || !fileInfo.isFile())
+ pixmap = "";
+
+ pixmapName.append(pixmap);
+ }
+}
+
+void Status::confLevels(bool defGroup)
+{
+ APP_CONFIG_BEGIN( cfg );
+ if (defGroup || cfg->hasKey("Levels"))
+ maxLevel = cfg->readNumEntry("Levels", 13);
+ APP_CONFIG_END( cfg );
+}
+
+void Status::confMisc(bool defGroup)
+{
+ APP_CONFIG_BEGIN( cfg );
+ if (defGroup || cfg->hasKey("LevelPosition"))
+ fillArray(levelPos, cfg->readEntry("LevelPosition", "0,1,2,3,,4,,5,,6,,7"), maxLevel);
+
+ if (defGroup || cfg->hasKey("PixmapDirectory")) {
+ pixmapDirectory = cfg->readEntry("PixmapDirectory");
+
+ if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~")
+ pixmapDirectory.insert(0, "pics/");
+ if (pixmapDirectory.right(1) != "/")
+ pixmapDirectory.append("/");
+ }
+
+ if (defGroup || cfg->hasKey("LifesPixmapName"))
+ fillStrList(lifesPixmapName,
+ cfg->readEntry("LifesPixmapName", "lifes.xpm"), maxLevel+1);
+ if (defGroup || cfg->hasKey("LevelPixmapName"))
+ fillStrList(levelPixmapName,
+ cfg->readEntry("LevelPixmapName", "level.xpm"), maxLevel+1);
+ APP_CONFIG_END( cfg );
+}
+
+void Status::confScheme()
+{
+ APP_CONFIG_BEGIN( cfg );
+ SAVE_CONFIG_GROUP( cfg, oldgroup );
+ QString newgroup;
+
+ // if not set, read mode and scheme from the configfile
+ if (mode == -1 && scheme == -1) {
+ scheme = cfg->readNumEntry("Scheme", -1);
+ mode = cfg->readNumEntry("Mode", -1);
+
+ // if mode is not set in the defGroup-group, lookup the scheme group
+ if (scheme != -1 || mode == -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ cfg->setGroup(newgroup);
+
+ mode = cfg->readNumEntry("Mode", -1);
+ RESTORE_CONFIG_GROUP( cfg, oldgroup );
+ }
+ }
+
+ confLevels();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ cfg->setGroup(newgroup);
+
+ confLevels(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ cfg->setGroup(newgroup);
+
+ confLevels(FALSE);
+ }
+
+ RESTORE_CONFIG_GROUP( cfg, oldgroup );
+
+ confMisc();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ cfg->setGroup(newgroup);
+
+ confMisc(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ cfg->setGroup(newgroup);
+
+ confMisc(FALSE);
+ }
+
+ fillPixmapName(lifesPixmapName);
+ fillPixmapName(levelPixmapName);
+
+ initPixmaps();
+
+ setFixedHeight(minHeight());
+
+ RESTORE_CONFIG_GROUP( cfg, oldgroup );
+ APP_CONFIG_END( cfg );
+}
+
+void Status::setScheme(int Scheme, int Mode)
+{
+ mode = Mode;
+ scheme = Scheme;
+
+ confScheme();
+
+ repaint();
+}
+
+int Status::minHeight()
+{
+ if (lifesPix->isEmpty() && levelPix->isEmpty())
+ return 0;
+ if (levelPix->isEmpty())
+ return lifesPix->at(0)->height();
+ if (lifesPix->isEmpty())
+ return levelPix->at(0)->height();
+ return (lifesPix->at(0)->height() > levelPix->at(0)->height()) ?
+ lifesPix->at(0)->height() : levelPix->at(0)->height();
+}
+
+int Status::minWidth()
+{
+ if (lifesPix->isEmpty() && levelPix->isEmpty())
+ return 0;
+ if (levelPix->isEmpty())
+ return lifesPix->at(0)->width();
+ if (lifesPix->isEmpty())
+ return levelPix->at(0)->width();
+ return (lifesPix->at(0)->width() > levelPix->at(0)->width()) ?
+ lifesPix->at(0)->width() : levelPix->at(0)->width();
+}
+
+void Status::setLifes(int lifes)
+{
+ actualLifes = lifes;
+ repaint();
+}
+
+void Status::setLevel(int Level)
+{
+ level = Level;
+
+ initPixmaps();
+
+ actualLevel = (level > (int) levelPix->count()) ? (int) levelPix->count() : level;
+ repaint();
+}
diff --git a/noncore/games/kpacman/status.h b/noncore/games/kpacman/status.h
new file mode 100644
index 0000000..4f69b02
--- a/dev/null
+++ b/noncore/games/kpacman/status.h
@@ -0,0 +1,78 @@
+#ifndef STATUS_H
+#define STATUS_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "portable.h"
+
+#if defined( KDE2_PORT )
+#include <kapp.h>
+#include <kconfig.h>
+#endif
+
+#include <qwidget.h>
+#include <qpixmap.h>
+#include <qstring.h>
+#include <qarray.h>
+#include <qlist.h>
+#include <qstrlist.h>
+#include <qregexp.h>
+
+class Status : public QWidget
+{
+ Q_OBJECT
+public:
+ Status(QWidget *parent=0, const char *name=0, int scheme=-1, int mode=-1);
+ ~Status() {};
+
+public slots:
+ void setScheme(int scheme, int mode);
+ void setLevel(int level);
+ void setLifes(int lifes);
+
+protected:
+ void paintEvent(QPaintEvent *);
+ int minHeight();
+ int minWidth();
+
+ QString decodeHexOctString(QString str);
+
+ void fillArray(QArray<int> &, QString, int);
+ void fillStrList(QStrList &, QString, int);
+ void fillPixmapName(QStrList &);
+
+ void confScheme();
+ void confLevels(bool defGroup=TRUE);
+ void confMisc(bool defGroup=TRUE);
+
+ void initPixmaps();
+
+private:
+ QArray<int> levelPos;
+ int actualLifes;
+ int actualLevel;
+
+ QString pixmapDirectory;
+
+ QStrList lifesPixmapName;
+ QStrList levelPixmapName;
+
+ QString lastLifesPixmapName;
+ QString lastLevelPixmapName;
+
+ QList<QPixmap> *loadPixmap(QWidget *parent, QString pixmapName,
+ QList<QPixmap> *pixmaps=0);
+
+ QList<QPixmap> *lifesPix;
+ QList<QPixmap> *levelPix;
+
+ int maxLevel;
+ int level;
+
+ int scheme;
+ int mode;
+};
+
+#endif // STATUS_H