summaryrefslogtreecommitdiffstats
path: root/tdepacman
diff options
context:
space:
mode:
Diffstat (limited to 'tdepacman')
-rw-r--r--tdepacman/CMakeL10n.txt8
-rw-r--r--tdepacman/CMakeLists.txt63
-rw-r--r--tdepacman/bitfont.cpp71
-rw-r--r--tdepacman/bitfont.h30
-rw-r--r--tdepacman/bitmaps.h67
-rw-r--r--tdepacman/board.cpp421
-rw-r--r--tdepacman/board.h102
-rw-r--r--tdepacman/colors.h21
-rw-r--r--tdepacman/energizer.cpp61
-rw-r--r--tdepacman/energizer.h30
-rw-r--r--tdepacman/fruit.cpp176
-rw-r--r--tdepacman/fruit.h53
-rw-r--r--tdepacman/hi16-app-tdepacman.pngbin0 -> 325 bytes
-rw-r--r--tdepacman/hi32-app-tdepacman.pngbin0 -> 535 bytes
-rw-r--r--tdepacman/keys.cpp192
-rw-r--r--tdepacman/keys.h44
-rw-r--r--tdepacman/lo16-app-tdepacman.pngbin0 -> 325 bytes
-rw-r--r--tdepacman/lo32-app-tdepacman.pngbin0 -> 535 bytes
-rw-r--r--tdepacman/main.cpp56
-rw-r--r--tdepacman/monster.cpp262
-rw-r--r--tdepacman/monster.h62
-rw-r--r--tdepacman/pacman.cpp147
-rw-r--r--tdepacman/pacman.h47
-rw-r--r--tdepacman/painter.cpp955
-rw-r--r--tdepacman/painter.h144
-rw-r--r--tdepacman/referee.cpp1393
-rw-r--r--tdepacman/referee.h191
-rw-r--r--tdepacman/score.cpp628
-rw-r--r--tdepacman/score.h124
-rw-r--r--tdepacman/status.cpp353
-rw-r--r--tdepacman/status.h74
-rw-r--r--tdepacman/tdepacman.cpp476
-rw-r--r--tdepacman/tdepacman.desktop16
-rw-r--r--tdepacman/tdepacman.h185
-rw-r--r--tdepacman/tdepacmanrc70
-rw-r--r--tdepacman/tdepacmanui.rc18
-rw-r--r--tdepacman/tdepacmanview.cpp163
-rw-r--r--tdepacman/tdepacmanview.h68
38 files changed, 6771 insertions, 0 deletions
diff --git a/tdepacman/CMakeL10n.txt b/tdepacman/CMakeL10n.txt
new file mode 100644
index 0000000..3e90f50
--- /dev/null
+++ b/tdepacman/CMakeL10n.txt
@@ -0,0 +1,8 @@
+##### create translation templates ##############
+
+tde_l10n_create_template( "messages/tdepacman" )
+
+tde_l10n_create_template(
+ CATALOG "desktop_files/tdepacman.desktop/"
+ SOURCES tdepacman.desktop
+)
diff --git a/tdepacman/CMakeLists.txt b/tdepacman/CMakeLists.txt
new file mode 100644
index 0000000..f01bedd
--- /dev/null
+++ b/tdepacman/CMakeLists.txt
@@ -0,0 +1,63 @@
+include_directories(
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+ ${TDEGAMES_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+ ${TDE_LIB_DIR}
+ ${TDEGAMES_LIBRARY_DIRS}
+)
+
+
+##### tdepacman (executable)
+
+tde_add_executable( ${PROJECT_NAME} AUTOMOC
+
+ SOURCES
+ tdepacmanview.cpp
+ referee.cpp
+ status.cpp
+ painter.cpp
+ score.cpp
+ pacman.cpp
+ monster.cpp
+ keys.cpp
+ fruit.cpp
+ energizer.cpp
+ board.cpp
+ bitfont.cpp
+ tdepacman.cpp
+ main.cpp
+ LINK
+ tdeui-shared
+ tdecore-shared
+ ${TDEGAMES_LIBRARIES}
+
+ DESTINATION ${BIN_INSTALL_DIR}
+)
+
+
+##### other data
+
+install(
+ FILES tdepacmanui.rc
+ DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}
+)
+
+install(
+ FILES tdepacmanrc
+ DESTINATION ${CONFIG_INSTALL_DIR}
+)
+
+
+tde_create_translated_desktop( ${PROJECT_NAME}.desktop )
+
+
+##### icons
+
+tde_install_icons( ${PROJECT_NAME} )
diff --git a/tdepacman/bitfont.cpp b/tdepacman/bitfont.cpp
new file mode 100644
index 0000000..f1535fb
--- /dev/null
+++ b/tdepacman/bitfont.cpp
@@ -0,0 +1,71 @@
+#include "bitfont.h"
+
+Bitfont::Bitfont(TQString 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;
+ }
+}
+
+TQRect Bitfont::rect(TQString str)
+{
+ return TQRect(0, 0, str.length()*fontWidth, fontHeight);
+}
+
+TQPixmap Bitfont::text(TQString str, TQColor fg, TQColor bg)
+{
+ TQPixmap FG(str.length()*fontWidth, fontHeight);
+ TQBitmap MASK(str.length()*fontWidth, fontHeight, TRUE);
+
+ const uchar *s = reinterpret_cast<const unsigned char *>(str.latin1());
+ 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()) {
+ TQPixmap 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/tdepacman/bitfont.h b/tdepacman/bitfont.h
new file mode 100644
index 0000000..029383e
--- /dev/null
+++ b/tdepacman/bitfont.h
@@ -0,0 +1,30 @@
+#ifndef BITFONT_H
+#define BITFONT_H
+
+#include <tqstring.h>
+#include <tqbitmap.h>
+#include <tqpixmap.h>
+#include <tqrect.h>
+
+#include "colors.h"
+
+class Bitfont
+{
+public:
+ Bitfont(TQString fontname, uchar firstChar, uchar lastChar);
+
+ TQPixmap text(TQString str, TQColor fg = BLACK, TQColor bg = TQColor());
+ TQRect rect(TQString str);
+ int width();
+ int height();
+ uchar firstChar();
+ uchar lastChar();
+private:
+ TQBitmap font;
+ int fontWidth;
+ int fontHeight;
+ uchar fontFirstChar;
+ uchar fontLastChar;
+};
+
+#endif // BITFONT_H
diff --git a/tdepacman/bitmaps.h b/tdepacman/bitmaps.h
new file mode 100644
index 0000000..f430384
--- /dev/null
+++ b/tdepacman/bitmaps.h
@@ -0,0 +1,67 @@
+static unsigned char demo_bits[] = {
+ "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+ "++*******************************************************++"
+ "+*********************************************************+"
+ "+** *** **+"
+ "+** . . . . . . . . . . . . *** . . . . . . . . . . . . **+"
+ "+** *** **+"
+ "+** . ******* . ********* . *** . ********* . ******* . **+"
+ "+** ******* ********* *** ********* ******* **+"
+ "+** o ******* . ********* . *** . ********* . ******* o **+"
+ "+** ******* ********* *** ********* ******* **+"
+ "+** . ******* . ********* . *** . ********* . ******* . **+"
+ "+** **+"
+ "+** . . . . . . . . . . . . . . . . . . . . . . . . . . **+"
+ "+** **+"
+ "+** . ******* . *** . *************** . *** . ******* . **+"
+ "+** ******* *** *************** *** ******* **+"
+ "+** . ******* . *** . *************** . *** . ******* . **+"
+ "+** *** *** *** **+"
+ "+** . . . . . . *** . . . . *** . . . . *** . . . . . . **+"
+ "+** *** *** *** **+"
+ "+************ . ********* *** ********* . ************+"
+ "++*********** ********* *** ********* ***********++"
+ "+++++++++++** . ********* *** ********* . **+++++++++++"
+ "+++++++++++** *** *** **+++++++++++"
+ "+++++++++++** . *** 0 *** . **+++++++++++"
+ "+++++++++++** *** *** **+++++++++++"
+ "+++++++++++** . *** ######---###### *** . **+++++++++++"
+ "+************ *** ######---###### *** ************+"
+ "+************ . *** ## ## *** . ************+"
+ " ## ## "
+ " . ## 2 1 3 ## . "
+ " ## ## "
+ "+************ . *** ## ## *** . ************+"
+ "+************ *** ############### *** ************+"
+ "+++++++++++** . *** ############### *** . **+++++++++++"
+ "+++++++++++** *** *** **+++++++++++"
+ "+++++++++++** . *** F *** . **+++++++++++"
+ "+++++++++++** *** *** **+++++++++++"
+ "+++++++++++** . *** *************** *** . **+++++++++++"
+ "++*********** *** *************** *** ***********++"
+ "+************ . *** *************** *** . ************+"
+ "+** *** **+"
+ "+** . . . . . . . . . . . . *** . . . . . . . . . . . . **+"
+ "+** *** **+"
+ "+** . ******* . ********* . *** . ********* . ******* . **+"
+ "+** ******* ********* *** ********* ******* **+"
+ "+** . ******* . ********* . *** . ********* . ******* . **+"
+ "+** *** *** **+"
+ "+** o . . *** . . . . . . . P . . . . . . . *** . . o **+"
+ "+** *** *** **+"
+ "+****** . *** . *** . *************** . *** . *** . ******+"
+ "+****** *** *** *************** *** *** ******+"
+ "+****** . *** . *** . *************** . *** . *** . ******+"
+ "+** *** *** *** **+"
+ "+** . . . . . . *** . . . . *** . . . . *** . . . . . . **+"
+ "+** *** *** *** **+"
+ "+** . ******************* . *** . ******************* . **+"
+ "+** ******************* *** ******************* **+"
+ "+** . ******************* . *** . ******************* . **+"
+ "+** **+"
+ "+** . . . . . . . . . . . . . . . . . . . . . . . . . . **+"
+ "+** **+"
+ "+*********************************************************+"
+ "++*******************************************************++"
+ "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
+};
diff --git a/tdepacman/board.cpp b/tdepacman/board.cpp
new file mode 100644
index 0000000..621a086
--- /dev/null
+++ b/tdepacman/board.cpp
@@ -0,0 +1,421 @@
+#include <kapp.h>
+
+#include <tdelocale.h>
+
+#include <tqrect.h>
+#include <tqregexp.h>
+#include <tqmessagebox.h>
+#include <tqfile.h>
+#include <tqtextstream.h>
+
+#include "board.h"
+#include "bitmaps.h"
+
+Board::Board(int size) : TQMemArray<int> (size)
+{
+ sz = size; // set size of board
+
+ map = "";
+ mapName = ""; // no map loaded so far
+
+ init(None); // initialize varibales
+}
+
+void Board::init(Image image, TQString 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 {
+ TQFile levelFile(levelName);
+ if (!levelFile.open(IO_ReadOnly)) {
+
+ TQString 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(TQRegExp("@LEVELNAME@"), levelName);
+ // TQMessageBox::information(0, i18n("Initialization Error"), msg);
+ printf("%s\n", msg.local8Bit().data());
+ } else {
+ map.fill(' ', BoardHeight*BoardWidth);
+ int height = 0;
+
+ TQTextStream levelStream(&levelFile);
+ while (!levelStream.eof() && height < BoardHeight) {
+ TQString line = levelStream.readLine();
+
+ if (line.find(TQRegExp("^ *;")) == -1) {
+
+ line.replace(TQRegExp(";.*"), ""); // strip off comments
+ line.replace(TQRegExp("\" *$"), ""); // strip off trailing "
+ line.replace(TQRegExp("^ *\""), ""); // strip off leading "
+
+ map.replace(height*BoardWidth,
+ (line.length() > BoardWidth) ? BoardWidth : line.length(),
+ line.latin1());
+
+ 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(reinterpret_cast<const unsigned char *>(map.latin1()));
+ 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/tdepacman/board.h b/tdepacman/board.h
new file mode 100644
index 0000000..3b56973
--- /dev/null
+++ b/tdepacman/board.h
@@ -0,0 +1,102 @@
+#ifndef BOARD_H
+#define BOARD_H
+
+#include <tqmemarray.h>
+#include <tqstring.h>
+#include <tqptrlist.h>
+#include <tqrect.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 TQMemArray<int>
+{
+public:
+ Board (int size);
+ ~Board() {};
+ void init(Image image, TQString 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
+
+ TQString map;
+ TQString 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/tdepacman/colors.h b/tdepacman/colors.h
new file mode 100644
index 0000000..33beae2
--- /dev/null
+++ b/tdepacman/colors.h
@@ -0,0 +1,21 @@
+#ifndef COLORS_H
+#define COLORS_H
+
+#include <tqcolor.h>
+
+#define BLACK TQColor(TQt::black)
+#define RED TQColor(TQt::red)
+#define BROWN TQColor(0xde, 0x95, 0x41)
+#define PINK TQColor(0xff, 0xba, 0xde)
+#define CYAN TQColor(0x00, 0xff, 0xde)
+#define LIGHTBLUE TQColor(0x41, 0xba, 0xde)
+#define ORANGE TQColor(0xff, 0xba, 0x41)
+#define YELLOW TQColor(TQt::yellow)
+#define BLUE TQColor(0x20, 0x20, 0xde)
+#define GREEN TQColor(TQt::green)
+#define LIGHTGREEN TQColor(0x41, 0xba, 0x94)
+#define FLESH TQColor(0xff, 0xba, 0x94)
+#define WHITE TQColor(0xd8, 0xdc, 0xd8)
+
+#endif // COLORS_H
+
diff --git a/tdepacman/energizer.cpp b/tdepacman/energizer.cpp
new file mode 100644
index 0000000..ca08f3b
--- /dev/null
+++ b/tdepacman/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/tdepacman/energizer.h b/tdepacman/energizer.h
new file mode 100644
index 0000000..377cd02
--- /dev/null
+++ b/tdepacman/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/tdepacman/fruit.cpp b/tdepacman/fruit.cpp
new file mode 100644
index 0000000..e6ad2d5
--- /dev/null
+++ b/tdepacman/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/tdepacman/fruit.h b/tdepacman/fruit.h
new file mode 100644
index 0000000..fbbd9c0
--- /dev/null
+++ b/tdepacman/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/tdepacman/hi16-app-tdepacman.png b/tdepacman/hi16-app-tdepacman.png
new file mode 100644
index 0000000..7dc8172
--- /dev/null
+++ b/tdepacman/hi16-app-tdepacman.png
Binary files differ
diff --git a/tdepacman/hi32-app-tdepacman.png b/tdepacman/hi32-app-tdepacman.png
new file mode 100644
index 0000000..2c2d2e6
--- /dev/null
+++ b/tdepacman/hi32-app-tdepacman.png
Binary files differ
diff --git a/tdepacman/keys.cpp b/tdepacman/keys.cpp
new file mode 100644
index 0000000..df8f980
--- /dev/null
+++ b/tdepacman/keys.cpp
@@ -0,0 +1,192 @@
+#include <kapp.h>
+#include <kstddirs.h>
+
+#include <tdeconfig.h>
+#include <tdelocale.h>
+#include <tdeaccel.h>
+#include <tqpushbt.h>
+#include <tqlabel.h>
+#include <tqframe.h>
+#include <tqkeycode.h>
+#include <tqpixmap.h>
+#include <tqstring.h>
+
+#include "keys.h"
+
+PKeys::PKeys( TQWidget *parent, const char *name)
+ : TQDialog( parent, name, TRUE, 0 )
+{
+ TDEStandardDirs *dirs = TDEGlobal::dirs();
+
+ TQPushButton *okButton = new TQPushButton(this);
+ okButton->setText(i18n("Ok"));
+ okButton->setFixedSize(okButton->size());
+ connect( okButton, SIGNAL(clicked()),this, SLOT(ok()) );
+ okButton->move(20,210);
+
+ TQPushButton *defaultButton = new TQPushButton(this);
+ defaultButton->setText(i18n("Defaults"));
+ defaultButton->setFixedSize(defaultButton->size());
+ connect( defaultButton, SIGNAL(clicked()),this, SLOT(defaults()) );
+ defaultButton->move(140,210);
+
+ TQPushButton *cancelButton = new TQPushButton(this);
+ cancelButton->setText(i18n("Cancel"));
+ cancelButton->setFixedSize(cancelButton->size());
+ connect( cancelButton, SIGNAL(clicked()),this, SLOT(reject()) );
+ cancelButton->move(260,210);
+
+ TQFrame *separator = new TQFrame(this);
+ separator->setFrameStyle( TQFrame::HLine | TQFrame::Sunken );
+ separator->setGeometry( 20, 190, 340, 4 );
+
+ for ( int x = 0; x < 4; x++) {
+ TQLabel *l = new TQLabel(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 );
+
+ TQString pixPath;
+
+ TQPushButton *up = new TQPushButton(this);
+ pixPath = dirs->findResource("appdata", "pics/up.xpm");
+ up->setPixmap( TQPixmap(pixPath));
+ up->setFixedSize(up->pixmap()->size());
+ connect( up, SIGNAL(clicked()),this, SLOT(butUp()) );
+ up->move(180, 50);
+
+ TQPushButton *down = new TQPushButton(this);
+ pixPath = dirs->findResource("appdata", "pics/down.xpm");
+ down->setPixmap( TQPixmap(pixPath));
+ down->setFixedSize(down->pixmap()->size());
+ connect( down, SIGNAL(clicked()),this, SLOT(butDown()) );
+ down->move(180, 130);
+
+ TQPushButton *left = new TQPushButton(this);
+ pixPath = dirs->findResource("appdata", "pics/left.xpm");
+ left->setPixmap( TQPixmap(pixPath));
+ left->setFixedSize(left->pixmap()->size());
+ connect( left, SIGNAL(clicked()),this, SLOT(butLeft()) );
+ left->move(140, 90);
+
+ TQPushButton *right = new TQPushButton(this);
+ pixPath = dirs->findResource("appdata", "pics/right.xpm");
+ right->setPixmap( TQPixmap(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 PKeys::keyPressEvent( TQKeyEvent *e )
+{
+ uint kCode = e->key() & ~(SHIFT | CTRL | ALT);
+ TQString string = TDEAccel::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 PKeys::butUp()
+{
+ getKey(0);
+}
+
+void PKeys::butDown()
+{
+ getKey(1);
+}
+
+void PKeys::butLeft()
+{
+ getKey(2);
+}
+
+void PKeys::butRight()
+{
+ getKey(3);
+}
+
+void PKeys::getKey(int i)
+{
+ if ( lab != 0)
+ focusOut(lab);
+
+ focusIn(labels[i]);
+}
+
+void PKeys::focusOut(TQLabel *l)
+{
+ l->setFrameStyle( TQFrame::NoFrame );
+ l->setBackgroundColor(backgroundColor());
+ l->repaint();
+}
+
+void PKeys::focusIn(TQLabel *l)
+{
+ lab = l;
+ lab->setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
+ lab->setBackgroundColor(white);
+ lab->repaint();
+}
+
+void PKeys::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 PKeys::init()
+{
+ TQString up("Up");
+ up = kapp->config()->readEntry("upKey", up);
+ labels[0]->setText(up);
+
+ TQString down("Down");
+ down = kapp->config()->readEntry("downKey", down);
+ labels[1]->setText(down);
+
+ TQString left("Left");
+ left = kapp->config()->readEntry("leftKey", left);
+ labels[2]->setText(left);
+
+ TQString right("Right");
+ right = kapp->config()->readEntry("rightKey", right);
+ labels[3]->setText(right);
+}
+
+void PKeys::ok()
+{
+ kapp->config()->writeEntry("upKey", labels[0]->text() );
+ kapp->config()->writeEntry("downKey", labels[1]->text() );
+ kapp->config()->writeEntry("leftKey", labels[2]->text() );
+ kapp->config()->writeEntry("rightKey", labels[3]->text() );
+ kapp->config()->sync();
+
+ accept();
+}
+
+#include "keys.moc"
diff --git a/tdepacman/keys.h b/tdepacman/keys.h
new file mode 100644
index 0000000..f1c822a
--- /dev/null
+++ b/tdepacman/keys.h
@@ -0,0 +1,44 @@
+#ifndef KEYS_H
+#define KEYS_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <kapp.h>
+
+#include <tqdialog.h>
+#include <tqlabel.h>
+#include <tqstring.h>
+#include <tdeaccel.h>
+
+class PKeys : public TQDialog
+{
+ Q_OBJECT
+public:
+ PKeys( TQWidget *parent=0, const char *name=0 );
+
+private slots:
+ void butRight();
+ void butLeft();
+ void butUp();
+ void butDown();
+
+ void getKey(int);
+ void defaults();
+ void focusIn(TQLabel *);
+ void focusOut(TQLabel *);
+
+ void ok();
+
+protected:
+ void keyPressEvent( TQKeyEvent * );
+
+private:
+ void init();
+
+ TQLabel *labels[4];
+ TQLabel *lab;
+};
+
+#endif // KEYS_H
diff --git a/tdepacman/lo16-app-tdepacman.png b/tdepacman/lo16-app-tdepacman.png
new file mode 100644
index 0000000..7dc8172
--- /dev/null
+++ b/tdepacman/lo16-app-tdepacman.png
Binary files differ
diff --git a/tdepacman/lo32-app-tdepacman.png b/tdepacman/lo32-app-tdepacman.png
new file mode 100644
index 0000000..2c2d2e6
--- /dev/null
+++ b/tdepacman/lo32-app-tdepacman.png
Binary files differ
diff --git a/tdepacman/main.cpp b/tdepacman/main.cpp
new file mode 100644
index 0000000..e80c93e
--- /dev/null
+++ b/tdepacman/main.cpp
@@ -0,0 +1,56 @@
+/***************************************************************************
+ main.cpp - description
+ -------------------
+ begin : Sam Jan 19 13:37:57 CET 2002
+ copyright : (C) 1998-2003 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 <tdecmdlineargs.h>
+#include <tdeaboutdata.h>
+#include <tdelocale.h>
+
+#include "tdepacman.h"
+
+static const char *description =
+ I18N_NOOP("A pacman game for the TDE 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 14 years of her friendship\n"
+ "and Christine Nickel for the 'K' in my life.");
+
+static TDECmdLineOptions options[] =
+{
+ { 0, 0, 0 }
+ // INSERT YOUR COMMANDLINE OPTIONS HERE
+};
+
+int main(int argc, char *argv[])
+{
+
+ TDEAboutData aboutData( "tdepacman", I18N_NOOP("TDEpacman"),
+ VERSION, description, TDEAboutData::License_GPL,
+ "(c) 1998-2003, Jörg Thönnissen", 0, 0, "joe@dsite.de");
+ aboutData.addAuthor("Jörg Thönnissen",0, "joe@dsite.de");
+ TDECmdLineArgs::init( argc, argv, &aboutData );
+ TDECmdLineArgs::addCmdLineOptions( options ); // Add our own options.
+
+ TDEApplication app;
+
+ TDEpacmanApp *tdepacman = new TDEpacmanApp();
+ tdepacman->show();
+
+ return app.exec();
+}
diff --git a/tdepacman/monster.cpp b/tdepacman/monster.cpp
new file mode 100644
index 0000000..2f402b4
--- /dev/null
+++ b/tdepacman/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/tdepacman/monster.h b/tdepacman/monster.h
new file mode 100644
index 0000000..385c513
--- /dev/null
+++ b/tdepacman/monster.h
@@ -0,0 +1,62 @@
+#ifndef MONSTER_H
+#define MONSTER_H
+
+#include <stdlib.h>
+#include <tqpixmap.h>
+#include <tqwidget.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/tdepacman/pacman.cpp b/tdepacman/pacman.cpp
new file mode 100644
index 0000000..40f60a8
--- /dev/null
+++ b/tdepacman/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/tdepacman/pacman.h b/tdepacman/pacman.h
new file mode 100644
index 0000000..6f1a7c1
--- /dev/null
+++ b/tdepacman/pacman.h
@@ -0,0 +1,47 @@
+#ifndef PACMAN_H
+#define PACMAN_H
+
+#include <stdlib.h>
+#include <tqpixmap.h>
+#include <tqwidget.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/tdepacman/painter.cpp b/tdepacman/painter.cpp
new file mode 100644
index 0000000..4c897c8
--- /dev/null
+++ b/tdepacman/painter.cpp
@@ -0,0 +1,955 @@
+#include <kapp.h>
+#include <kstddirs.h>
+
+#include <tdeconfig.h>
+#include <tqcolor.h>
+#include <tqpainter.h>
+#include <tqpixmap.h>
+#include <tqbitmap.h>
+#include <tqrect.h>
+#include <tqstring.h>
+#include <tqmessagebox.h>
+#include <tqfileinfo.h>
+
+#include "painter.h"
+#include "board.h"
+
+Painter::Painter( Board *b, TQWidget *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();
+}
+
+TQPtrList<TQPixmap> *Painter::loadPixmap(TQWidget *parent, TQString pixmapName,
+ TQPtrList<TQPixmap> *pixmaps)
+{
+ if (pixmaps == NULL) {
+ pixmaps = new TQPtrList<TQPixmap>;
+ pixmaps->setAutoDelete(TRUE);
+ }
+
+ if (!pixmaps->isEmpty())
+ pixmaps->clear();
+
+ TQPixmap PIXMAP(pixmapName);
+ if (PIXMAP.isNull() || PIXMAP.mask() == NULL) {
+ TQString 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(TQRegExp("@PIXMAPNAME@"), pixmapName);
+ // TQMessageBox::critical(parent, i18n("Initialization Error"), msg);
+ printf("%s\n", msg.local8Bit().data());
+ return 0;
+ }
+
+ int height = PIXMAP.height();
+ int width = (height == 0) ? 0 : PIXMAP.width()/(PIXMAP.width()/height);
+
+ TQBitmap BITMAP;
+ TQBitmap MASK;
+
+ BITMAP = *PIXMAP.mask();
+ MASK.resize(width, height);
+
+ for (int x = 0; x < PIXMAP.width()/width; x++) {
+ TQPixmap *pixmap = new TQPixmap(width, height);
+ pixmaps->append(pixmap);
+ bitBlt(pixmap, 0, 0, &PIXMAP, x*width, 0, width, height, TQPixmap::CopyROP, TRUE);
+ bitBlt(&MASK, 0, 0, &BITMAP, x*width, 0, width, height, TQPixmap::CopyROP, TRUE);
+ pixmap->setMask(MASK);
+ }
+
+ return pixmaps;
+}
+
+TQPtrList<TQPixmap> *Painter::textPixmap(TQStrList &str, TQPtrList<TQPixmap> *pixmaps,
+ TQColor fg, TQColor bg)
+{
+ if (pixmaps == NULL) {
+ pixmaps = new TQPtrList<TQPixmap>;
+ pixmaps->setAutoDelete(TRUE);
+ }
+
+ if (!pixmaps->isEmpty())
+ pixmaps->clear();
+
+ for (uint s = 0; s < str.count(); s++) {
+ TQPixmap *pixmap = new TQPixmap(bitfont->text(str.at(s), fg, bg));
+ pixmaps->append(pixmap);
+ }
+
+ return pixmaps;
+}
+
+TQPtrList<TQPixmap> *Painter::textPixmap(TQString str, TQPtrList<TQPixmap> *pixmaps,
+ TQColor fg, TQColor bg)
+{
+ if (pixmaps == NULL) {
+ pixmaps = new TQPtrList<TQPixmap>;
+ pixmaps->setAutoDelete(TRUE);
+ }
+
+ if (!pixmaps->isEmpty())
+ pixmaps->clear();
+
+ TQPixmap *pixmap = new TQPixmap(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.
+ */
+TQPoint Painter::point(int pos)
+{
+ return TQPoint((board->x(pos)-1)*BlockWidth, (board->y(pos)-1)*BlockHeight);
+}
+
+
+TQRect Painter::rect(int pos, PixMap pix, uint i)
+{
+ if (pos == OUT)
+ return TQRect();
+
+ TQPixmap *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 TQRect();
+
+ TQRect rect = PIXMAP->rect();
+ TQPoint point = this->point(pos);
+ rect.moveCenter(TQPoint(point.x()-1, point.y()-1));
+
+ return rect;
+}
+
+TQRect Painter::rect(int pos, TQString str, int align)
+{
+ if (pos == OUT) // return an empty rect if the position
+ return TQRect(); // is invalid
+ TQPoint point = this->point(pos);
+ TQRect rect = bitfont->rect(str);
+
+ rect.moveCenter(TQPoint(point.x()-1, point.y()-1));
+
+ int dx = 0;
+ int dy = 0;
+
+ if (align & TQLabel::AlignLeft || align & TQLabel::AlignRight) {
+ dx = (str.length()-1) * (bitfont->width()/2);
+ if (align & TQLabel::AlignRight)
+ dx *= -1;
+ }
+
+ if (align & TQLabel::AlignTop || align & TQLabel::AlignBottom) {
+ dy = bitfont->height()/2;
+ if (align & TQLabel::AlignBottom)
+ dy *= -1;
+ }
+
+ if (dx != 0 || dy != 0)
+ rect.moveBy(dx, dy);
+
+ return rect;
+}
+
+TQRect Painter::rect(TQRect r1, TQRect r2)
+{
+ TQRect 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;
+ TQRect 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(TQPoint point, DrawWidget where, TQPixmap 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(TQRect rect, DrawWidget where, TQPixmap pix)
+{
+ draw(TQPoint(rect.x(), rect.y()), where, pix);
+}
+
+void Painter::draw(int pos, DrawWidget where, PixMap pix, uint i)
+{
+ TQPixmap *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;
+
+ TQRect rect = PIXMAP->rect();
+ TQPoint point = this->point(pos);
+ rect.moveCenter(TQPoint(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;
+ }
+}
+
+TQPixmap Painter::draw(int pos, DrawWidget where,
+ TQString str, TQColor fg, TQColor bg, int align)
+{
+ TQPixmap TEXT = bitfont->text(str, fg, bg);
+
+ TQRect rect = this->rect(pos, str, align);
+ TQPixmap SAVE = TQPixmap(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;
+}
+
+TQRect Painter::draw(int col, int row, DrawWidget where,
+ TQString str, TQColor fg, TQColor bg, int align)
+{
+ TQPixmap TEXT = bitfont->text(str, fg, bg);
+
+ TQRect 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) ||
+ *fruitScorePixmapName.at(level) == '\0') {
+ if (*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) ||
+ *monsterScorePixmapName.at(level) == '\0') {
+ if (*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()) {
+ TQRect 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()) {
+ TQRect rect = this->rect(pos, PrisonPix);
+ bitBlt(&roomPix, rect.x(), rect.y(), prisonPix->at((uint) border));
+ }
+}
+
+void Painter::drawPoint(int pos)
+{
+ if (!pointPix->isEmpty()) {
+ TQRect rect = this->rect(pos, PointPix);
+ bitBlt(&roomPix, rect.x(), rect.y(), pointPix->at(0));
+ }
+}
+
+TQString Painter::decodeHexOctString(TQString s)
+{
+ TQString value;
+ TQString valids;
+ int pos, xpos = 0, opos = 0;
+ int v, len, leadin;
+ const char *ptr;
+ uchar c;
+
+ while (((xpos = s.find(TQRegExp("\\\\x[0-9a-fA-F]+"), xpos)) != -1) ||
+ ((opos = s.find(TQRegExp("\\\\[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 = value.latin1();
+
+ 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(TQStrList &list, TQMemArray<int> &values)
+{
+ if( !list.isEmpty())
+ list.clear();
+
+ TQString 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.latin1());
+ }
+}
+
+void Painter::fillArray(TQMemArray<int> &array, TQString values, int max)
+{
+ array.resize(max);
+ int last = 0;
+ bool ok;
+ TQString 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(TQStrList &list, TQString values, int max)
+{
+ if (!list.isEmpty())
+ list.clear();
+
+ TQString last = "";
+ TQString 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.latin1());
+ }
+}
+
+void Painter::fillPixmapName(TQStrList &pixmapName)
+{
+ TQStrList list = pixmapName;
+
+ if (!pixmapName.isEmpty())
+ pixmapName.clear();
+
+ TQString pixmap;
+
+ TQFileInfo fileInfo;
+
+ for (uint i = 0; i < list.count(); i++) {
+ pixmap = list.at(i);
+
+ if (pixmap.left(1) != "/" && pixmap.left(1) != "~")
+ pixmap = TDEGlobal::dirs()->findResource("appdata", pixmapDirectory+pixmap);
+
+ fileInfo.setFile(pixmap);
+ if (!fileInfo.isReadable() || !fileInfo.isFile())
+ pixmap = "";
+
+ pixmapName.append(pixmap.utf8());
+ }
+}
+
+void Painter::confLevels(bool defGroup)
+{
+ if (defGroup || kapp->config()->hasKey("Levels"))
+ maxLevel = kapp->config()->readNumEntry("Levels", 13);
+}
+
+void Painter::confMisc(bool defGroup)
+{
+ if (defGroup || kapp->config()->hasKey("PixmapDirectory")) {
+ pixmapDirectory = kapp->config()->readEntry("PixmapDirectory");
+
+ if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~")
+ pixmapDirectory.insert(0, "pics/");
+ if (pixmapDirectory.right(1) != "/")
+ pixmapDirectory.append("/");
+ }
+
+ if (defGroup || kapp->config()->hasKey("PointPixmapName"))
+ fillStrList(pointPixmapName,
+ kapp->config()->readEntry("PointPixmapName", "point.xpm"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("WallPixmapName"))
+ fillStrList(wallPixmapName,
+ kapp->config()->readEntry("WallPixmapName", "wall.xpm"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("PrisonPixmapName"))
+ fillStrList(prisonPixmapName,
+ kapp->config()->readEntry("PrisonPixmapName", "prison.xpm"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("EnergizerPixmapName"))
+ fillStrList(energizerPixmapName,
+ kapp->config()->readEntry("EnergizerPixmapName", "switch.xpm"),maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("FruitPixmapName"))
+ fillStrList(fruitPixmapName,
+ kapp->config()->readEntry("FruitPixmapName", "fruit.xpm"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("PacmanPixmapName"))
+ fillStrList(pacmanPixmapName,
+ kapp->config()->readEntry("PacmanPixmapName", "pacman.xpm"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("DyingPixmapName"))
+ fillStrList(dyingPixmapName,
+ kapp->config()->readEntry("DyingPixmapName", "dying.xpm"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("EyesPixmapName"))
+ fillStrList(eyesPixmapName,
+ kapp->config()->readEntry("EyesPixmapName", "eyes.xpm"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("MonsterPixmapName"))
+ fillStrList(monsterPixmapName,
+ kapp->config()->readEntry("MonsterPixmapName", "monster.xpm"), maxLevel+1);
+
+ if (defGroup || kapp->config()->hasKey("FruitScorePixmapName"))
+ fillStrList(fruitScorePixmapName,
+ kapp->config()->readEntry("FruitScorePixmapName"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("MonsterScorePixmapName"))
+ fillStrList(monsterScorePixmapName,
+ kapp->config()->readEntry("MonsterScorePixmapName"), maxLevel+1);
+}
+
+void Painter::confScoring(bool defGroup)
+{
+ if (defGroup || kapp->config()->hasKey("FruitScore"))
+ fillArray(fruitScore,
+ kapp->config()->readEntry("FruitScore",
+ "100,300,500,,700,,1000,,2000,,3000,,5000"),
+ maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("MonsterScore"))
+ fillArray(monsterScore,
+ kapp->config()->readEntry("MonsterScore", "200,400,800,1600"), 4);
+
+ if (defGroup || kapp->config()->hasKey("FruitScoreString"))
+ fillStrList(fruitScoreString,
+ kapp->config()->readEntry("FruitScoreString"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("MonsterScoreString"))
+ fillStrList(monsterScoreString,
+ kapp->config()->readEntry("MonsterScoreString"), 4);
+}
+
+void Painter::confScheme()
+{
+ TQString oldgroup = kapp->config()->group();
+ TQString newgroup;
+
+ // if not set, read mode and scheme from the configfile
+ if (mode == -1 && scheme == -1) {
+ scheme = kapp->config()->readNumEntry("Scheme", -1);
+ mode = kapp->config()->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);
+ kapp->config()->setGroup(newgroup);
+
+ mode = kapp->config()->readNumEntry("Mode", -1);
+ kapp->config()->setGroup(oldgroup);
+ }
+ }
+
+ confLevels();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ kapp->config()->setGroup(newgroup);
+
+ confLevels(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ kapp->config()->setGroup(newgroup);
+
+ confLevels(FALSE);
+ }
+
+ kapp->config()->setGroup(oldgroup);
+
+ confMisc();
+ confScoring();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ kapp->config()->setGroup(newgroup);
+
+ confMisc(FALSE);
+ confScoring(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ kapp->config()->setGroup(newgroup);
+
+ confMisc(FALSE);
+ confScoring(FALSE);
+ }
+
+ if (*fruitScoreString.at(0) == '\0')
+ fillScoreString(fruitScoreString, fruitScore);
+ if (*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();
+
+ kapp->config()->setGroup(oldgroup);
+}
+
+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/tdepacman/painter.h b/tdepacman/painter.h
new file mode 100644
index 0000000..a15c615
--- /dev/null
+++ b/tdepacman/painter.h
@@ -0,0 +1,144 @@
+#ifndef PAINTER_H
+#define PAINTER_H
+
+#include <kapp.h>
+
+#include <tdelocale.h>
+#include <tqpixmap.h>
+#include <tqbitmap.h>
+#include <tqlabel.h>
+#include <tqcolor.h>
+#include <tqptrlist.h>
+#include <tqstrlist.h>
+#include <tqregexp.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 *, TQWidget *parent=0, int scheme=-1, int mode=-1,Bitfont *font=0);
+ TQPixmap levelPix() { return roomPix; }
+
+ void setScheme(int scheme=-1, int mode=-1, Bitfont *font=0);
+ void setLevel(int level=0);
+
+ TQRect rect(int pos, PixMap pix, uint i = 0);
+ TQRect rect(int pos, TQString str, int align = TQLabel::AlignCenter );
+ TQRect rect(TQRect r1, TQRect r2);
+
+ void draw(TQPoint point, DrawWidget where, TQPixmap pix);
+ void draw(TQRect rect, DrawWidget where, TQPixmap pix);
+ void draw(int pos, DrawWidget where, PixMap pix, uint i = 0);
+ TQPixmap draw(int pos, DrawWidget where, TQString str,
+ TQColor fg, TQColor bg = TQColor(), int align = TQLabel::AlignCenter);
+ TQRect draw(int col, int row, DrawWidget where, TQString str,
+ TQColor fg, TQColor bg = TQColor(), int align = TQLabel::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:
+ TQString decodeHexOctString(TQString str);
+
+ void fillScoreString(TQStrList &, TQMemArray<int> &);
+ void fillArray(TQMemArray<int> &, TQString, int);
+ void fillStrList(TQStrList &, TQString, int);
+ void fillPixmapName(TQStrList &);
+
+ void confScheme();
+ void confLevels(bool defGroup=TRUE);
+ void confMisc(bool defGroup=TRUE);
+ void confScoring(bool defGroup=TRUE);
+
+ void initPixmaps();
+ void initRoomPixmap();
+ void initbackPixmaps();
+
+private:
+ TQWidget *w;
+ Board *board;
+ Bitfont *bitfont;
+
+ int BlockWidth;
+ int BlockHeight;
+
+ TQMemArray<int> fruitScore;
+ TQStrList fruitScoreString;
+ TQMemArray<int> monsterScore;
+ TQStrList monsterScoreString;
+
+ TQString pixmapDirectory;
+
+ TQStrList pointPixmapName;
+ TQStrList wallPixmapName;
+ TQStrList prisonPixmapName;
+ TQStrList energizerPixmapName;
+ TQStrList fruitPixmapName;
+ TQStrList pacmanPixmapName;
+ TQStrList dyingPixmapName;
+ TQStrList eyesPixmapName;
+ TQStrList monsterPixmapName;
+ TQStrList fruitScorePixmapName;
+ TQStrList monsterScorePixmapName;
+
+ TQString lastPointPixmapName;
+ TQString lastWallPixmapName;
+ TQString lastPrisonPixmapName;
+ TQString lastEnergizerPixmapName;
+ TQString lastFruitPixmapName;
+ TQString lastPacmanPixmapName;
+ TQString lastDyingPixmapName;
+ TQString lastEyesPixmapName;
+ TQString lastMonsterPixmapName;
+ TQString lastFruitScorePixmapName;
+ TQString lastMonsterScorePixmapName;
+
+ TQPtrList<TQPixmap> *loadPixmap(TQWidget *parent, TQString pixmapName,
+ TQPtrList<TQPixmap> *pixmaps=0);
+ TQPtrList<TQPixmap> *textPixmap(TQStrList &, TQPtrList<TQPixmap> *pixmaps=0,
+ TQColor fg = BLACK, TQColor bg = TQColor());
+ TQPtrList<TQPixmap> *textPixmap(TQString str, TQPtrList<TQPixmap> *pixmaps=0,
+ TQColor fg = BLACK, TQColor bg = TQColor());
+
+ TQPoint point(int pos);
+ int checkRange(int value, int max, int min=0);
+
+ TQPtrList<TQPixmap> *wallPix;
+ TQPtrList<TQPixmap> *prisonPix;
+ TQPtrList<TQPixmap> *pointPix;
+ TQPtrList<TQPixmap> *energizerPix;
+ TQPtrList<TQPixmap> *fruitPix;
+ TQPtrList<TQPixmap> *pacmanPix;
+ TQPtrList<TQPixmap> *dyingPix;
+ TQPtrList<TQPixmap> *eyesPix;
+ TQPtrList<TQPixmap> *monsterPix;
+ TQPtrList<TQPixmap> *fruitScorePix;
+ TQPtrList<TQPixmap> *monsterScorePix;
+
+ TQPixmap roomPix;
+ TQPixmap backPix;
+
+ bool plainColor;
+ TQColor backgroundColor;
+
+ int maxLevel;
+ int level;
+
+ int scheme;
+ int mode;
+};
+
+#endif // PAINTER_H
diff --git a/tdepacman/referee.cpp b/tdepacman/referee.cpp
new file mode 100644
index 0000000..1f4e2bc
--- /dev/null
+++ b/tdepacman/referee.cpp
@@ -0,0 +1,1393 @@
+#include <stdlib.h>
+
+#include <kapp.h>
+#include <kstddirs.h>
+
+#include <tdeconfig.h>
+#include <tqdatetm.h>
+#include <tqtimer.h>
+#include <tqevent.h>
+#include <tqcolor.h>
+#include <tqkeycode.h>
+#include <tqfileinfo.h>
+#include <tdeaccel.h>
+
+#include "referee.h"
+#include "board.h"
+#include "pacman.h"
+#include "monster.h"
+#include "fruit.h"
+#include "painter.h"
+
+Referee::Referee( TQWidget *parent, const char *name, int Scheme, int Mode, Bitfont *font)
+ : TQWidget( parent, name )
+{
+ gameState.resize(12);
+ gameTimer = 0;
+ energizerTimer = 0;
+
+ focusedPause = false;
+ setFocusPolicy(TQWidget::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 TQPtrList<Monster>;
+ monsters->setAutoDelete(TRUE);
+
+ monsterRect = new TQPtrList<TQRect>;
+ monsterRect->setAutoDelete(TRUE);
+
+ energizers = new TQPtrList<Energizer>;
+ energizers->setAutoDelete(TRUE);
+
+ energizerRect = new TQPtrList<TQRect>;
+ energizerRect->setAutoDelete(TRUE);
+
+ pacmanRect.setRect(0, 0, 0, 0);
+ fruitRect.setRect(0, 0, 0, 0);
+
+ TQTime midnight( 0, 0, 0 );
+ srand( midnight.secsTo(TQTime::currentTime()) );
+
+ lifes = 0;
+ points = 0;
+
+ emit setLifes(lifes);
+ emit setPoints(points);
+
+ intro();
+}
+
+void Referee::paintEvent( TQPaintEvent *e)
+{
+ if (gameState.testBit(HallOfFame))
+ return;
+
+ TQRect rect = e->rect();
+
+ if (!rect.isEmpty()) {
+ TQPixmap 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( TQTimerEvent *e )
+{
+ if (gameState.testBit(HallOfFame))
+ return;
+
+ TQRect 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()
+{
+ TQString up("Up");
+ up = kapp->config()->readEntry("upKey", up);
+ UpKey = TDEShortcut(up);
+
+ TQString down("Down");
+ down = kapp->config()->readEntry("downKey", down);
+ DownKey = TDEShortcut(down);
+
+ TQString left("Left");
+ left = kapp->config()->readEntry("leftKey", left);
+ LeftKey = TDEShortcut(left);
+
+ TQString right("Right");
+ right = kapp->config()->readEntry("rightKey", right);
+ RightKey = TDEShortcut(right);
+}
+
+void Referee::fillArray(TQMemArray<int> &array, TQString values, int max)
+{
+ if (max < 0)
+ max = values.contains(',')+1;
+
+ array.resize(max);
+ int last = 0;
+ bool ok;
+ TQString 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(TQStrList &list, TQString values, int max)
+{
+ if (!list.isEmpty())
+ list.clear();
+
+ TQString last = "";
+ TQString 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.latin1());
+ }
+}
+
+void Referee::fillMapName()
+{
+ TQStrList list = mapName;
+
+ if (!mapName.isEmpty())
+ mapName.clear();
+
+ TQString map;
+
+ TQFileInfo fileInfo;
+
+ for (uint i = 0; i < list.count(); i++) {
+ map = list.at(i);
+
+ if (map.left(1) != "/" && map.left(1) != "~")
+ map = TDEGlobal::dirs()->findResource("appdata", mapDirectory+map);
+
+ fileInfo.setFile(map);
+ if (!fileInfo.isReadable())
+ map = "";
+
+ mapName.append(map.utf8());
+ }
+}
+
+void Referee::confLevels(bool defGroup)
+{
+ if (defGroup || kapp->config()->hasKey("Levels"))
+ maxLevel = kapp->config()->readNumEntry("Levels", 13);
+}
+
+void Referee::confMisc(bool defGroup)
+{
+ if (defGroup || kapp->config()->hasKey("PixmapDirectory")) {
+ pixmapDirectory = kapp->config()->readEntry("PixmapDirectory");
+
+ if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~")
+ pixmapDirectory.insert(0, "pics/");
+ if (pixmapDirectory.right(1) != "/")
+ pixmapDirectory.append("/");
+ }
+
+ if (defGroup || kapp->config()->hasKey("MapDirectory")) {
+ mapDirectory = kapp->config()->readEntry("MapDirectory");
+
+ if (mapDirectory.left(1) != "/" && mapDirectory.left(1) != "~")
+ mapDirectory.insert(0, "maps/");
+ if (mapDirectory.right(1) != "/")
+ mapDirectory.append("/");
+ }
+
+ if (defGroup || kapp->config()->hasKey("MapName"))
+ fillStrList(mapName, kapp->config()->readEntry("MapName", "map"), maxLevel+1);
+
+ if (defGroup || kapp->config()->hasKey("MonsterIQ"))
+ fillArray(monsterIQ, kapp->config()->readEntry("MonsterIQ", "0,170,180,170,180,170,180"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("FruitIQ"))
+ fillArray(fruitIQ, kapp->config()->readEntry("FruitIQ", "0,170,180,170,180,170,180"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("FruitIndex"))
+ fillArray(fruitIndex, kapp->config()->readEntry("FruitIndex", "0"), maxLevel+1);
+}
+
+void Referee::confTiming(bool defGroup)
+{
+ if (defGroup || kapp->config()->hasKey("SpeedMS"))
+ fillArray(speed, kapp->config()->readEntry("SpeedMS", "20"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("PacmanTicks"))
+ fillArray(pacmanTicks,kapp->config()->readEntry("PacmanTicks", "3"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("RemTicks"))
+ fillArray(remTicks, kapp->config()->readEntry("RemTicks", "1"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("DangerousTicks"))
+ fillArray(dangerousTicks, kapp->config()->readEntry("DangerousTicks", "3"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("HarmlessTicks"))
+ fillArray(harmlessTicks, kapp->config()->readEntry("HarmlessTicks", "7,6,,5,,4"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("HarmlessDurationTicks"))
+ fillArray(harmlessDurTicks, kapp->config()->readEntry("HarmlessDurationTicks", "375,,,300,,250,200,150"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("HarmlessWarningTicks"))
+ fillArray(harmlessWarnTicks, kapp->config()->readEntry("HarmlessWarningTicks", "135"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("ArrestTicks"))
+ fillArray(arrestTicks, kapp->config()->readEntry("ArrestTicks", "6"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("ArrestDurationTicks"))
+ fillArray(arrestDurTicks, kapp->config()->readEntry("ArrestDurationTicks", "200,,,150"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("FruitTicks"))
+ fillArray(fruitTicks, kapp->config()->readEntry("FruitTicks", "7,6,,5,,4"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("FruitAppearsTicks"))
+ fillArray(fruitAppearsTicks, kapp->config()->readEntry("FruitAppearsTicks", "1000,,1500,2000,2500,3000,3500,4000"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("FruitDurationTicks"))
+ fillArray(fruitDurTicks, kapp->config()->readEntry("FruitDurationTicks", "500,,,400,350,300,,250,200,150"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("FruitScoreDurationTicks"))
+ fillArray(fruitScoreDurTicks, kapp->config()->readEntry("FruitScoreDurationTicks", "150"), maxLevel+1);
+
+ if (defGroup || kapp->config()->hasKey("MonsterScoreDurationMS"))
+ monsterScoreDurMS = kapp->config()->readNumEntry("MonsterScoreDurationMS", 1000);
+ if (defGroup || kapp->config()->hasKey("PlayerDurationMS"))
+ playerDurMS = kapp->config()->readNumEntry("PlayerDurationMS", 3000);
+ if (defGroup || kapp->config()->hasKey("ReadyDurationMS"))
+ readyDurMS = kapp->config()->readNumEntry("ReadyDurationMS", 2000);
+ if (defGroup || kapp->config()->hasKey("GameOverDurationMS"))
+ gameOverDurMS = kapp->config()->readNumEntry("GameOverDurationMS", 3000);
+ if (defGroup || kapp->config()->hasKey("AfterPauseMS"))
+ afterPauseMS = kapp->config()->readNumEntry("AfterPauseMS", 1000);
+ if (defGroup || kapp->config()->hasKey("DyingPreAnimationMS"))
+ dyingPreAnimationMS = kapp->config()->readNumEntry("DyingPreAnimationMS", 1000);
+ if (defGroup || kapp->config()->hasKey("DyingAnimationMS"))
+ dyingAnimationMS = kapp->config()->readNumEntry("DyingAnimationMS", 100);
+ if (defGroup || kapp->config()->hasKey("DyingPostAnimationMS"))
+ dyingPostAnimationMS = kapp->config()->readNumEntry("DyingPostAnimationMS", 500);
+ if (defGroup || kapp->config()->hasKey("IntroAnimationMS"))
+ introAnimationMS = kapp->config()->readNumEntry("IntroAnimationMS", 800);
+ if (defGroup || kapp->config()->hasKey("IntroPostAnimationMS"))
+ introPostAnimationMS = kapp->config()->readNumEntry("IntroPostAnimationMS", 1000);
+ if (defGroup || kapp->config()->hasKey("LevelUpPreAnimationMS"))
+ levelUpPreAnimationMS = kapp->config()->readNumEntry("LevelUpPreAnimationMS", 2000);
+ if (defGroup || kapp->config()->hasKey("LevelUpAnimationMS"))
+ levelUpAnimationMS = kapp->config()->readNumEntry("LevelUpAnimationMS", 2000);
+ if (defGroup || kapp->config()->hasKey("EnergizerAnimationMS"))
+ energizerAnimationMS = kapp->config()->readNumEntry("EnergizerAnimationMS", 200);
+}
+
+void Referee::confScoring(bool defGroup)
+{
+ if (defGroup || kapp->config()->hasKey("PointScore"))
+ pointScore = kapp->config()->readNumEntry("PointScore", 10);
+ if (defGroup || kapp->config()->hasKey("EnergizerScore"))
+ energizerScore = kapp->config()->readNumEntry("EnergizerScore", 50);
+ if (defGroup || kapp->config()->hasKey("FruitScore"))
+ fillArray(fruitScore, kapp->config()->readEntry("FruitScore", "100,300,500,,700,,1000,,2000,,3000,,5000"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("MonsterScore"))
+ fillArray(monsterScore, kapp->config()->readEntry("MonsterScore", "200,400,800,1600"), 4);
+ if (defGroup || kapp->config()->hasKey("ExtraLifeScore"))
+ fillArray(extraLifeScore, kapp->config()->readEntry("ExtraLifeScore", "10000"), -1);
+}
+
+void Referee::confScheme()
+{
+ TQString oldgroup = kapp->config()->group();
+ TQString newgroup;
+
+ // if not set, read mode and scheme from the configfile
+ if (mode == -1 && scheme == -1) {
+ scheme = kapp->config()->readNumEntry("Scheme", -1);
+ mode = kapp->config()->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);
+ kapp->config()->setGroup(newgroup);
+
+ mode = kapp->config()->readNumEntry("Mode", -1);
+ kapp->config()->setGroup(oldgroup);
+ }
+ }
+
+ confLevels();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ kapp->config()->setGroup(newgroup);
+
+ confLevels(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ kapp->config()->setGroup(newgroup);
+
+ confLevels(FALSE);
+ }
+
+ kapp->config()->setGroup(oldgroup);
+
+ confMisc();
+ confTiming();
+ confScoring();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ kapp->config()->setGroup(newgroup);
+
+ confMisc(FALSE);
+ confTiming(FALSE);
+ confScoring(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ kapp->config()->setGroup(newgroup);
+
+ confMisc(FALSE);
+ confTiming(FALSE);
+ confScoring(FALSE);
+ }
+
+ fillMapName();
+
+ kapp->config()->setGroup(oldgroup);
+}
+
+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( TQKeyEvent *k )
+{
+ if (gameState.testBit(Paused) || gameState.testBit(HallOfFame) ||
+ gameState.testBit(Demonstration) || gameState.testBit(Dying) ||
+ gameState.testBit(Ready) || gameState.testBit(LevelDone) ||
+ !gameState.testBit(Playing))
+ return;
+
+ uint key = k->key();
+ 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)
+ TQTimer::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))
+ TQTimer::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 forcedGameHighscores();
+}
+
+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();
+ }
+ // manual pause deactivating (also) deactivates a focusedPause
+ focusedPause = false;
+ }
+ //0.3.2 emit gamePause();
+}
+
+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)
+{
+ TQString pts;
+
+ switch (t) {
+ case 0 : repaint(pix->draw(16, 6, RoomPix, i18n("CHARACTER"), WHITE, TQColor(), AlignLeft), FALSE);
+ repaint(pix->draw(36, 6, RoomPix, i18n("/"), WHITE, TQColor(), AlignLeft), FALSE);
+ repaint(pix->draw(40, 6, RoomPix, i18n("NICKNAME"), WHITE, TQColor(), AlignLeft), FALSE);
+ break;
+ case 1 : introMonster(0);
+ break;
+ case 2 : repaint(pix->draw(16, 10, RoomPix, i18n("-SHADOW"), RED, TQColor(), AlignLeft), FALSE);
+ break;
+ case 3 : repaint(pix->draw(38, 10, RoomPix, i18n("\"BLINKY\""), RED, TQColor(), AlignLeft), FALSE);
+ break;
+ case 4 : introMonster(1);
+ break;
+ case 5 : repaint(pix->draw(16, 16, RoomPix, i18n("-SPEEDY"), PINK, TQColor(), AlignLeft), FALSE);
+ break;
+ case 6 : repaint(pix->draw(38, 16, RoomPix, i18n("\"PINKY\""), PINK, TQColor(), AlignLeft), FALSE);
+ break;
+ case 7 : introMonster(2);
+ break;
+ case 8 : repaint(pix->draw(16, 22, RoomPix, i18n("-BASHFUL"), CYAN, TQColor(), AlignLeft), FALSE);
+ break;
+ case 9 : repaint(pix->draw(38, 22, RoomPix, i18n("\"INKY\""), CYAN, TQColor(), AlignLeft), FALSE);
+ break;
+ case 10 : introMonster(3);
+ break;
+ case 11 : repaint(pix->draw(16, 28, RoomPix, i18n("-POKEY"), ORANGE, TQColor(), AlignLeft), FALSE);
+ break;
+ case 12 : repaint(pix->draw(38, 28, RoomPix, i18n("\"CLYDE\""), ORANGE, TQColor(), AlignLeft), FALSE);
+ break;
+ case 13 : pts.sprintf("%d", pointScore);
+ repaint(pix->draw(28, 44, RoomPix, pts, WHITE, TQColor(), AlignRight), FALSE);
+ repaint(pix->draw(31, 44, RoomPix, "\x1C\x1D\x1E", WHITE, TQColor(), AlignLeft), FALSE);
+ pts.sprintf("%d", energizerScore);
+ repaint(pix->draw(28, 48, RoomPix, pts, WHITE, TQColor(), AlignRight), FALSE);
+ repaint(pix->draw(31, 48, RoomPix, "\x1C\x1D\x1E", WHITE, TQColor(), AlignLeft), FALSE);
+ break;
+ case 14 : // "@ 1980 MIDWAY MFG.CO."
+ repaint(pix->draw(30, 58, RoomPix, "© 1998-2003 J.THÖNNISSEN", PINK), FALSE);
+ break;
+ }
+}
+
+void Referee::introPlay()
+{
+ if (!gameState.testBit(Introducing) || gameState.testBit(Ready))
+ return;
+ if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
+ TQTimer::singleShot(afterPauseMS, this, SLOT(introPlay()));
+ return;
+ }
+
+ if (!gameState.testBit(Init)) {
+ if (monstersEaten == 4) {
+ stop();
+ TQTimer::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)
+ TQTimer::singleShot(introAnimationMS, this, SLOT(introPlay()));
+}
+
+void Referee::demo()
+{
+ if (gameState.testBit(Ready))
+ return;
+
+ if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
+ TQTimer::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;
+ TQTimer::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();
+ //0.3.2 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;
+ TQTimer::singleShot(playerDurMS, this, SLOT(ready()));
+}
+
+void Referee::ready()
+{
+ if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
+ TQTimer::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();
+ TQTimer::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);
+ TQTimer::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;
+ TQTimer::singleShot(levelUpPreAnimationMS, this, SLOT(levelUpPlay()));
+}
+
+void Referee::levelUpPlay()
+{
+ if (gameState.testBit(Ready))
+ return;
+
+ if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
+ TQTimer::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) {
+ TQTimer::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)) {
+ TQTimer::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);
+ TQTimer::singleShot(dyingPreAnimationMS, this, SLOT(killed()));
+ } else {
+ stop();
+ if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
+ TQTimer::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)) {
+ TQTimer::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)
+ TQTimer::singleShot(dyingPostAnimationMS, this, SLOT(killedPlay()));
+ else
+ TQTimer::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);
+ TQTimer::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);
+ TQRect *r = new TQRect();
+ 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);
+ TQRect *r = new TQRect();
+ 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(TQFocusEvent *)
+{
+ if (focusInContinue && focusedPause &&
+ gameState.testBit(Paused) && gameState.testBit(Playing)) {
+ focusedPause = false;
+ // this also calls the Referee::pause() function
+ emit focusedGamePause();
+ }
+}
+
+void Referee::focusOutEvent(TQFocusEvent *)
+{
+ if (focusOutPause && !focusedPause &&
+ !gameState.testBit(Paused) && gameState.testBit(Playing)) {
+ focusedPause = true;
+ // this also calls the Referee::pause() function
+ emit focusedGamePause();
+ }
+}
+
+#include "referee.moc"
diff --git a/tdepacman/referee.h b/tdepacman/referee.h
new file mode 100644
index 0000000..c147d18
--- /dev/null
+++ b/tdepacman/referee.h
@@ -0,0 +1,191 @@
+#ifndef REFEREE_H
+#define REFEREE_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <kapp.h>
+
+#include <tqwidget.h>
+#include <tqptrlist.h>
+#include <tqstrlist.h>
+#include <tqarray.h>
+#include <tqbitarray.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 TQWidget
+{
+ Q_OBJECT
+public:
+ Referee (TQWidget *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 focusedGamePause();
+ void forcedGameHighscores();
+
+protected:
+ void timerEvent(TQTimerEvent *);
+ void paintEvent(TQPaintEvent *);
+ void keyPressEvent(TQKeyEvent *);
+
+ void focusOutEvent(TQFocusEvent *);
+ void focusInEvent(TQFocusEvent *);
+
+ void fillArray(TQMemArray<int> &, TQString, int);
+ void fillStrList(TQStrList &, TQString, 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:
+ TQBitArray gameState;
+ int timerCount;
+ int maxLevel;
+
+ int scheme;
+ int mode;
+
+ TQString pixmapDirectory;
+ TQString mapDirectory;
+ TQStrList mapName;
+
+ TQMemArray<int> speed;
+ TQMemArray<int> monsterIQ;
+ TQMemArray<int> fruitIQ;
+ TQMemArray<int> fruitIndex;
+ TQMemArray<int> pacmanTicks;
+ TQMemArray<int> remTicks;
+ TQMemArray<int> dangerousTicks;
+ TQMemArray<int> harmlessTicks;
+ TQMemArray<int> harmlessDurTicks;
+ TQMemArray<int> harmlessWarnTicks;
+ TQMemArray<int> arrestTicks;
+ TQMemArray<int> arrestDurTicks;
+ TQMemArray<int> fruitTicks;
+ TQMemArray<int> fruitAppearsTicks;
+ TQMemArray<int> fruitDurTicks;
+ TQMemArray<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;
+ TQMemArray<int> fruitScore;
+ TQMemArray<int> monsterScore;
+ TQMemArray<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;
+
+ TQPtrList<Monster> *monsters;
+ TQPtrList<TQRect> *monsterRect;
+
+ TQPtrList<Energizer> *energizers;
+ TQPtrList<TQRect> *energizerRect;
+
+ TQRect pacmanRect;
+ TQRect 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/tdepacman/score.cpp b/tdepacman/score.cpp
new file mode 100644
index 0000000..77c87d8
--- /dev/null
+++ b/tdepacman/score.cpp
@@ -0,0 +1,628 @@
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <kapp.h>
+#include <kstddirs.h>
+
+#include <tdeaccel.h>
+#include <tdeconfig.h>
+#include <tdemessagebox.h>
+#include <tqpixmap.h>
+#include <tqstring.h>
+#include <tqdstream.h>
+#include <tqkeycode.h>
+#include <tqtimer.h>
+#include <tqfileinfo.h>
+
+#include "bitfont.h"
+#include "score.h"
+
+Score::Score(TQWidget *parent, const char *name, int Scheme, int Mode, Bitfont *font) : TQWidget(parent, name)
+{
+ setFocusPolicy(TQWidget::StrongFocus);
+
+ paused = FALSE;
+
+ lastScore = -1;
+ lastPlayer = -1;
+
+ cursorBlinkTimer = 0;
+ cursorBlinkMS = -1;
+ cursor.x = -1;
+ cursor.y = -1;
+ cursor.on = FALSE;
+ cursor.chr = TQChar('?');
+
+ 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( TQPaintEvent *e)
+{
+ if (rect(1, 0, i18n(" 1UP ")).intersects(e->rect())) {
+ TQPixmap pix;
+ TQColor 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())) {
+ TQPixmap 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())) {
+ TQPixmap pix;
+ TQColor fg = BLACK;
+ if (cursor.on || paused || lastPlayer != 1)
+ fg = WHITE;
+ pix = bitfont->text(i18n(" 2UP "), fg, BLACK);
+ bitBlt(this, x(21), y(0), &pix);
+ }
+
+ TQString s;
+
+ s.sprintf("%6d0", playerScore[0]/10);
+ if (rect(0, 1, s).intersects(e->rect())) {
+ TQPixmap 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())) {
+ TQPixmap 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())) {
+ TQPixmap 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())) {
+ TQPixmap 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())) {
+ TQPixmap 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())) {
+ TQPixmap 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())) {
+ TQPixmap 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()).utf8().data());
+ if (rect(1, (11+i)*1.25, s).intersects(e->rect())) {
+ TQPixmap 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())) {
+ TQPixmap pix = bitfont->text(cursor.chr, BLACK, YELLOW);
+ bitBlt(this, x(cursor.x), y(cursor.y*1.25), &pix);
+ }
+ }
+
+ if (paused) {
+
+ TQPixmap pix = bitfont->text(i18n("PAUSED"), RED, BLACK);
+ TQRect r = bitfont->rect(i18n("PAUSED"));
+ r.moveCenter(TQPoint(this->width()/2, this->height()/2));
+
+ bitBlt(this, r.x(), r.y(), &pix);
+ }
+}
+
+void Score::timerEvent(TQTimerEvent *e)
+{
+ 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(TQKeyEvent *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;
+ lastPlayer = -1;
+ cursor.x = -1;
+ cursor.y = -1;
+ emit gameFinished();
+ 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()
+{
+ TQString up("Up");
+ up = kapp->config()->readEntry("upKey", up);
+ UpKey = TDEShortcut(up);
+
+ TQString down("Down");
+ down = kapp->config()->readEntry("downKey", down);
+ DownKey = TDEShortcut(down);
+
+ TQString left("Left");
+ left = kapp->config()->readEntry("leftKey", left);
+ LeftKey = TDEShortcut(left);
+
+ TQString right("Right");
+ right = kapp->config()->readEntry("rightKey", right);
+ RightKey = TDEShortcut(right);
+}
+
+void Score::confTiming(bool defGroup)
+{
+ if (defGroup || kapp->config()->hasKey("CursorBlinkMS"))
+ cursorBlinkMS = kapp->config()->readNumEntry("CursorBlinkMS", 250);
+ if (defGroup || kapp->config()->hasKey("HallOfFameMS"))
+ hallOfFameMS = kapp->config()->readNumEntry("HallOfFameMS", 7000);
+ if (defGroup || kapp->config()->hasKey("AfterPauseMS"))
+ afterPauseMS = kapp->config()->readNumEntry("AfterPauseMS", 1000);
+}
+
+void Score::confScheme()
+{
+ TQString oldgroup = kapp->config()->group();
+ TQString newgroup;
+
+ // if not set, read mode and scheme from the configfile
+ if (mode == -1 && scheme == -1) {
+ scheme = kapp->config()->readNumEntry("Scheme", -1);
+ mode = kapp->config()->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);
+ kapp->config()->setGroup(newgroup);
+
+ mode = kapp->config()->readNumEntry("Mode", -1);
+ kapp->config()->setGroup(oldgroup);
+ }
+ }
+
+ int oldCursorBlinkMS = cursorBlinkMS;
+
+ confTiming();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ kapp->config()->setGroup(newgroup);
+
+ confTiming(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ kapp->config()->setGroup(newgroup);
+
+ confTiming(FALSE);
+ }
+
+ if (cursorBlinkMS != oldCursorBlinkMS) {
+ if (cursorBlinkTimer)
+ killTimer(cursorBlinkTimer);
+ cursorBlinkTimer = startTimer(cursorBlinkMS);
+ }
+
+ kapp->config()->setGroup(oldgroup);
+}
+
+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;
+
+ TQString 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)
+{
+ // pointer to the array-position of a new archived top score
+ lastScore = -1;
+
+ // was it a real game or just a demo (level == 0)
+ if (player >= 0 && player < maxPlayer && level != 0) {
+
+ lastPlayer = player;
+
+ for (int i = 0; i < 10; i++)
+ if ( playerScore[lastPlayer] > hallOfFame[i].points) {
+ lastScore = i;
+ break;
+ }
+ }
+
+ // no new highscore archived, finish after specified time
+ if (lastScore < 0) {
+ // enable gameNew directly for an immediate next try
+ emit gameFinished();
+ lastPlayer = -1;
+ TQTimer::singleShot(hallOfFameMS, this, SLOT(end()));
+ return;
+ }
+
+ // shift old (lower) scores to make place for the new one
+ 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 = TQDateTime::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)) {
+ TQDataStream 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 = TQString::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 = TQTime();
+ hallOfFame[i].moment = TQDateTime();
+ 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()
+{
+ 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 (tdepacmanrc: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 (tdepacmanrc:highscoreFilePath)."
+ ).arg(systemHighscoreFileInfo.filePath()),
+ TQString::null, "PrivateHighscore");
+
+ if (highscoreFile.open(IO_WriteOnly)) {
+ TQDataStream 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;
+
+ TQRect r = bitfont->rect(i18n("PAUSED"));
+ r.moveCenter(TQPoint(this->width()/2, this->height()/2));
+ repaint(r, TRUE);
+
+ // repaint 1UP or 2UP
+ repaint(FALSE);
+}
+
+void Score::end()
+{
+ if (paused) {
+ TQTimer::singleShot(afterPauseMS, this, SLOT(end()));
+ return;
+ }
+
+ // repaint 1UP or 2UP
+ repaint(FALSE);
+
+ // if lastPlayer != -1 we're already in playing mode
+ if (lastPlayer == -1)
+ emit gameHighscores();
+}
+
+/*
+ * Return the date in a formatted TQString. The format can be changed using internationalization
+ * of the string "YY/MM/DD". Invalid TQDate's where returned as "00/00/00".
+ */
+TQString Score::formatDate(TQDate date)
+{
+ TQString s = i18n("@YY@/@MM@/@DD@");
+
+ TQString dd;
+ dd.sprintf("%02d", date.isValid() ? date.year() % 100 : 0);
+ s.replace(TQRegExp("@YY@"), dd);
+ dd.sprintf("%02d", date.isValid() ? date.month() : 0);
+ s.replace(TQRegExp("@MM@"), dd);
+ dd.sprintf("%02d", date.isValid() ? date.day() : 0);
+ s.replace(TQRegExp("@DD@"), dd);
+
+ return s;
+}
+
+TQRect Score::rect(int col, float row, TQString str, int align)
+{
+ TQRect 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"-TDEConfig-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.
+ */
+TQFileInfo Score::locateHighscoreFilePath()
+{
+ TQFileInfo systemHighscoreDirPath;
+ TQStringList systemHighscoreDirs;
+
+ // Schreibfähige "private" highscore-Datei ermitteln für den fallback.
+ privateHighscoreFileInfo.setFile(TDEGlobal::dirs()->saveLocation("appdata")+highscoreName);
+
+ // FilePath aus der Konfigurationsdatei benutzen
+ systemHighscoreFileInfo.setFile(kapp->config()->readEntry("HighscoreFilePath"));
+
+ // Kein Wert aus der Konfiguration erhalten, dann die "system"-Datei suchen.
+ if (systemHighscoreFileInfo.filePath().isEmpty())
+ systemHighscoreDirs = TDEGlobal::dirs()->resourceDirs("appdata");
+ else
+ systemHighscoreDirs = TQStringList(systemHighscoreFileInfo.filePath());
+
+ for (TQStringList::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;
+ }
+
+ return privateHighscoreFileInfo;
+}
+
+#include "score.moc"
diff --git a/tdepacman/score.h b/tdepacman/score.h
new file mode 100644
index 0000000..fc0da45
--- /dev/null
+++ b/tdepacman/score.h
@@ -0,0 +1,124 @@
+#ifndef SCORE_H
+#define SCORE_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <kapp.h>
+
+#include <tqwidget.h>
+#include <tqstring.h>
+#include <tqpoint.h>
+#include <tqrect.h>
+#include <tqfile.h>
+#include <tqfileinfo.h>
+#include <tqdatetime.h>
+
+#include "painter.h"
+#include "bitfont.h"
+
+#define maxPlayer 1
+#define minPlayerNameLength 3
+#define highscoreName "highscore"
+
+class Score : public TQWidget
+{
+ Q_OBJECT
+public:
+ Score (TQWidget *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 gameFinished();
+ void gameHighscores();
+
+protected:
+ void timerEvent(TQTimerEvent *);
+ void paintEvent(TQPaintEvent *);
+ void keyPressEvent(TQKeyEvent *);
+
+ void focusInEvent(TQFocusEvent *) { ; }
+ void focusOutEvent(TQFocusEvent *) { ; }
+
+ void confScheme();
+ void confTiming(bool defGroup=TRUE);
+
+private:
+ Bitfont *bitfont;
+
+ TQRect rect(int col, float row, TQString str, int align = AlignCenter);
+ int x(int col);
+ int y(float row);
+
+ TQString formatDate(TQDate date);
+
+ /**
+ * Ermittelt die zu benutzende "highscore"-Datei, in die auch geschrieben werden kann.
+ * Über den "highscoreFilePath"-TDEConfig-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.
+ */
+ TQFileInfo 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];
+ TQString playerName[maxPlayer];
+
+ struct {
+ int x;
+ int y;
+ TQChar chr;
+ bool on;
+ } cursor;
+
+ int cursorBlinkTimer;
+ bool scrollRepeat;
+
+ struct {
+ int points;
+ int levels;
+ TQTime duration;
+ TQDateTime moment;
+ TQString name;
+ } hallOfFame[10];
+
+ TQFileInfo systemHighscoreFileInfo;
+ TQFileInfo privateHighscoreFileInfo;
+
+ TQFile highscoreFile;
+
+ int scheme;
+ int mode;
+};
+
+#endif // SCORE_H
diff --git a/tdepacman/status.cpp b/tdepacman/status.cpp
new file mode 100644
index 0000000..12f01b7
--- /dev/null
+++ b/tdepacman/status.cpp
@@ -0,0 +1,353 @@
+#include <kapp.h>
+#include <kstddirs.h>
+
+#include <tdelocale.h>
+#include <tqbitmap.h>
+#include <tqstring.h>
+#include <tqmsgbox.h>
+#include <tqfileinfo.h>
+
+#include "status.h"
+
+Status::Status( TQWidget *parent, const char *name, int Scheme, int Mode ) :
+ TQWidget( parent, name )
+{
+ actualLifes = 0;
+ actualLevel = 0;
+
+ lifesPix = NULL;
+ levelPix = NULL;
+
+ scheme = Scheme;
+ mode = Mode;
+ level = 0;
+
+ confScheme();
+}
+
+TQPtrList<TQPixmap> *Status::loadPixmap(TQWidget *parent, TQString pixmapName,
+ TQPtrList<TQPixmap> *pixmaps)
+{
+ if (pixmaps == NULL) {
+ pixmaps = new TQPtrList<TQPixmap>;
+ pixmaps->setAutoDelete(TRUE);
+ }
+
+ if (!pixmaps->isEmpty())
+ pixmaps->clear();
+
+ TQPixmap PIXMAP(pixmapName);
+ if (PIXMAP.isNull() || PIXMAP.mask() == NULL) {
+ TQString 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(TQRegExp("@PIXMAPNAME@"), pixmapName);
+ TQMessageBox::information(parent, i18n("Initialization Error"), msg);
+ return 0;
+ }
+
+ int height = PIXMAP.height();
+ int width = (height == 0) ? 0 : PIXMAP.width()/(PIXMAP.width()/height);
+
+ TQBitmap BITMAP;
+ TQBitmap MASK;
+
+ BITMAP = *PIXMAP.mask();
+ MASK.resize(width, height);
+
+ for (int x = 0; x < PIXMAP.width()/width; x++) {
+ TQPixmap *pixmap = new TQPixmap(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( TQPaintEvent *)
+{
+ 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);
+ }
+}
+
+TQString Status::decodeHexOctString(TQString s)
+{
+ TQString value;
+ TQString valids;
+ int pos, xpos = 0, opos = 0;
+ int v, len, leadin;
+ const char *ptr;
+ uchar c;
+
+ while (((xpos = s.find(TQRegExp("\\\\x[0-9a-fA-F]+"), xpos)) != -1) ||
+ ((opos = s.find(TQRegExp("\\\\[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 = value.latin1();
+
+ 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(TQMemArray<int> &array, TQString values, int max)
+{
+ array.resize(max);
+ int last = 0;
+ bool ok;
+ TQString 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(TQStrList &list, TQString values, int max)
+{
+ if (!list.isEmpty())
+ list.clear();
+
+ TQString last = "";
+ TQString 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.latin1());
+ }
+}
+
+void Status::fillPixmapName(TQStrList &pixmapName)
+{
+ TQStrList list = pixmapName;
+
+ if (!pixmapName.isEmpty())
+ pixmapName.clear();
+
+ TQString pixmap;
+
+ TQFileInfo fileInfo;
+
+ for (uint i = 0; i < list.count(); i++) {
+ pixmap = list.at(i);
+
+ if (pixmap.left(1) != "/" && pixmap.left(1) != "~")
+ pixmap = TDEGlobal::dirs()->findResource("appdata", pixmapDirectory+pixmap);
+
+ fileInfo.setFile(pixmap);
+ if (!fileInfo.isReadable() || !fileInfo.isFile())
+ pixmap = "";
+
+ pixmapName.append(pixmap.utf8());
+ }
+}
+
+void Status::confLevels(bool defGroup)
+{
+ if (defGroup || kapp->config()->hasKey("Levels"))
+ maxLevel = kapp->config()->readNumEntry("Levels", 13);
+}
+
+void Status::confMisc(bool defGroup)
+{
+ if (defGroup || kapp->config()->hasKey("LevelPosition"))
+ fillArray(levelPos, kapp->config()->readEntry("LevelPosition", "0,1,2,3,,4,,5,,6,,7"), maxLevel);
+
+ if (defGroup || kapp->config()->hasKey("PixmapDirectory")) {
+ pixmapDirectory = kapp->config()->readEntry("PixmapDirectory");
+
+ if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~")
+ pixmapDirectory.insert(0, "pics/");
+ if (pixmapDirectory.right(1) != "/")
+ pixmapDirectory.append("/");
+ }
+
+ if (defGroup || kapp->config()->hasKey("LifesPixmapName"))
+ fillStrList(lifesPixmapName,
+ kapp->config()->readEntry("LifesPixmapName", "lifes.xpm"), maxLevel+1);
+ if (defGroup || kapp->config()->hasKey("LevelPixmapName"))
+ fillStrList(levelPixmapName,
+ kapp->config()->readEntry("LevelPixmapName", "level.xpm"), maxLevel+1);
+
+}
+
+void Status::confScheme()
+{
+ TQString oldgroup = kapp->config()->group();
+ TQString newgroup;
+
+ // if not set, read mode and scheme from the configfile
+ if (mode == -1 && scheme == -1) {
+ scheme = kapp->config()->readNumEntry("Scheme", -1);
+ mode = kapp->config()->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);
+ kapp->config()->setGroup(newgroup);
+
+ mode = kapp->config()->readNumEntry("Mode", -1);
+ kapp->config()->setGroup(oldgroup);
+ }
+ }
+
+ confLevels();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ kapp->config()->setGroup(newgroup);
+
+ confLevels(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ kapp->config()->setGroup(newgroup);
+
+ confLevels(FALSE);
+ }
+
+ kapp->config()->setGroup(oldgroup);
+
+ confMisc();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ kapp->config()->setGroup(newgroup);
+
+ confMisc(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ kapp->config()->setGroup(newgroup);
+
+ confMisc(FALSE);
+ }
+
+ fillPixmapName(lifesPixmapName);
+ fillPixmapName(levelPixmapName);
+
+ initPixmaps();
+
+ setFixedHeight(minHeight());
+
+ kapp->config()->setGroup(oldgroup);
+}
+
+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();
+}
+
+#include "status.moc"
diff --git a/tdepacman/status.h b/tdepacman/status.h
new file mode 100644
index 0000000..6cbf759
--- /dev/null
+++ b/tdepacman/status.h
@@ -0,0 +1,74 @@
+#ifndef STATUS_H
+#define STATUS_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <kapp.h>
+
+#include <tdeconfig.h>
+#include <tqwidget.h>
+#include <tqpixmap.h>
+#include <tqstring.h>
+#include <tqmemarray.h>
+#include <tqptrlist.h>
+#include <tqstrlist.h>
+#include <tqregexp.h>
+
+class Status : public TQWidget
+{
+ Q_OBJECT
+public:
+ Status(TQWidget *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(TQPaintEvent *);
+ int minHeight();
+ int minWidth();
+
+ TQString decodeHexOctString(TQString str);
+
+ void fillArray(TQMemArray<int> &, TQString, int);
+ void fillStrList(TQStrList &, TQString, int);
+ void fillPixmapName(TQStrList &);
+
+ void confScheme();
+ void confLevels(bool defGroup=TRUE);
+ void confMisc(bool defGroup=TRUE);
+
+ void initPixmaps();
+
+private:
+ TQMemArray<int> levelPos;
+ int actualLifes;
+ int actualLevel;
+
+ TQString pixmapDirectory;
+
+ TQStrList lifesPixmapName;
+ TQStrList levelPixmapName;
+
+ TQString lastLifesPixmapName;
+ TQString lastLevelPixmapName;
+
+ TQPtrList<TQPixmap> *loadPixmap(TQWidget *parent, TQString pixmapName,
+ TQPtrList<TQPixmap> *pixmaps=0);
+
+ TQPtrList<TQPixmap> *lifesPix;
+ TQPtrList<TQPixmap> *levelPix;
+
+ int maxLevel;
+ int level;
+
+ int scheme;
+ int mode;
+};
+
+#endif // STATUS_H
diff --git a/tdepacman/tdepacman.cpp b/tdepacman/tdepacman.cpp
new file mode 100644
index 0000000..351d56f
--- /dev/null
+++ b/tdepacman/tdepacman.cpp
@@ -0,0 +1,476 @@
+/***************************************************************************
+ tdepacman.cpp - description
+ -------------------
+ begin : Sam Jan 19 13:37:57 CET 2002
+ copyright : (C) 1998-2003 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 files for TQt
+#include <tqkeycode.h>
+#include <tqcolor.h>
+#include <tqstring.h>
+#include <tqmsgbox.h>
+
+// include files for TDE
+#include <kcolordlg.h>
+#include <kstatusbar.h>
+#include <kstdaction.h>
+#include <kstdgameaction.h>
+
+// application specific includes
+#include "tdepacman.h"
+
+#define ID_STATUS_MSG 1
+
+TDEpacmanApp::TDEpacmanApp(TQWidget *, const char *name) : TDEMainWindow(0, name)
+{
+ config=kapp->config();
+
+ ///////////////////////////////////////////////////////////////////
+ // call inits to invoke all other construction parts
+ initStatusBar();
+ initActions();
+ initView();
+
+ readOptions();
+
+ highscoresChecked = false;
+ focusedPause = false;
+
+ 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(focusedGamePause()), this, SLOT(slotFocusedGamePause()));
+ connect(view->referee, SIGNAL(forcedGameHighscores()), this, SLOT(slotForcedGameHighscores()));
+
+ connect(view->score, SIGNAL(gameHighscores()), this, SLOT(slotGameHighscores()));
+ connect(view->score, SIGNAL(gameFinished()), this, SLOT(slotGameFinished()));
+}
+
+TDEpacmanApp::~TDEpacmanApp()
+{
+
+}
+
+
+void TDEpacmanApp::initActions()
+{
+ gameNew = KStdGameAction::gameNew(this, SLOT(slotGameNew()), actionCollection());
+ gamePause = KStdGameAction::pause(this, SLOT(slotGamePause()), actionCollection());
+ gamePause->setAccel(Key_F3);
+ gameQuit = KStdGameAction::quit(this, SLOT(slotGameQuit()), actionCollection());
+ gameHighscores = KStdGameAction::highscores(this, SLOT(slotGameHighscores()), actionCollection());
+ showMenuBar = KStdAction::showMenubar(this, SLOT(slotShowMenuBar()), actionCollection());
+ showToolBar = KStdAction::showToolbar(this, SLOT(slotShowToolBar()), actionCollection());
+ showStatusBar = KStdAction::showStatusbar(this, SLOT(slotShowStatusBar()), actionCollection());
+ showMouseCursor = new TDEToggleAction(i18n("Show Mouse&cursor"), 0,
+ this, SLOT(slotShowMouseCursor()), actionCollection(),
+ "options_show_mousecursor");
+ selectGraphicScheme = new TDEActionMenu(i18n("&Select graphic scheme"), actionCollection(),
+ "options_select_graphic_scheme");
+ KStdAction::keyBindings(this, SLOT(slotKeyBindings()), actionCollection());
+ focusOutPause = new TDEToggleAction(i18n("Pause in &Background"), 0,
+ this, SLOT(slotFocusOutPause()), actionCollection(),
+ "options_focus_out_pause");
+ focusInContinue = new TDEToggleAction(i18n("Continue in &Foreground"), 0,
+ this, SLOT(slotFocusInContinue()), actionCollection(),
+ "options_focus_in_continue");
+
+ showMenuBar->setStatusText(i18n("Enables/disables the menubar"));
+ showToolBar->setStatusText(i18n("Enables/disables the toolbar"));
+ showStatusBar->setStatusText(i18n("Enables/disables the statusbar"));
+ showMouseCursor->setStatusText(i18n("Enable/disables the mousecursor"));
+
+ // use the absolute path to your tdepacmanui.rc file for testing purpose in createGUI();
+ createGUI();
+}
+
+
+void TDEpacmanApp::initStatusBar()
+{
+ ///////////////////////////////////////////////////////////////////
+ // STATUSBAR
+ // TODO: add your own items you need for displaying current application status.
+ statusBar()->insertItem(i18n("Ready."), ID_STATUS_MSG);
+}
+
+void TDEpacmanApp::initView()
+{
+ ////////////////////////////////////////////////////////////////////
+ // create the main widget here that is managed by TDEMainWindow's view-region and
+ // connect the widget.
+
+ view = new TDEpacmanView(this);
+ setCentralWidget(view);
+
+ setFixedSize(view->width(), view->height());
+ view->referee->setFocus();
+}
+
+void TDEpacmanApp::saveOptions()
+{
+ // config->setGroup("General Options");
+ config->writeEntry("Geometry", size());
+ config->writeEntry("ShowMenubar", showMenuBar->isChecked());
+ config->writeEntry("ShowToolbar", showToolBar->isChecked());
+ config->writeEntry("ShowStatusbar", showStatusBar->isChecked());
+ config->writeEntry("ShowMousecursor", showMouseCursor->isChecked());
+ config->writeEntry("FocusOutPause", focusOutPause->isChecked());
+ config->writeEntry("FocusInContinue", focusInContinue->isChecked());
+ config->writeEntry("ToolBarPos", (int) toolBar("mainToolBar")->barPos());
+ config->writeEntry("Scheme", scheme);
+ config->writeEntry("Mode", mode);
+}
+
+void TDEpacmanApp::readOptions()
+{
+
+ // config->setGroup("General Options");
+
+ // bar status settings
+ bool bShowMenubar = config->readBoolEntry("ShowMenubar", true);
+ showMenuBar->setChecked(bShowMenubar);
+ slotShowMenuBar();
+
+ bool bShowToolbar = config->readBoolEntry("ShowToolbar", true);
+ showToolBar->setChecked(bShowToolbar);
+ slotShowToolBar();
+
+ bool bShowStatusbar = config->readBoolEntry("ShowStatusbar", false);
+ showStatusBar->setChecked(bShowStatusbar);
+ slotShowStatusBar();
+
+ // cursor status settings
+ bool bShowMousecursor = config->readBoolEntry("ShowMousecursor", false);
+ showMouseCursor->setChecked(bShowMousecursor);
+ slotShowMouseCursor();
+
+ // focus status settings
+ bool bFocusOutPause = config->readBoolEntry("FocusOutPause", false);
+ focusOutPause->setChecked(bFocusOutPause);
+ slotFocusOutPause();
+
+ bool bFocusInContinue = config->readBoolEntry("FocusInContinue", false);
+ focusInContinue->setChecked(bFocusInContinue);
+ slotFocusInContinue();
+
+ // bar position settings
+ TDEToolBar::BarPosition toolBarPos;
+ toolBarPos = (TDEToolBar::BarPosition) config->readNumEntry("ToolBarPos", TDEToolBar::Top);
+ toolBar("mainToolBar")->setBarPos(toolBarPos);
+
+ TQSize size = config->readSizeEntry("Geometry");
+ if (!size.isEmpty())
+ {
+ resize(size);
+ }
+
+ // scheme and mode
+ scheme = config->readNumEntry("Scheme", -1);
+ mode = config->readNumEntry("Mode", -1);
+ readSchemes();
+}
+
+void TDEpacmanApp::readSchemes()
+{
+ TQString saveGroup = config->group();
+ TQString group;
+ TQString description;
+
+ int modeCount = config->readNumEntry("ModeCount", -1);
+ int schemeCount = config->readNumEntry("SchemeCount");
+
+ modeID.resize(modeCount > 0 ? modeCount : 0);
+ schemeID.resize(schemeCount);
+ schemeMode.resize(schemeCount);
+
+ schemesPopup = new TQPtrList<TDEPopupMenu>;
+ schemesPopup->setAutoDelete(true);
+
+ modesPopup = selectGraphicScheme->popupMenu();
+ connect(modesPopup, SIGNAL(activated(int)), this, SLOT(slotSchemeActivated(int)));
+
+ if (schemeCount == 0 || scheme == -1) {
+ TQMessageBox::warning(this, i18n("Configuration Error"),
+ i18n("There are no schemes defined,\n"
+ "or no scheme is selected."));
+ return;
+ }
+
+ // create submenus (TQPopupMenu) for graphic-modes
+ for (int m = 0; m < modeCount; m++) {
+ group.sprintf("Mode %d", m);
+ config->setGroup(group);
+
+ description = config->readEntry("Description", group);
+
+ TDEPopupMenu *p = new TDEPopupMenu;
+ p->setCheckable(true);
+ connect(p, SIGNAL(activated(int)), this, SLOT(slotSchemeActivated(int)));
+ schemesPopup->append(p);
+
+ modeID[m] = modesPopup->insertItem(description, schemesPopup->at(m));
+ modesPopup->setItemEnabled(modeID[m], false);
+ modesPopup->setItemChecked(modeID[m], m == mode);
+ }
+
+ // create menuitems (insertItem) for graphic-schemes
+ for (int i = 0; i < schemeCount; i++) {
+ group.sprintf("Scheme %d", i);
+ config->setGroup(group);
+
+ description = config->readEntry("Description", group);
+ schemeMode[i] = config->readNumEntry("Mode", -1);
+
+ if (schemeMode[i] == -1) {
+ schemeID[i] = modesPopup->insertItem(description);
+ modesPopup->setItemChecked(schemeID[i], i == scheme);
+ } else {
+ schemeID[i] = schemesPopup->at(schemeMode[i])->insertItem(description);
+ schemesPopup->at(schemeMode[i])->setItemChecked(schemeID[i], i == scheme);
+ modesPopup->setItemEnabled(modeID[schemeMode[i]], true);
+ }
+ }
+
+ config->setGroup(saveGroup);
+}
+
+bool TDEpacmanApp::queryExit()
+{
+ saveOptions();
+ return true;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// SLOT IMPLEMENTATION
+/////////////////////////////////////////////////////////////////////
+
+void TDEpacmanApp::slotGameNew()
+{
+ // enable the gameHighscores action, if disabled by forced highscores mode
+ if (!gameHighscores->isEnabled())
+ gameHighscores->setEnabled(true);
+
+ // hide highscores and show board again, if in highscores mode
+ if (highscoresChecked)
+ slotGameHighscores();
+
+ // deactivate pause and uncheck the menuitem, if in pause state
+ if (gamePause->isChecked()) {
+ gamePause->setChecked(false);
+ slotGamePause();
+ }
+ // disable menuitem to prevent interruption of the game
+ gameNew->setEnabled(false);
+
+ view->referee->play();
+}
+
+void TDEpacmanApp::slotGamePause()
+{
+ view->referee->pause();
+ view->score->setPause(gamePause->isChecked());
+}
+
+void TDEpacmanApp::slotFocusedGamePause()
+{
+ // if an focus-event triggers the pause, toggle the gamePause checked
+ gamePause->setChecked(!gamePause->isChecked());
+ focusedPause = !focusedPause;
+
+ slotGamePause();
+}
+
+void TDEpacmanApp::slotGameHighscores()
+{
+ // toggle highscores mode flag
+ highscoresChecked = !highscoresChecked;
+
+ view->referee->toggleHallOfFame();
+
+ // show highscore (by lowering referee and status) or return to play (by raising them again)
+ if (highscoresChecked) {
+ view->referee->lower();
+ view->status->lower();
+ } else {
+ view->status->raise();
+ view->referee->raise();
+ view->referee->setFocus();
+
+ // after forced highscores comes the intro again
+ if (!gameHighscores->isEnabled()) {
+ gameHighscores->setEnabled(true);
+ view->referee->intro();
+ }
+ }
+}
+
+void TDEpacmanApp::slotForcedGameHighscores()
+{
+ // disable menuitem to prevent closing highscores display
+ gameHighscores->setEnabled(false);
+
+ slotGameHighscores();
+}
+
+void TDEpacmanApp::slotGameQuit()
+{
+ slotStatusMsg(i18n("Exiting..."));
+ saveOptions();
+ kapp->quit();
+}
+
+void TDEpacmanApp::slotShowMenuBar()
+{
+ slotStatusMsg(i18n("Toggling menubar..."));
+ ///////////////////////////////////////////////////////////////////
+ // turn Menubar on or off
+ if(!showMenuBar->isChecked()) {
+ menuBar()->hide();
+ setFixedSize(view->width(), view->height());
+ } else {
+ menuBar()->show();
+ }
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void TDEpacmanApp::slotShowToolBar()
+{
+ slotStatusMsg(i18n("Toggling toolbar..."));
+ ///////////////////////////////////////////////////////////////////
+ // turn Toolbar on or off
+ if(!showToolBar->isChecked()) {
+ toolBar("mainToolBar")->hide();
+ setFixedSize(view->width(), view->height());
+ } else {
+ toolBar("mainToolBar")->show();
+ }
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void TDEpacmanApp::slotShowStatusBar()
+{
+ slotStatusMsg(i18n("Toggle the statusbar..."));
+ ///////////////////////////////////////////////////////////////////
+ // turn Statusbar on or off
+ if(!showStatusBar->isChecked()) {
+ statusBar()->hide();
+ setFixedSize(view->width(), view->height());
+ } else {
+ statusBar()->show();
+ }
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void TDEpacmanApp::slotShowMouseCursor()
+{
+ slotStatusMsg(i18n("Toggle the mousecursor..."));
+ ///////////////////////////////////////////////////////////////////
+ // turn Mousecursor on or off
+ if(!showMouseCursor->isChecked()) {
+ view->setCursor(blankCursor);
+ } else {
+ view->setCursor(arrowCursor);
+ }
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void TDEpacmanApp::slotSchemeActivated(int id)
+{
+ slotStatusMsg(i18n("Graphic scheme selected..."));
+ ///////////////////////////////////////////////////////////////////
+ // select activated scheme/mode
+
+ mode = -1;
+ 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);
+ }
+ }
+
+ view->setScheme(scheme, mode);
+ setFixedSize(view->width(), view->height());
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void TDEpacmanApp::slotFocusOutPause()
+{
+ slotStatusMsg(i18n("Toggle focusOutPause..."));
+ ///////////////////////////////////////////////////////////////////
+ // turn focusOutPause on or off
+ view->referee->setFocusOutPause(focusOutPause->isChecked());
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void TDEpacmanApp::slotFocusInContinue()
+{
+ slotStatusMsg(i18n("Toggle focusInContinue..."));
+ ///////////////////////////////////////////////////////////////////
+ // turn focusInContinue on or off
+ view->referee->setFocusInContinue(focusInContinue->isChecked());
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void TDEpacmanApp::slotKeyBindings()
+{
+ slotStatusMsg(i18n("Configure key bindings..."));
+ ///////////////////////////////////////////////////////////////////
+ // configure key bindings
+ PKeys *keys = new PKeys();
+ if (keys->exec() == TQDialog::Accepted) {
+ view->referee->initKeys();
+ view->score->initKeys();
+ }
+ delete keys;
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void TDEpacmanApp::slotGameFinished()
+{
+ slotStatusMsg(i18n("Game finished..."));
+ ///////////////////////////////////////////////////////////////////
+ // enable/disable the menuitem
+ gameNew->setEnabled(true);
+
+ slotStatusMsg(i18n("Ready."));
+}
+
+void TDEpacmanApp::slotStatusMsg(const TQString &text)
+{
+ ///////////////////////////////////////////////////////////////////
+ // change status message permanently
+ statusBar()->clear();
+ statusBar()->changeItem(text, ID_STATUS_MSG);
+}
+
+#include "tdepacman.moc"
diff --git a/tdepacman/tdepacman.desktop b/tdepacman/tdepacman.desktop
new file mode 100644
index 0000000..8d69824
--- /dev/null
+++ b/tdepacman/tdepacman.desktop
@@ -0,0 +1,16 @@
+[Desktop Entry]
+Name=TDEpacman
+
+GenericName=Arcade Game
+
+Comment=A simple clone of the classic arcade game Pac-Man
+
+Keywords=arcade;pacman;dots;ghosts;level;
+
+Type=Application
+Exec=tdepacman -caption "%c" %i %m
+Icon=tdepacman.png
+MiniIcon=tdepacman.png
+Terminal=false
+X-DocPath=tdepacman/index.html
+Categories=Qt;TDE;Game;ArcadeGame;
diff --git a/tdepacman/tdepacman.h b/tdepacman/tdepacman.h
new file mode 100644
index 0000000..65740ed
--- /dev/null
+++ b/tdepacman/tdepacman.h
@@ -0,0 +1,185 @@
+/***************************************************************************
+ tdepacman.h - description
+ -------------------
+ begin : Sam Jan 19 13:37:57 CET 2002
+ copyright : (C) 1998-2003 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef TDEPACMAN_H
+#define TDEPACMAN_H
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+// include files for TQt
+#include <tqptrlist.h>
+#include <tqfileinf.h>
+#include <tqregexp.h>
+
+//include files for TDE
+#include <kapp.h>
+#include <tdemainwindow.h>
+#include <tdepopupmenu.h>
+#include <tdeaction.h>
+#include <tdelocale.h>
+#include <tdemenubar.h>
+
+// application specific includes
+#include "tdepacmanview.h"
+#include "referee.h"
+#include "status.h"
+#include "score.h"
+#include "keys.h"
+
+// forward declaration of the TDEpacman classes
+class TDEpacmanView;
+
+/**
+ * The base class for TDEpacman application.
+ */
+class TDEpacmanApp : public TDEMainWindow
+{
+ Q_OBJECT
+
+ friend class TDEpacmanView;
+
+ public:
+ /** constructor of TDEpacmanApp, calls all init functions to create the application.
+ */
+ TDEpacmanApp(TQWidget *parent = 0, const char *name = 0);
+ virtual ~TDEpacmanApp();
+
+ protected:
+ /** save general Options like all bar positions and status as well as the application specific
+ * Options to the configuration file
+ */
+ void saveOptions();
+ /** read general Options again and initialize all variables
+ */
+ void readOptions();
+ /** read graphic schemes and build menu items for selection
+ */
+ void readSchemes();
+ /** initializes the TDEActions of the application */
+ void initActions();
+ /** sets up the statusbar for the main window by initialzing a statuslabel.
+ */
+ void initStatusBar();
+ /** creates the centerwidget of the KTMainWindow instance and sets it as the view
+ */
+ void initView();
+ /** queryExit is called by KTMainWindow when the last window of the application is going to be closed
+ * during the closeEvent().
+ * Against the default implementation that just returns true, this calls saveOptions() to save the
+ * settings of the window's properties.
+ * @see KTMainWindow#queryExit
+ * @see KTMainWindow#closeEvent
+ */
+ virtual bool queryExit();
+
+
+ public slots:
+ /** play new game
+ */
+ void slotGameNew();
+ /** pause (continue) game
+ */
+ void slotGamePause();
+ /** pause (continue) game triggered by focus events
+ */
+ void slotFocusedGamePause();
+ /** toggle the highscores
+ */
+ void slotGameHighscores();
+ /** toggle the highscores, forced by the referee
+ */
+ void slotForcedGameHighscores();
+ /** save the options, then quits the application.
+ */
+ void slotGameQuit();
+ /** toggles the menubar
+ */
+ void slotShowMenuBar();
+ /** toggles the toolbar
+ */
+ void slotShowToolBar();
+ /** toggles the statusbar
+ */
+ void slotShowStatusBar();
+ /** toggles the mousecursor
+ */
+ void slotShowMouseCursor();
+ /** graphic scheme activated
+ * @param id the id of the activated/selected menuitem
+ */
+ void slotSchemeActivated(int id);
+ /** toggles the focus out pause
+ */
+ void slotFocusOutPause();
+ /** toggles the focus in continue
+ */
+ void slotFocusInContinue();
+ /** changes the statusbar contents for the standard label permanently, used to indicate current actions.
+ * @param text the text that is displayed in the statusbar
+ */
+ void slotStatusMsg(const TQString &text);
+ /** configure keysbindings dialog
+ */
+ void slotKeyBindings();
+ /** game (including highscores displayed) has been finished
+ */
+ void slotGameFinished();
+
+ private:
+ /** the configuration object of the application */
+ TDEConfig *config;
+ /** view is the main widget which represents your working area. The View
+ * class should handle all events of the view widget. It is kept empty so
+ * you can create your view according to your application's needs by
+ * changing the view class.
+ */
+ TDEpacmanView *view;
+
+ // TDEAction pointers to enable/disable actions
+ TDEAction* gameNew;
+ TDEToggleAction* gamePause;
+ TDEAction* gameHighscores;
+ TDEAction* gameQuit;
+ TDEToggleAction* showMenuBar;
+ TDEToggleAction* showToolBar;
+ TDEToggleAction* showStatusBar;
+ TDEToggleAction* showMouseCursor;
+ TDEToggleAction* focusOutPause;
+ TDEToggleAction* focusInContinue;
+ TDEActionMenu* selectGraphicScheme;
+
+ // active scheme/mode
+ int scheme;
+ int mode;
+
+ TDEPopupMenu *modesPopup; // TDEAction main scheme selection menu
+ TQPtrList<TDEPopupMenu> *schemesPopup; // submenus for selecting scheme
+
+ // ID's of the menuitem(s) for finding/selecting scheme by id
+ TQMemArray<int> modeID;
+ TQMemArray<int> schemeID;
+
+ TQMemArray<int> schemeMode; // mode(group) of the schemes, -1 if no group
+
+ bool highscoresChecked; // highscores display active
+ bool focusedPause; // Pause caused by focusEvents
+};
+
+#endif // TDEPACMAN_H
diff --git a/tdepacman/tdepacmanrc b/tdepacman/tdepacmanrc
new file mode 100644
index 0000000..156c455
--- /dev/null
+++ b/tdepacman/tdepacmanrc
@@ -0,0 +1,70 @@
+FocusInContinue=true
+FocusOutPause=true
+HideMouseCursor=false
+LevelPixmapName=fruit.xpm
+Mode=0
+ModeCount=2
+Scheme=0
+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.pbm
+Mode=0
+PixmapDirectory=
+
+[Scheme 1]
+Description=MIDWAY MFG.CO. (&tiny)
+Description[de]=MIDWAY MFG.CO. (&klein)
+Font=font-small.pbm
+Mode=0
+PixmapDirectory=tiny
+
+[Scheme 2]
+Description=K&Zacman (incomplete)
+Description[de]=K&Zacman (unvollständig)
+Font=font-smooth.pbm
+FruitPixmapName=../fruit.xpm
+LevelPixmapName=../fruit.xpm
+PixmapDirectory=zacman
+PrisonPixmapName=../prison.xpm
+
+[Scheme 3]
+Description=&MIDWAY MFG.CO.
+EyesPixmapName=../eyes.xpm
+Font=font-smooth.pbm
+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.pbm
+Mode=1
+MonsterPixmapName=../tiny/monster.xpm
+PixmapDirectory=mspacman-tiny
diff --git a/tdepacman/tdepacmanui.rc b/tdepacman/tdepacmanui.rc
new file mode 100644
index 0000000..9228ab9
--- /dev/null
+++ b/tdepacman/tdepacmanui.rc
@@ -0,0 +1,18 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="tdepacman" version="0.3.2">
+<MenuBar>
+ <Menu name="game"><text>&amp;Game</text>
+ </Menu>
+ <Menu name="settings"><text>&amp;Settings</text>
+ <Action name="options_show_mousecursor" append="show_merge"/>
+ <Action name="options_select_graphic_scheme" append="configure_merge"/>
+ <Action name="options_focus_out_pause" append="configure_merge"/>
+ <Action name="options_focus_in_continue" append="configure_merge"/>
+ </Menu>
+</MenuBar>
+
+<ToolBar noMerge="1" name="mainToolBar"><text>Main Toolbar</text>
+ <Action name="game_new"/>
+ <Action name="game_pause"/>
+</ToolBar>
+</kpartgui>
diff --git a/tdepacman/tdepacmanview.cpp b/tdepacman/tdepacmanview.cpp
new file mode 100644
index 0000000..1a9d3e4
--- /dev/null
+++ b/tdepacman/tdepacmanview.cpp
@@ -0,0 +1,163 @@
+/***************************************************************************
+ tdepacmanview.cpp - description
+ -------------------
+ begin : Sam Jan 19 13:37:57 CET 2002
+ copyright : (C) 1998-2003 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 files for TQt
+#include <tqmessagebox.h>
+
+// include files for TDE
+#include <kapp.h>
+#include <tdeconfig.h>
+#include <kstddirs.h>
+
+// application specific includes
+#include "tdepacmanview.h"
+#include "bitfont.h"
+#include "score.h"
+#include "referee.h"
+#include "status.h"
+
+TDEpacmanView::TDEpacmanView( TQWidget *parent, const char *name) : TQWidget( 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);
+
+ setFixedSize(referee->width(), bitfont->height()*3 + referee->height() + status->height());
+}
+
+TDEpacmanView::~TDEpacmanView()
+{
+}
+
+void TDEpacmanView::confMisc(bool defGroup)
+{
+ TDEStandardDirs *dirs = TDEGlobal::dirs();
+ TQString findPath;
+
+ if (defGroup || kapp->config()->hasKey("Font")) {
+ fontName = kapp->config()->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);
+ if (!findPath.isEmpty())
+ fontName = findPath;
+
+ bitfontFirstChar = kapp->config()->readNumEntry("FontFirstChar", 0x0e);
+ bitfontLastChar = kapp->config()->readNumEntry("FontLastChar", 0x5f);
+ }
+}
+
+void TDEpacmanView::confScheme()
+{
+ TQString lastFontName = fontName;
+ TQString oldgroup = kapp->config()->group();
+ TQString newgroup;
+
+ // if not set, read mode and scheme from the configfile
+ if (mode == -1 && scheme == -1) {
+ scheme = kapp->config()->readNumEntry("Scheme", -1);
+ mode = kapp->config()->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);
+ kapp->config()->setGroup(newgroup);
+
+ mode = kapp->config()->readNumEntry("Mode", -1);
+ kapp->config()->setGroup(oldgroup);
+ }
+ }
+
+ confMisc();
+
+ if (mode != -1) {
+ newgroup.sprintf("Mode %d", mode);
+ kapp->config()->setGroup(newgroup);
+
+ confMisc(FALSE);
+ }
+
+ if (scheme != -1) {
+ newgroup.sprintf("Scheme %d", scheme);
+ kapp->config()->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) {
+ TQString 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(TQRegExp("@FONTNAME@"), fontName);
+ // TQMessageBox::critical(this, i18n("Initialization Error"), msg);
+ printf("%s\n", msg.local8Bit().data());
+ }
+ }
+
+ kapp->config()->setGroup(oldgroup);
+}
+
+void TDEpacmanView::setScheme(int Scheme, int Mode)
+{
+ mode = Mode;
+ scheme = Scheme;
+
+ confScheme();
+
+ score->setScheme(Scheme, Mode, bitfont);
+ referee->setScheme(Scheme, Mode, bitfont);
+ status->setScheme(Scheme, Mode);
+
+ setFixedSize(referee->width(),
+ bitfont->height()*3 + referee->height() + status->height());
+ updateGeometry();
+
+ score->repaint(FALSE);
+ referee->repaint(FALSE);
+ status->repaint(FALSE);
+}
+
+void TDEpacmanView::resizeEvent( TQResizeEvent * )
+{
+ 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);
+}
+
+#include "tdepacmanview.moc"
diff --git a/tdepacman/tdepacmanview.h b/tdepacman/tdepacmanview.h
new file mode 100644
index 0000000..a7792df
--- /dev/null
+++ b/tdepacman/tdepacmanview.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+ tdepacmanview.h - description
+ -------------------
+ begin : Sam Jan 19 13:37:57 CET 2002
+ copyright : (C) 1998-2003 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef TDEPACMANVIEW_H
+#define TDEPACMANVIEW_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+//include files for TQt
+#include <tqwidget.h>
+#include <tqregexp.h>
+
+// application specific includes
+#include "score.h"
+#include "referee.h"
+#include "status.h"
+#include "painter.h"
+
+/** The TDEpacmanView class provides the view widget for the TDEpacmanApp instance.
+ * The View instance inherits TQWidget as a base class and represents the view object of a KTMainWindow.
+ */
+class TDEpacmanView : public TQWidget
+{
+ Q_OBJECT
+public:
+ /** Constructor for the main view */
+ TDEpacmanView ( TQWidget *parent = 0, const char *name = 0);
+ /** Destructor for the main view */
+ virtual ~TDEpacmanView();
+
+ void setScheme(int scheme=-1, int mode=-1);
+ Score *score;
+ Referee *referee;
+ Status *status;
+
+protected:
+ void confScheme();
+ void confMisc(bool defGroup=TRUE);
+ void resizeEvent( TQResizeEvent * );
+
+private:
+ Bitfont *bitfont;
+ uchar bitfontFirstChar;
+ uchar bitfontLastChar;
+
+ TQString fontName;
+
+ int scheme;
+ int mode;
+};
+
+#endif // TDEPACMANVIEW_H