summaryrefslogtreecommitdiff
authorleseb <leseb>2002-04-15 22:40:28 (UTC)
committer leseb <leseb>2002-04-15 22:40:28 (UTC)
commita91544d04ed391bbdc0c6f95ff8a80d35190788c (patch) (side-by-side diff)
tree85dea85fd8a1cdb6d2d18fef57753d0b5e4bd143
parent6396d8b9fca7f3f50010a13a26e4ee9569abefb3 (diff)
downloadopie-a91544d04ed391bbdc0c6f95ff8a80d35190788c.zip
opie-a91544d04ed391bbdc0c6f95ff8a80d35190788c.tar.gz
opie-a91544d04ed391bbdc0c6f95ff8a80d35190788c.tar.bz2
New directory structure
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--apps/Games/kpacman.desktop8
-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
-rw-r--r--pics/kpacman.pngbin0 -> 535 bytes
-rw-r--r--share/kpacman/fonts/font.xbm140
-rw-r--r--share/kpacman/kpacman.conf71
-rw-r--r--share/kpacman/pics/down.xpm29
-rw-r--r--share/kpacman/pics/dying.xpm21
-rw-r--r--share/kpacman/pics/eyes.xpm22
-rw-r--r--share/kpacman/pics/fruit.xpm32
-rw-r--r--share/kpacman/pics/left.xpm29
-rw-r--r--share/kpacman/pics/lifes.xpm21
-rw-r--r--share/kpacman/pics/monster.xpm28
-rw-r--r--share/kpacman/pics/pacman.xpm21
-rw-r--r--share/kpacman/pics/point.xpm9
-rw-r--r--share/kpacman/pics/prison.xpm10
-rw-r--r--share/kpacman/pics/right.xpm29
-rw-r--r--share/kpacman/pics/switch.xpm13
-rw-r--r--share/kpacman/pics/up.xpm29
-rw-r--r--share/kpacman/pics/wall.xpm9
54 files changed, 7690 insertions, 0 deletions
diff --git a/apps/Games/kpacman.desktop b/apps/Games/kpacman.desktop
new file mode 100644
index 0000000..da51668
--- a/dev/null
+++ b/apps/Games/kpacman.desktop
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Type=Application
+Exec=kpacman
+Icon=kpacman
+Comment=
+Comment[de]=
+Name=Kpacman
+Name[de]=Kpacman
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
diff --git a/pics/kpacman.png b/pics/kpacman.png
new file mode 100644
index 0000000..2c2d2e6
--- a/dev/null
+++ b/pics/kpacman.png
Binary files differ
diff --git a/share/kpacman/fonts/font.xbm b/share/kpacman/fonts/font.xbm
new file mode 100644
index 0000000..5c7ffcd
--- a/dev/null
+++ b/share/kpacman/fonts/font.xbm
@@ -0,0 +1,140 @@
+#define font_small_width 128
+#define font_small_height 128
+static char font_small_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x02,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x02,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x02,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x02,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x02,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x06,0x88,0x8e,0x9f,0x88,0x9f,
+ 0x9c,0x9f,0x8e,0x8c,0x39,0x63,0x00,0x00,0x00,0x42,0x09,0x4c,0x51,0x48,0x4c,
+ 0x41,0x42,0x50,0x51,0x52,0x85,0x94,0x00,0x00,0x00,0x99,0x09,0x48,0x51,0x44,
+ 0x4a,0x4f,0x42,0x48,0x51,0x52,0x85,0x94,0xf0,0x7c,0x1e,0x85,0x09,0x48,0x48,
+ 0x48,0x49,0x50,0x5e,0x48,0x4e,0x5e,0xbd,0x94,0x10,0x11,0x01,0x85,0x09,0x48,
+ 0x44,0x50,0x5f,0x50,0x52,0x44,0x51,0x50,0xa5,0x94,0xf0,0x10,0x0e,0x99,0x09,
+ 0x48,0x42,0x51,0x48,0x51,0x52,0x44,0x51,0x50,0xa5,0x94,0x10,0x10,0x10,0x42,
+ 0x06,0x9c,0x9f,0x8e,0x88,0x8e,0x8c,0x84,0x8e,0x8e,0x19,0x63,0x10,0x10,0x0f,
+ 0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x38,0x36,0x14,0x08,0x42,0x04,0x0c,0x18,0x0c,0x08,0x00,0x00,
+ 0x00,0x00,0x40,0x00,0x38,0x36,0x3e,0x1c,0x25,0x0a,0x0c,0x0c,0x18,0x1c,0x08,
+ 0x00,0x00,0x00,0x20,0x00,0x1c,0x24,0x14,0x0a,0x12,0x04,0x08,0x0c,0x18,0x7f,
+ 0x08,0x00,0x00,0x00,0x10,0x00,0x0c,0x12,0x14,0x1c,0x08,0x2a,0x04,0x0c,0x18,
+ 0x3e,0x3e,0x0c,0x1c,0x00,0x08,0x00,0x04,0x00,0x3e,0x28,0x24,0x11,0x00,0x0c,
+ 0x18,0x1c,0x08,0x0c,0x00,0x00,0x04,0x00,0x00,0x00,0x14,0x1e,0x52,0x11,0x00,
+ 0x0c,0x18,0x3e,0x08,0x08,0x00,0x0c,0x02,0x00,0x02,0x00,0x14,0x08,0x21,0x2e,
+ 0x00,0x18,0x0c,0x22,0x00,0x04,0x00,0x0c,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x18,0x3e,0x7e,0x38,
+ 0x3f,0x3c,0x7f,0x1e,0x3e,0x00,0x00,0x30,0x00,0x06,0x1e,0x32,0x1c,0x63,0x30,
+ 0x3c,0x03,0x06,0x63,0x23,0x63,0x0c,0x0c,0x18,0x00,0x0c,0x33,0x63,0x18,0x70,
+ 0x18,0x36,0x3f,0x03,0x30,0x27,0x63,0x0c,0x0c,0x0c,0x3e,0x18,0x33,0x63,0x18,
+ 0x3c,0x3c,0x33,0x60,0x3f,0x18,0x1e,0x7e,0x00,0x00,0x06,0x00,0x30,0x18,0x63,
+ 0x18,0x1e,0x60,0x7f,0x60,0x63,0x0c,0x79,0x60,0x0c,0x0c,0x0c,0x3e,0x18,0x0c,
+ 0x26,0x18,0x07,0x63,0x30,0x63,0x63,0x0c,0x61,0x30,0x0c,0x08,0x18,0x00,0x0c,
+ 0x00,0x1c,0x7e,0x7f,0x3e,0x30,0x3e,0x3e,0x0c,0x3e,0x1e,0x00,0x04,0x30,0x00,
+ 0x06,0x0c,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x42,0x38,0x7e,0x78,0x3e,0xfc,0xfe,0xf8,0xc6,0xfc,0xf8,0xc6,
+ 0x0c,0xc6,0xc6,0x7c,0xa9,0x6c,0xc6,0xcc,0x66,0x0c,0x06,0x0c,0xc6,0x30,0x60,
+ 0x66,0x0c,0xee,0xce,0xc6,0x95,0xc6,0xc6,0x06,0xc6,0x0c,0x06,0x06,0xc6,0x30,
+ 0x60,0x36,0x0c,0xfe,0xde,0xc6,0x95,0xc6,0x7e,0x06,0xc6,0x7c,0x7e,0xe6,0xfe,
+ 0x30,0x60,0x1e,0x0c,0xfe,0xfe,0xc6,0x69,0xfe,0xc6,0x06,0xc6,0x0c,0x06,0xc6,
+ 0xc6,0x30,0x66,0x3e,0x0c,0xd6,0xf6,0xc6,0x02,0xc6,0xc6,0xcc,0x66,0x0c,0x06,
+ 0xcc,0xc6,0x30,0x66,0x76,0x0c,0xc6,0xe6,0xc6,0x3c,0xc6,0x7e,0x78,0x3e,0xfc,
+ 0x06,0xf8,0xc6,0xfc,0x3c,0xe6,0xfc,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x7c,0x7e,0x3c,
+ 0xfc,0xc6,0xc6,0xc6,0xc6,0xcc,0xfe,0x3c,0x02,0x3c,0x10,0x00,0xc6,0xc6,0xc6,
+ 0x66,0x30,0xc6,0xc6,0xc6,0xee,0xcc,0xe0,0x0c,0x04,0x30,0x38,0x00,0xc6,0xc6,
+ 0xc6,0x06,0x30,0xc6,0xc6,0xd6,0x78,0xcc,0x70,0x0c,0x08,0x30,0x6c,0x00,0xc6,
+ 0xc6,0xe6,0x7c,0x30,0xc6,0xee,0xfe,0x38,0x78,0x38,0x0c,0x10,0x30,0x00,0x00,
+ 0x7e,0xd6,0x3e,0xc0,0x30,0xc6,0x7c,0xfe,0x7c,0x30,0x1c,0x0c,0x20,0x30,0x00,
+ 0x00,0x06,0x66,0x76,0xc6,0x30,0xc6,0x38,0xee,0xee,0x30,0x0e,0x0c,0x40,0x30,
+ 0x00,0x00,0x06,0xdc,0xe6,0x7c,0x30,0x7c,0x10,0xc6,0xc6,0x30,0xfe,0x3c,0x80,
+ 0x3c,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x10,0x38,0x7e,0x78,0x3e,0xfc,0xfe,0xf8,0xc6,0xfc,0xf8,
+ 0xc6,0x0c,0xc6,0xc6,0x7c,0x18,0x6c,0xc6,0xcc,0x66,0x0c,0x06,0x0c,0xc6,0x30,
+ 0x60,0x66,0x0c,0xee,0xce,0xc6,0x18,0xc6,0xc6,0x06,0xc6,0x0c,0x06,0x06,0xc6,
+ 0x30,0x60,0x36,0x0c,0xfe,0xde,0xc6,0x00,0xc6,0x7e,0x06,0xc6,0x7c,0x7e,0xe6,
+ 0xfe,0x30,0x60,0x1e,0x0c,0xfe,0xfe,0xc6,0x00,0xfe,0xc6,0x06,0xc6,0x0c,0x06,
+ 0xc6,0xc6,0x30,0x66,0x3e,0x0c,0xd6,0xf6,0xc6,0x00,0xc6,0xc6,0xcc,0x66,0x0c,
+ 0x06,0xcc,0xc6,0x30,0x66,0x76,0x0c,0xc6,0xe6,0xc6,0x00,0xc6,0x7e,0x78,0x3e,
+ 0xfc,0x06,0xf8,0xc6,0xfc,0x3c,0xe6,0xfc,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x7c,0x7e,
+ 0x3c,0xfc,0xc6,0xc6,0xc6,0xc6,0xcc,0xfe,0x38,0x18,0x1c,0x4c,0x00,0xc6,0xc6,
+ 0xc6,0x66,0x30,0xc6,0xc6,0xc6,0xee,0xcc,0xe0,0x18,0x18,0x18,0x7e,0x00,0xc6,
+ 0xc6,0xc6,0x06,0x30,0xc6,0xc6,0xd6,0x78,0xcc,0x70,0x18,0x18,0x18,0x32,0x00,
+ 0xc6,0xc6,0xe6,0x7c,0x30,0xc6,0xee,0xfe,0x38,0x78,0x38,0x0c,0x18,0x30,0x00,
+ 0x00,0x7e,0xd6,0x3e,0xc0,0x30,0xc6,0x7c,0xfe,0x7c,0x30,0x1c,0x18,0x18,0x18,
+ 0x00,0x00,0x06,0x66,0x76,0xc6,0x30,0xc6,0x38,0xee,0xee,0x30,0x0e,0x18,0x18,
+ 0x18,0x00,0x00,0x06,0xdc,0xe6,0x7c,0x30,0x7c,0x10,0xc6,0xc6,0x30,0xfe,0x38,
+ 0x18,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,
+ 0x00,0x00,0x00,0x00,0x3c,0x00,0x00,0x0c,0x20,0x3c,0x00,0xcc,0x18,0x38,0x14,
+ 0x42,0x1c,0x00,0x00,0x00,0x42,0x3c,0x00,0x08,0x38,0x04,0x24,0xcc,0x18,0x08,
+ 0x00,0x99,0x20,0x00,0x00,0x00,0x99,0x00,0x00,0x00,0x54,0x1e,0x18,0x78,0x18,
+ 0x34,0x00,0x85,0x3c,0x48,0x00,0x00,0xa9,0x00,0x00,0x08,0x14,0x04,0x24,0xfc,
+ 0x00,0x44,0x00,0x85,0x24,0x24,0x7c,0x7c,0x99,0x00,0x00,0x0c,0x54,0x04,0x18,
+ 0x30,0x18,0x38,0x00,0x99,0x38,0x48,0x60,0x00,0xa9,0x00,0x00,0x0c,0x38,0x2e,
+ 0x24,0xfc,0x18,0x24,0x00,0x42,0x00,0x00,0x60,0x00,0x42,0x00,0x00,0x0c,0x08,
+ 0x3a,0x00,0x30,0x18,0x18,0x00,0x3c,0x7c,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,
+ 0x10,0x18,0x38,0x10,0x00,0x7e,0x00,0x00,0x10,0x30,0x00,0x44,0x24,0x46,0x30,
+ 0x24,0x10,0x20,0x10,0x18,0x66,0x6e,0x00,0x00,0x18,0x48,0x00,0xa6,0x26,0xa4,
+ 0x00,0x18,0x7c,0x10,0x20,0x08,0x66,0x6e,0x10,0x00,0x10,0x30,0x24,0xe4,0x74,
+ 0xe8,0x30,0x00,0x10,0x38,0x38,0x00,0x66,0x68,0x38,0x00,0x10,0x00,0x48,0xd4,
+ 0x94,0xde,0x18,0x00,0x10,0x00,0x00,0x00,0x7e,0x68,0x10,0x00,0x00,0x78,0x24,
+ 0xf0,0x88,0xf0,0xcc,0x00,0x00,0x00,0x00,0x00,0x06,0x68,0x00,0x30,0x00,0x00,
+ 0x00,0x88,0x48,0x88,0xcc,0x00,0x7c,0x00,0x00,0x00,0x06,0x68,0x00,0x00,0x00,
+ 0x00,0x00,0x88,0xe4,0x88,0x78,0x1c,0x70,0x10,0x58,0x28,0x10,0x00,0x00,0x38,
+ 0x70,0x10,0x28,0x18,0x60,0x10,0x28,0x00,0x00,0x00,0x24,0x00,0x28,0x00,0x3c,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0x38,0x38,0x38,0x38,0xfc,
+ 0x66,0xfc,0xfc,0xfc,0xfc,0x78,0x78,0x78,0x78,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,
+ 0x36,0x03,0x0c,0x0c,0x0c,0x0c,0x30,0x30,0x30,0x30,0xc6,0xc6,0xc6,0xc6,0xc6,
+ 0xc6,0x7e,0x03,0x7c,0x7c,0x7c,0x7c,0x30,0x30,0x30,0x30,0xfe,0xfe,0xfe,0xfe,
+ 0xfe,0xfe,0x36,0x66,0x0c,0x0c,0x0c,0x0c,0x30,0x30,0x30,0x30,0xc6,0xc6,0xc6,
+ 0xc6,0xc6,0xc6,0x36,0x3c,0x0c,0x0c,0x0c,0x0c,0x30,0x30,0x30,0x30,0xc6,0xc6,
+ 0xc6,0xc6,0xc6,0xc6,0xf6,0x10,0xfc,0xfc,0xfc,0xfc,0x78,0x78,0x78,0x78,0x00,
+ 0x58,0x1c,0x70,0x10,0x58,0x28,0x00,0x00,0x1c,0x70,0x10,0x28,0xe0,0x00,0x00,
+ 0x3c,0x24,0x00,0x00,0x00,0x24,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x04,
+ 0x18,0x6c,0xce,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0xe6,0xc6,0xc6,0xc6,0xc6,0xcc,
+ 0x3c,0x2c,0xcc,0xde,0xc6,0xc6,0xc6,0xc6,0xc6,0x24,0xf6,0xc6,0xc6,0xc6,0xc6,
+ 0xcc,0x24,0x3c,0xde,0xfe,0xc6,0xc6,0xc6,0xc6,0xc6,0x18,0xde,0xc6,0xc6,0xc6,
+ 0xc6,0x78,0x24,0x6c,0xcc,0xf6,0xc6,0xc6,0xc6,0xc6,0xc6,0x24,0xce,0xc6,0xc6,
+ 0xc6,0xc6,0x30,0x3c,0x6c,0x6c,0xe6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0xc6,0xc6,
+ 0xc6,0xc6,0xc6,0x30,0x04,0x3c,0x3c,0xc6,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0x7c,
+ 0x7c,0x7c,0x7c,0x7c,0x30,0x00,0x0c,0x1c,0x70,0x10,0x58,0x28,0x10,0x00,0x00,
+ 0x38,0x70,0x10,0x28,0x18,0x60,0x10,0x28,0x00,0x00,0x00,0x24,0x00,0x28,0x00,
+ 0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0xfc,0x66,0xfc,0xfc,0xfc,0xfc,0x78,0x78,0x78,0x78,0x6c,0x6c,0x6c,0x6c,0x6c,
+ 0x6c,0x36,0x03,0x0c,0x0c,0x0c,0x0c,0x30,0x30,0x30,0x30,0xc6,0xc6,0xc6,0xc6,
+ 0xc6,0xc6,0x7e,0x03,0x7c,0x7c,0x7c,0x7c,0x30,0x30,0x30,0x30,0xfe,0xfe,0xfe,
+ 0xfe,0xfe,0xfe,0x36,0x66,0x0c,0x0c,0x0c,0x0c,0x30,0x30,0x30,0x30,0xc6,0xc6,
+ 0xc6,0xc6,0xc6,0xc6,0x36,0x3c,0x0c,0x0c,0x0c,0x0c,0x30,0x30,0x30,0x30,0xc6,
+ 0xc6,0xc6,0xc6,0xc6,0xc6,0xf6,0x10,0xfc,0xfc,0xfc,0xfc,0x78,0x78,0x78,0x78,
+ 0x00,0x58,0x1c,0x70,0x10,0x58,0x28,0x00,0x00,0x1c,0x70,0x10,0x28,0xe0,0x00,
+ 0x14,0x3c,0x24,0x00,0x00,0x00,0x24,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,
+ 0x04,0x00,0x6c,0xce,0x7c,0x7c,0x7c,0x7c,0x7c,0x10,0xe6,0xc6,0xc6,0xc6,0xc6,
+ 0xcc,0x1c,0x66,0xcc,0xde,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0xf6,0xc6,0xc6,0xc6,
+ 0xc6,0xcc,0x24,0x66,0xde,0xfe,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0xde,0xc6,0xc6,
+ 0xc6,0xc6,0x78,0x24,0x3c,0xcc,0xf6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0xce,0xc6,
+ 0xc6,0xc6,0xc6,0x30,0x1c,0x18,0x6c,0xe6,0xc6,0xc6,0xc6,0xc6,0xc6,0x10,0xc6,
+ 0xc6,0xc6,0xc6,0xc6,0x30,0x04,0x18,0x3c,0xc6,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,
+ 0x7c,0x7c,0x7c,0x7c,0x7c,0x30,0x04,0x18};
diff --git a/share/kpacman/kpacman.conf b/share/kpacman/kpacman.conf
new file mode 100644
index 0000000..baa767d
--- a/dev/null
+++ b/share/kpacman/kpacman.conf
@@ -0,0 +1,71 @@
+[Default]
+FocusInContinue=true
+FocusOutPause=true
+HideMouseCursor=false
+LevelPixmapName=fruit.xpm
+Mode=0
+ModeCount=2
+Scheme=1
+SchemeCount=5
+downKey=Down
+leftKey=Left
+rightKey=Right
+upKey=Up
+
+[Mode 0]
+Description=&Pacman
+
+[Mode 1]
+Description=&Ms.Pacman
+DyingAnimationMS=150
+EnergizerPixmapName=switch.xpm,,,switch02.xpm,,,switch03.xpm,,,,switch.xpm,,,,,,,,,,,,switch03.xpm,,,,switch.xpm
+ExtraLifeScore=-10000,-30000,-50000,30000
+FruitScore=100,200,500,700,1000,2000,5000
+FruitScorePixmapName=fruitscore.xpm
+LevelPosition=0,1,2,3,4,5,6
+Levels=29
+MapDirectory=mspacman
+MapName=map01,,,map02,,,map03,,,,map04,,,,map03,,,,map04,,,,map03,,,,map04
+PointPixmapName=point.xpm,,,point02.xpm,,,point03.xpm,,,,point.xpm,,,,,,,,,,,,point03.xpm,,,,point.xpm
+PrisonPixmapName=prison.xpm,,,prison02.xpm,,,prison03.xpm,,,,prison04.xpm,,,,prison05.xpm,,,,prison06.xpm,,,,prison03.xpm,,,,prison04.xpm
+WallPixmapName=wall.xpm,,,wall02.xpm,,,wall03.xpm,,,,wall04.xpm,,,,wall05.xpm,,,,wall06.xpm,,,,wall03.xpm,,,,wall04.xpm
+
+[Scheme 0]
+Description=&MIDWAY MFG.CO.
+Description[de]=&MIDWAY MFG.CO.
+Font=font-smooth.xbm
+Mode=0
+PixmapDirectory=
+
+[Scheme 1]
+Description=MIDWAY MFG.CO. (&tiny)
+Description[de]=MIDWAY MFG.CO. (&klein)
+Font=font-small.xbm
+Mode=0
+PixmapDirectory=tiny
+
+[Scheme 2]
+Description=K&Zacman (incomplete)
+Description[de]=K&Zacman (unvollständig)
+Font=font-smooth.xbm
+FruitPixmapName=../fruit.xpm
+LevelPixmapName=../fruit.xpm
+PixmapDirectory=zacman
+PrisonPixmapName=../prison.xpm
+
+[Scheme 3]
+Description=&MIDWAY MFG.CO.
+EyesPixmapName=../eyes.xpm
+Font=font-smooth.xbm
+Mode=1
+MonsterPixmapName=../monster.xpm
+PixmapDirectory=mspacman
+
+[Scheme 4]
+Description=MIDWAY MFG.CO. (&tiny)
+Description[de]=MIDWAY MFG.CO. (&klein)
+EyesPixmapName=../tiny/eyes.xpm
+Font=font-small.xbm
+Mode=1
+MonsterPixmapName=../tiny/monster.xpm
+PixmapDirectory=mspacman-tiny
diff --git a/share/kpacman/pics/down.xpm b/share/kpacman/pics/down.xpm
new file mode 100644
index 0000000..66d169d
--- a/dev/null
+++ b/share/kpacman/pics/down.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * d_xpm[] = {
+/* width height num_colors chars_per_pixel */
+"20 20 3 1",
+/* colors */
+" s None c None",
+". c #000000",
+"X c #008080",
+/* pixels */
+" ",
+" ",
+" ",
+" .............. ",
+" .XXXXXXXXXXXX. ",
+" .XXXXXXXXXX. ",
+" .XXXXXXXXXX. ",
+" .XXXXXXXX. ",
+" .XXXXXXXX. ",
+" .XXXXXX. ",
+" .XXXXXX. ",
+" .XXXX. ",
+" .XXXX. ",
+" .XX. ",
+" .XX. ",
+" .. ",
+" .. ",
+" ",
+" ",
+" "};
diff --git a/share/kpacman/pics/dying.xpm b/share/kpacman/pics/dying.xpm
new file mode 100644
index 0000000..5d33fa9
--- a/dev/null
+++ b/share/kpacman/pics/dying.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static char *dying[]={
+"176 16 2 1",
+". c None",
+"# c #ffff00",
+"................................................................................................................................................................................",
+"................................................................................................................................................................................",
+"................................................................................................................................................................................",
+"..##.........##.................................................................................................................................................................",
+"..###.......###...#...........#.................................................................................................................................................",
+"..####.....####..####.......####................................................................................................................................................",
+"..#####...#####..#####.....#####.###.........###......................................................................................................................#...#.....",
+"..######.######..#######.#######.######...######.####.......####....................................................................................................#..#.#......",
+"...###########....#############..###############.###############.....#######...........###..............#...............#...............#...............#............#......#...",
+"...###########....#############...#############..###############.###############.....#######...........###.............###..............#...............#..................#....",
+"....#########......###########.....###########....#############..###############..#############......#######..........#####............###..............#..........##...........",
+"......#####..........###.###.........###.###........####.####.....#############..###############....#########.........#####............###..............#...................##..",
+"....................................................................####.####.....######.######...#############......#######...........###..............#............#..........",
+"....................................................................................###...###.....######.######.....#########.........#####.............#...........#......#....",
+"...................................................................................................####...####.......###.###...........#.#.............................#.#..#...",
+"......................................................................................................................................................................#...#....."};
diff --git a/share/kpacman/pics/eyes.xpm b/share/kpacman/pics/eyes.xpm
new file mode 100644
index 0000000..9e7cfc3
--- a/dev/null
+++ b/share/kpacman/pics/eyes.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static char * eyes_xpm[] = {
+"64 16 3 1",
+" c None",
+"b c #2020d8",
+"w c #dedede",
+" ",
+" ",
+" bb bb ",
+" wbbw wbbw ",
+" wwww wwww ww ww ww ww ",
+" wwww wwww wwww wwww ww ww wwww wwww ",
+" ww ww wwbb wwbb wwww wwww bbww bbww ",
+" wwbb wwbb wwww wwww bbww bbww ",
+" ww ww wbbw wbbw ww ww ",
+" bb bb ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/share/kpacman/pics/fruit.xpm b/share/kpacman/pics/fruit.xpm
new file mode 100644
index 0000000..4d0ea1f
--- a/dev/null
+++ b/share/kpacman/pics/fruit.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char * fruit_small_xpm[] = {
+/* width height num_colors chars_per_pixel */
+"208 16 10 1",
+/* colors */
+" s None c None",
+"x c #000000",
+"r c #ff0000",
+"n c #de9541",
+"u c #41bade",
+"o c #ffba41",
+"y c #ffff00",
+"b c #2020de",
+"g c #00ff00",
+"w c #dedede",
+/* pixels */
+" ",
+" e e ",
+" nn w gg gg n n eeeee eeeee yy yy bbb ",
+" nnnn gggwggg nggggg nggggg rrr n rrr rrr n rrr e e r r yyxxyy yyxxyy bb bb ",
+" nn n rrgggggrr n ggg n ggg rrrrrnrrrrr rrrrrnrrrrr gbg gbg b rrr b b rrr b yyyyyyyy yyyyyyyy bbbbbbb ",
+" n n rrrrrgrrrwr oonnnooo oonnnooo rrrrrrrrrrrr rrrrrrrrrrrr gggyggg gggyggg b rrrrr b b rrrrr b yyxyyyyy yyxyyyyy bbbbbbb ",
+" rrrn n rwrrrrrwrrr oooonooooo oooonooooo rrrrrrrrrrrr rrrrrrrrrrrr gybygggyg gybygggyg byrryryrryb byrryryrryb yxyyyyyy yxyyyyyy bbbbbbb ",
+" rrrnrr n rrrwrwrrrrr oooooooooooo oooooooooooo rrrrrrrrrrrr rrrrrrrrrrrr ggyggbygg ggyggbygg byyyyryyyyb byyyyryyyyb yyxyyyyyyy yyxyyyyyyy y y ",
+" rrrrr rnrr rrrrrrrrwrr oooooooooooo oooooooooooo rrrrrrrrrwrr rrrrrrrrrwrr gbygggygygg gbygggygygg bbyyyyyyybb bbyyyyyyybb yyxyyyyyyy yyxyyyyyyy y yy ",
+" rwrr rrnrrr rwrrwrrrr oooooooooooo oooooooooooo rrrrrrrrrwrr rrrrrrrrrwrr gyggbyggbyg gyggbyggbyg bby y ybb bby y ybb yyyyyyyyyy yyyyyyyyyy y y ",
+" rrwr rrrrrr rrrrrrrrr oooooooooooo oooooooooooo rrrrrrrwrr rrrrrrrwrr gbygggygggg gbygggygggg bb y bb bb y bb yyxyyyyyyyyy yyxyyyyyyyyy y ",
+" rrr rwrrrr rrwrrw oooooooooo oooooooooo rrrrrrrrrr rrrrrrrrrr ggybybygg ggybybygg b y b b y b yyxyyyyyyyyy yyxyyyyyyyyy y y ",
+" rrwrrr rrrrr oooooooooo oooooooooo rrrrrrrr rrrrrrrr gggygggyg gggygggyg y y yyyyyyyyyyyy yyyyyyyyyyyy y yy ",
+" rrrr r oooooo oooooo rr rrr rr rrr gygggyg gygggyg y y yeeeeewweeey yeeeeewweeey y y ",
+" ggy ggy eeeeewweee eeeeewweee y ",
+" "};
diff --git a/share/kpacman/pics/left.xpm b/share/kpacman/pics/left.xpm
new file mode 100644
index 0000000..8d39ed6
--- a/dev/null
+++ b/share/kpacman/pics/left.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * l_xpm[] = {
+/* width height num_colors chars_per_pixel */
+"20 20 3 1",
+/* colors */
+" s None c None",
+". c #000000",
+"X c #008080",
+/* pixels */
+" ",
+" ",
+" ",
+" .. ",
+" ..X. ",
+" ..XXX. ",
+" ..XXXXX. ",
+" ..XXXXXXX. ",
+" ..XXXXXXXXX. ",
+" ..XXXXXXXXXXX. ",
+" ..XXXXXXXXXXX. ",
+" ..XXXXXXXXX. ",
+" ..XXXXXXX. ",
+" ..XXXXX. ",
+" ..XXX. ",
+" ..X. ",
+" .. ",
+" ",
+" ",
+" "};
diff --git a/share/kpacman/pics/lifes.xpm b/share/kpacman/pics/lifes.xpm
new file mode 100644
index 0000000..0248284
--- a/dev/null
+++ b/share/kpacman/pics/lifes.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static char * lifes_xpm[] = {
+"16 16 2 1",
+" s None c None",
+"y c #ffff00",
+" ",
+" ",
+" yyyyy ",
+" yyyyyyy ",
+" yyyyyyyyy ",
+" yyyyyyyy ",
+" yyyyyy ",
+" yyyy ",
+" yyyyyy ",
+" yyyyyyyy ",
+" yyyyyyyyy ",
+" yyyyyyy ",
+" yyyyy ",
+" ",
+" ",
+" "};
diff --git a/share/kpacman/pics/monster.xpm b/share/kpacman/pics/monster.xpm
new file mode 100644
index 0000000..911a950
--- a/dev/null
+++ b/share/kpacman/pics/monster.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char * monster_xpm[] = {
+"320 16 8 1",
+/* colors */
+" s None c None",
+"r c #ff0000",
+"p c #ffbade",
+"c c #00ffde",
+"o c #ffba41",
+"b c #2020de",
+"f c #ffba94",
+"w c #dedede",
+" ",
+" rrrr rrrr pppp pppp cccc cccc oooo oooo rrrr rrrr rrrr rrrr rrrr rrrr rrrr rrrr bbbb bbbb wwww wwww ",
+" rrrrrrrr rrrrrrrr pppppppp pppppppp cccccccc cccccccc oooooooo oooooooo rrrrrrrr rrrrrrrr rrrrrrrr rrrrrrrr rrrrrrrr rrrrrrrr rrrrrrrr rrrrrrrr bbbbbbbb bbbbbbbb wwwwwwww wwwwwwww ",
+" rrrrrrrrrr rrrrrrrrrr pppppppppp pppppppppp cccccccccc cccccccccc oooooooooo oooooooooo rrrrrrrrrr rrrrrrrrrr rrrrrrrrrr rrrrrrrrrr rrrrrrrrrr rrrrrrrrrr rrrrrrrrrr rrrrrrrrrr bbbbbbbbbb bbbbbbbbbb wwwwwwwwww wwwwwwwwww ",
+" rrrrrrrrrrrr rrrrrrrrrrrr pppppppppppp pppppppppppp cccccccccccc cccccccccccc oooooooooooo oooooooooooo rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr bbbbbbbbbbbb bbbbbbbbbbbb wwwwwwwwwwww wwwwwwwwwwww ",
+" rrrrrrrrrrrr rrrrrrrrrrrr pppppppppppp pppppppppppp cccccccccccc cccccccccccc oooooooooooo oooooooooooo rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr bbbbbbbbbbbb bbbbbbbbbbbb wwwwwwwwwwww wwwwwwwwwwww ",
+" rrrrrrrrrrrr rrrrrrrrrrrr pppppppppppp pppppppppppp cccccccccccc cccccccccccc oooooooooooo oooooooooooo rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr rrrrrrrrrrrr bbbffbbffbbb bbbffbbffbbb wwwrrwwrrwww wwwrrwwrrwww ",
+" rrrrrrrrrrrrrr rrrrrrrrrrrrrr pppppppppppppp pppppppppppppp cccccccccccccc cccccccccccccc oooooooooooooo oooooooooooooo rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr bbbbffbbffbbbb bbbbffbbffbbbb wwwwrrwwrrwwww wwwwrrwwrrwwww ",
+" rrrrrrrrrrrrrr rrrrrrrrrrrrrr pppppppppppppp pppppppppppppp cccccccccccccc cccccccccccccc oooooooooooooo oooooooooooooo rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr bbbbbbbbbbbbbb bbbbbbbbbbbbbb wwwwwwwwwwwwww wwwwwwwwwwwwww ",
+" rrrrrrrrrrrrrr rrrrrrrrrrrrrr pppppppppppppp pppppppppppppp cccccccccccccc cccccccccccccc oooooooooooooo oooooooooooooo rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr bbbbbbbbbbbbbb bbbbbbbbbbbbbb wwwwwwwwwwwwww wwwwwwwwwwwwww ",
+" rrrrrrrrrrrrrr rrrrrrrrrrrrrr pppppppppppppp pppppppppppppp cccccccccccccc cccccccccccccc oooooooooooooo oooooooooooooo rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr bbffbbffbbffbb bbffbbffbbffbb wwrrwwrrwwrrww wwrrwwrrwwrrww ",
+" rrrrrrrrrrrrrr rrrrrrrrrrrrrr pppppppppppppp pppppppppppppp cccccccccccccc cccccccccccccc oooooooooooooo oooooooooooooo rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr bfbbffbbffbbfb bfbbffbbffbbfb wrwwrrwwrrwwrw wrwwrrwwrrwwrw ",
+" rrrrrrrrrrrrrr rrrrrrrrrrrrrr pppppppppppppp pppppppppppppp cccccccccccccc cccccccccccccc oooooooooooooo oooooooooooooo rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr rrrrrrrrrrrrrr bbbbbbbbbbbbbb bbbbbbbbbbbbbb wwwwwwwwwwwwww wwwwwwwwwwwwww ",
+" rr rrr rrr rr rrrr rrrr rrrr pp ppp ppp pp pppp pppp pppp cc ccc ccc cc cccc cccc cccc oo ooo ooo oo oooo oooo oooo rr rrr rrr rr rrrr rrrr rrrr rr rrr rrr rr rrrr rrrr rrrr rr rrr rrr rr rrrr rrrr rrrr rr rrr rrr rr rrrr rrrr rrrr bb bbb bbb bb bbbb bbbb bbbb ww www www ww wwww wwww wwww ",
+" r rr rr r rr rr rr p pp pp p pp pp pp c cc cc c cc cc cc o oo oo o oo oo oo r rr rr r rr rr rr r rr rr r rr rr rr r rr rr r rr rr rr r rr rr r rr rr rr b bb bb b bb bb bb w ww ww w ww ww ww ",
+" "};
diff --git a/share/kpacman/pics/pacman.xpm b/share/kpacman/pics/pacman.xpm
new file mode 100644
index 0000000..2aa037b
--- a/dev/null
+++ b/share/kpacman/pics/pacman.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static char * pacman_xpm[] = {
+"192 16 2 1",
+" s None c None",
+"y c #ffff00",
+" ",
+" yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy ",
+" yyyyyyyyy yy yy yyyyyyyyy yyyyyyyyy yyyyyyy yyyyy yyyyy yyyyy yyyyyyyyy yyyyyyyyy yyyyyyy ",
+" yyyyyyyyyyy yyy yyy yyyyyyyyyyy yyyyyyyyyyy yyyyyyy yyyyyyyyy yyyyyyyyy yyyyyyyyy yyyyyyyyyyy yyyyyyyyyyy yyyyyyy ",
+" yyyyyyyyyyy yyyy yyyy yyyyyyyyyyy yyyyyyyyyyy yyyyyy yyyyyyyyyyy yyyyyyyyyyy yyyyyyyyyyy yyyyyyyyyyy yyyyyyyyyyy yyyyyy ",
+" yyyyyyyyyyyyy yyyyy yyyyy yy yy yyyyyyyyyyyyy yyyyyyyyyy yyyyyy yyyyyyyyyyy yyyyyyyyyyy yyyyyyyyyyy yyyyyyyyyyyyy yyyyyyyyyy yyyyyy ",
+" yyyyyyyyyyyyy yyyyy yyyyy yyy yyy yyyyyyyyyyyyy yyyyyyy yyyyy yyyyyyyyyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyyyyyyyyy yyyyyyy yyyyy ",
+" yyyyyyyyyyyyy yyyyyy yyyyyy yyyy yyyy yyyyyyyyyyyyy yyyy yyyy yyyyyyyyyyyyy yyyyyy yyyyyy yyyyy yyyyy yyyyyyyyyyyyy yyyy yyyy ",
+" yyyyyyyyyyyyy yyyyyy yyyyyy yyyyy yyyyy yyyyyyyyyyyyy yyyyyyy yyyyy yyyyyyyyyyyyy yyyyyy yyyyyy yyyy yyyy yyyyyyyyyyyyy yyyyyyy yyyyy ",
+" yyyyyyyyyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyyyyyyyyy yyyyyyyyyy yyyyyy yyyyyyyyyyyyy yyyyy yyyyy yyy yyy yyyyyyyyyyyyy yyyyyyyyyy yyyyyy ",
+" yyyyyyyyyyy yyyyyyyyyyy yyyyyyyyyyy yyyyyyyyyyy yyyyyyyyyyy yyyyyy yyyyyyyyyyyyy yyyyy yyyyy yy yy yyyyyyyyyyy yyyyyyyyyyy yyyyyy ",
+" yyyyyyyyyyy yyyyyyyyyyy yyyyyyyyyyy yyyyyyyyyyy yyyyyyyyyyy yyyyyyy yyyyyyyyyyy yyyy yyyy yyyyyyyyyyy yyyyyyyyyyy yyyyyyy ",
+" yyyyyyyyy yyyyyyyyy yyyyyyyyy yyyyyyyyy yyyyyyyyy yyyyyyy yyyyyyyyyyy yyy yyy yyyyyyyyy yyyyyyyyy yyyyyyy ",
+" yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyyyyyy yy yy yyyyy yyyyy yyyyy ",
+" yyyyy ",
+" "};
diff --git a/share/kpacman/pics/point.xpm b/share/kpacman/pics/point.xpm
new file mode 100644
index 0000000..36c3c9e
--- a/dev/null
+++ b/share/kpacman/pics/point.xpm
@@ -0,0 +1,9 @@
+/* XPM */
+static char * point_xpm[] = {
+"4 4 2 1",
+" c None",
+"f c #ffba94",
+" ",
+" ff ",
+" ff ",
+" "};
diff --git a/share/kpacman/pics/prison.xpm b/share/kpacman/pics/prison.xpm
new file mode 100644
index 0000000..38cbb58
--- a/dev/null
+++ b/share/kpacman/pics/prison.xpm
@@ -0,0 +1,10 @@
+/* XPM */
+static char * prison_xpm[] = {
+"72 4 3 1",
+" s None c None",
+"p c #ffbade",
+"b c #2020de",
+" b b b b b b ppb bpp pppp",
+" b b bbbb bbbb bbbbbb b b bbbb ",
+" b b bbbb bbbb b b bbbbbb bbbb ",
+" b b b b b b ppb bpp pppp "};
diff --git a/share/kpacman/pics/right.xpm b/share/kpacman/pics/right.xpm
new file mode 100644
index 0000000..d36e84a
--- a/dev/null
+++ b/share/kpacman/pics/right.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * r_xpm[] = {
+/* width height num_colors chars_per_pixel */
+"20 20 3 1",
+/* colors */
+" s None c None",
+". c #000000",
+"X c #008080",
+/* pixels */
+" ",
+" ",
+" ",
+" .. ",
+" .X.. ",
+" .XXX.. ",
+" .XXXXX.. ",
+" .XXXXXXX.. ",
+" .XXXXXXXXX.. ",
+" .XXXXXXXXXXX.. ",
+" .XXXXXXXXXXX.. ",
+" .XXXXXXXXX.. ",
+" .XXXXXXX.. ",
+" .XXXXX.. ",
+" .XXX.. ",
+" .X.. ",
+" .. ",
+" ",
+" ",
+" "};
diff --git a/share/kpacman/pics/switch.xpm b/share/kpacman/pics/switch.xpm
new file mode 100644
index 0000000..fbc7a69
--- a/dev/null
+++ b/share/kpacman/pics/switch.xpm
@@ -0,0 +1,13 @@
+/* XPM */
+static char * switch_xpm[] = {
+"16 8 2 1",
+" s None c None",
+"f c #ffba94",
+" ffff ",
+" ffffff ",
+"ffffffff ",
+"ffffffff ",
+"ffffffff ",
+"ffffffff ",
+" ffffff ",
+" ffff "};
diff --git a/share/kpacman/pics/up.xpm b/share/kpacman/pics/up.xpm
new file mode 100644
index 0000000..28974c3
--- a/dev/null
+++ b/share/kpacman/pics/up.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * u_xpm[] = {
+/* width height num_colors chars_per_pixel */
+"20 20 3 1",
+/* colors */
+" s None c None",
+". c #000000",
+"X c #008080",
+/* pixels */
+" ",
+" ",
+" ",
+" .. ",
+" .. ",
+" .XX. ",
+" .XX. ",
+" .XXXX. ",
+" .XXXX. ",
+" .XXXXXX. ",
+" .XXXXXX. ",
+" .XXXXXXXX. ",
+" .XXXXXXXX. ",
+" .XXXXXXXXXX. ",
+" .XXXXXXXXXX. ",
+" .XXXXXXXXXXXX. ",
+" .............. ",
+" ",
+" ",
+" "};
diff --git a/share/kpacman/pics/wall.xpm b/share/kpacman/pics/wall.xpm
new file mode 100644
index 0000000..7cd0ffb
--- a/dev/null
+++ b/share/kpacman/pics/wall.xpm
@@ -0,0 +1,9 @@
+/* XPM */
+static char * wall_xpm[] = {
+"112 4 2 1",
+" s None c None",
+"b c #2020de",
+" b b bb b b bb b b bb bb b b ",
+" b b bbbb bb b b bb b b bbbb bb b b bb bbbb ",
+" b b bbbb b b bb b b bb bbbb b bbbb b bb bb ",
+" b b bb b b b b bb bb bb b b "};