summaryrefslogtreecommitdiff
path: root/noncore/games/kpacman
authorleseb <leseb>2002-04-15 22:40:28 (UTC)
committer leseb <leseb>2002-04-15 22:40:28 (UTC)
commita91544d04ed391bbdc0c6f95ff8a80d35190788c (patch) (unidiff)
tree85dea85fd8a1cdb6d2d18fef57753d0b5e4bd143 /noncore/games/kpacman
parent6396d8b9fca7f3f50010a13a26e4ee9569abefb3 (diff)
downloadopie-a91544d04ed391bbdc0c6f95ff8a80d35190788c.zip
opie-a91544d04ed391bbdc0c6f95ff8a80d35190788c.tar.gz
opie-a91544d04ed391bbdc0c6f95ff8a80d35190788c.tar.bz2
New directory structure
Diffstat (limited to 'noncore/games/kpacman') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/kpacman/bitfont.cpp71
-rw-r--r--noncore/games/kpacman/bitfont.h31
-rw-r--r--noncore/games/kpacman/bitmaps.h67
-rw-r--r--noncore/games/kpacman/board.cpp425
-rw-r--r--noncore/games/kpacman/board.h102
-rw-r--r--noncore/games/kpacman/colors.h21
-rw-r--r--noncore/games/kpacman/config.cpp394
-rw-r--r--noncore/games/kpacman/config.h74
-rw-r--r--noncore/games/kpacman/energizer.cpp61
-rw-r--r--noncore/games/kpacman/energizer.h30
-rw-r--r--noncore/games/kpacman/fruit.cpp176
-rw-r--r--noncore/games/kpacman/fruit.h53
-rw-r--r--noncore/games/kpacman/keys.cpp203
-rw-r--r--noncore/games/kpacman/keys.h48
-rw-r--r--noncore/games/kpacman/kpacman.cpp369
-rw-r--r--noncore/games/kpacman/kpacman.h95
-rw-r--r--noncore/games/kpacman/kpacman.moc.cpp73
-rw-r--r--noncore/games/kpacman/kpacman.pro42
-rw-r--r--noncore/games/kpacman/kpacmanwidget.cpp162
-rw-r--r--noncore/games/kpacman/kpacmanwidget.h50
-rw-r--r--noncore/games/kpacman/main.cpp66
-rw-r--r--noncore/games/kpacman/monster.cpp262
-rw-r--r--noncore/games/kpacman/monster.h62
-rw-r--r--noncore/games/kpacman/opie-kpacman.control11
-rwxr-xr-xnoncore/games/kpacman/opie-kpacman.postinst6
-rw-r--r--noncore/games/kpacman/pacman.cpp147
-rw-r--r--noncore/games/kpacman/pacman.h47
-rw-r--r--noncore/games/kpacman/painter.cpp972
-rw-r--r--noncore/games/kpacman/painter.h148
-rw-r--r--noncore/games/kpacman/portable.h63
-rw-r--r--noncore/games/kpacman/referee.cpp1426
-rw-r--r--noncore/games/kpacman/referee.h196
-rw-r--r--noncore/games/kpacman/score.cpp642
-rw-r--r--noncore/games/kpacman/score.h129
-rw-r--r--noncore/games/kpacman/status.cpp367
-rw-r--r--noncore/games/kpacman/status.h78
36 files changed, 7169 insertions, 0 deletions
diff --git a/noncore/games/kpacman/bitfont.cpp b/noncore/games/kpacman/bitfont.cpp
new file mode 100644
index 0000000..40581c8
--- a/dev/null
+++ b/noncore/games/kpacman/bitfont.cpp
@@ -0,0 +1,71 @@
1#include "bitfont.h"
2
3Bitfont::Bitfont(QString fontname, uchar firstChar, uchar lastChar)
4{
5 if (!fontname.isEmpty())
6 font.load(fontname);
7 if (font.width() == font.height()) {
8 fontWidth = fontHeight = font.width() / 16;
9 fontFirstChar = 1;
10 fontLastChar = 255;
11 } else {
12 fontWidth = font.width()/(lastChar-firstChar+1);
13 fontHeight = font.height();
14 fontFirstChar = firstChar;
15 fontLastChar = lastChar;
16 }
17}
18
19QRect Bitfont::rect(QString str)
20{
21 return QRect(0, 0, str.length()*fontWidth, fontHeight);
22}
23
24QPixmap Bitfont::text(QString str, QColor fg, QColor bg)
25{
26 QPixmap FG(str.length()*fontWidth, fontHeight);
27 QBitmap MASK(str.length()*fontWidth, fontHeight, TRUE);
28
29 const uchar *s = (const uchar *) str.data();
30 for (uint i = 0; i < str.length(); i++) {
31 if (font.width() == font.height())
32 bitBlt(&MASK, i*fontWidth, 0, &font,
33 (*s%16)*fontWidth, (*s/16)*fontWidth, fontWidth, fontHeight);
34 else
35 if (*s >= fontFirstChar && *s <= fontLastChar)
36 bitBlt(&MASK, i*fontWidth, 0, &font,
37 (*s-fontFirstChar)*fontWidth, 0, fontWidth, fontHeight);
38 s++;
39 }
40
41 FG.fill(fg);
42 FG.setMask(MASK);
43
44 if (bg.isValid()) {
45 QPixmap BG(str.length()*fontWidth, fontHeight);
46 BG.fill(bg);
47 bitBlt(&BG, 0, 0, &FG);
48 return BG;
49 } else
50 return FG;
51}
52
53uchar Bitfont::firstChar()
54{
55 return fontFirstChar;
56}
57
58uchar Bitfont::lastChar()
59{
60 return fontLastChar;
61}
62
63int Bitfont::width()
64{
65 return fontWidth;
66}
67
68int Bitfont::height()
69{
70 return fontHeight;
71}
diff --git a/noncore/games/kpacman/bitfont.h b/noncore/games/kpacman/bitfont.h
new file mode 100644
index 0000000..c12aa0f
--- a/dev/null
+++ b/noncore/games/kpacman/bitfont.h
@@ -0,0 +1,31 @@
1#ifndef BITFONT_H
2#define BITFONT_H
3
4#include <qstring.h>
5#include <qbitmap.h>
6#include <qpixmap.h>
7#include <qrect.h>
8
9#include "colors.h"
10
11class Bitfont
12{
13public:
14 Bitfont(QString fontname, uchar firstChar, uchar lastChar);
15
16 QPixmap text(QString str, QColor fg = BLACK, QColor bg = QColor());
17 QRect rect(QString str);
18 int width();
19 int height();
20 uchar firstChar();
21 uchar lastChar();
22private:
23 QBitmap font;
24 int fontWidth;
25 int fontHeight;
26 uchar fontFirstChar;
27 uchar fontLastChar;
28};
29
30#endif // BITFONT_H
31
diff --git a/noncore/games/kpacman/bitmaps.h b/noncore/games/kpacman/bitmaps.h
new file mode 100644
index 0000000..f430384
--- a/dev/null
+++ b/noncore/games/kpacman/bitmaps.h
@@ -0,0 +1,67 @@
1static unsigned char demo_bits[] = {
2 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
3 "++*******************************************************++"
4 "+*********************************************************+"
5 "+** *** **+"
6 "+** . . . . . . . . . . . . *** . . . . . . . . . . . . **+"
7 "+** *** **+"
8 "+** . ******* . ********* . *** . ********* . ******* . **+"
9 "+** ******* ********* *** ********* ******* **+"
10 "+** o ******* . ********* . *** . ********* . ******* o **+"
11 "+** ******* ********* *** ********* ******* **+"
12 "+** . ******* . ********* . *** . ********* . ******* . **+"
13 "+** **+"
14 "+** . . . . . . . . . . . . . . . . . . . . . . . . . . **+"
15 "+** **+"
16 "+** . ******* . *** . *************** . *** . ******* . **+"
17 "+** ******* *** *************** *** ******* **+"
18 "+** . ******* . *** . *************** . *** . ******* . **+"
19 "+** *** *** *** **+"
20 "+** . . . . . . *** . . . . *** . . . . *** . . . . . . **+"
21 "+** *** *** *** **+"
22 "+************ . ********* *** ********* . ************+"
23 "++*********** ********* *** ********* ***********++"
24 "+++++++++++** . ********* *** ********* . **+++++++++++"
25 "+++++++++++** *** *** **+++++++++++"
26 "+++++++++++** . *** 0 *** . **+++++++++++"
27 "+++++++++++** *** *** **+++++++++++"
28 "+++++++++++** . *** ######---###### *** . **+++++++++++"
29 "+************ *** ######---###### *** ************+"
30 "+************ . *** ## ## *** . ************+"
31 " ## ## "
32 " . ## 2 1 3 ## . "
33 " ## ## "
34 "+************ . *** ## ## *** . ************+"
35 "+************ *** ############### *** ************+"
36 "+++++++++++** . *** ############### *** . **+++++++++++"
37 "+++++++++++** *** *** **+++++++++++"
38 "+++++++++++** . *** F *** . **+++++++++++"
39 "+++++++++++** *** *** **+++++++++++"
40 "+++++++++++** . *** *************** *** . **+++++++++++"
41 "++*********** *** *************** *** ***********++"
42 "+************ . *** *************** *** . ************+"
43 "+** *** **+"
44 "+** . . . . . . . . . . . . *** . . . . . . . . . . . . **+"
45 "+** *** **+"
46 "+** . ******* . ********* . *** . ********* . ******* . **+"
47 "+** ******* ********* *** ********* ******* **+"
48 "+** . ******* . ********* . *** . ********* . ******* . **+"
49 "+** *** *** **+"
50 "+** o . . *** . . . . . . . P . . . . . . . *** . . o **+"
51 "+** *** *** **+"
52 "+****** . *** . *** . *************** . *** . *** . ******+"
53 "+****** *** *** *************** *** *** ******+"
54 "+****** . *** . *** . *************** . *** . *** . ******+"
55 "+** *** *** *** **+"
56 "+** . . . . . . *** . . . . *** . . . . *** . . . . . . **+"
57 "+** *** *** *** **+"
58 "+** . ******************* . *** . ******************* . **+"
59 "+** ******************* *** ******************* **+"
60 "+** . ******************* . *** . ******************* . **+"
61 "+** **+"
62 "+** . . . . . . . . . . . . . . . . . . . . . . . . . . **+"
63 "+** **+"
64 "+*********************************************************+"
65 "++*******************************************************++"
66 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
67};
diff --git a/noncore/games/kpacman/board.cpp b/noncore/games/kpacman/board.cpp
new file mode 100644
index 0000000..849e75b
--- a/dev/null
+++ b/noncore/games/kpacman/board.cpp
@@ -0,0 +1,425 @@
1
2#include "portable.h"
3
4#if defined( KDE2_PORT )
5#include <kapp.h>
6#include <klocale.h>
7#endif
8
9#include <qrect.h>
10#include <qregexp.h>
11#include <qmessagebox.h>
12#include <qfile.h>
13#include <qtextstream.h>
14
15#include "board.h"
16#include "bitmaps.h"
17
18Board::Board(int size) : QArray<int> (size)
19{
20 sz = size; // set size of board
21
22 map = "";
23 mapName = ""; // no map loaded so far
24
25 init(None); // initialize varibales
26}
27
28void Board::init(Image image, QString levelName)
29{
30 prisonEntry = OUT;
31 prisonExit = OUT;
32 fruitHome = OUT;
33 fruitPosition = OUT;
34 pacmanHome = OUT;
35 pacmanPosition = OUT;
36 for (int m = 0; m < 8; m++) {
37 monsterHome[m] = OUT;
38 monsterPosition[m] = OUT;
39 }
40 for (int e = 0; e < 8; e++) {
41 energizerPosition[e] = OUT;
42 }
43 for (int e = 0; e < 8; e++) {
44 tunnelPosition[e] = OUT;
45 }
46
47 fill(0);
48 numPoints = 0;
49 numEnergizers = 0;
50 numMonsters = 0;
51 numTunnels = 0;
52
53 if (!levelName.isNull() && !levelName.isEmpty())
54 if (mapName == levelName)
55 image = File;
56 else {
57 QFile levelFile(levelName);
58 if (!levelFile.open(IO_ReadOnly)) {
59
60 QString msg = i18n("The levelmap could not be constructed.\n\n"
61 "The file '@LEVELNAME@' does not exist,\n"
62 "or could not be opened for reading.");
63 msg.replace(QRegExp("@LEVELNAME@"), levelName);
64 // QMessageBox::information(0, i18n("Initialization Error"), msg);
65 printf("%s\n", msg.data());
66 } else {
67 map.fill(' ', BoardHeight*BoardWidth);
68 int height = 0;
69
70 QTextStream levelStream(&levelFile);
71 while (!levelStream.eof() && height < BoardHeight) {
72 QString line = levelStream.readLine();
73
74 if (line.find(QRegExp("^ *;")) == -1) {
75
76 line.replace(QRegExp(";.*"), ""); // strip off comments
77 line.replace(QRegExp("\" *$"), ""); // strip off trailing "
78 line.replace(QRegExp("^ *\""), ""); // strip off leading "
79
80 map.replace(height*BoardWidth,
81 (line.length() > BoardWidth) ? BoardWidth : line.length(),
82 line.data());
83
84 height++;
85 }
86 }
87 mapName = levelName;
88 levelFile.close();
89 image = File;
90 }
91 }
92
93 switch (image) {
94 case Intro : // setup(demo_bits);
95 break;
96 case Demo : setup(demo_bits);
97 break;
98 case Level : setup(demo_bits);
99 break;
100 case File : setup((uchar *) map.data());
101 break;
102 default : break;
103 }
104}
105
106void Board::setup(const uchar *buf)
107{
108 for ( int index = 0; buf[index] != 0 && index < BoardWidth*BoardHeight; index++ ) {
109 switch (buf[index]) {
110 case '*' : set(index, brick); break;
111 case '+' : set(index, out); break;
112 case '#' : set(index, prison); break;
113 case '-' : set(index, gate); break;
114 case 'E' : set(index, tunnel); break;
115 case '.' : set(index, Point); break;
116 case 'o' : set(index, energizer); break;
117 case 'I' : set(index, prisonentry); break;
118 case 'O' : set(index, prisonexit); break;
119 case 'F' : set(index, fruithome); break;
120 case 'P' : set(index, pacmanhome); break;
121 default : if (buf[index] >= '0' && buf[index] <= '7') {
122 set(index, monsterhome, buf[index]-(uchar)'0');
123 }
124 }
125 }
126}
127
128bool Board::inBounds(int pos)
129{
130 return ( pos < 0 || pos > sz-1 ? FALSE : TRUE);
131}
132
133void Board::set(int pos, Square sq, int m)
134{
135 if (inBounds(pos))
136 switch (sq) {
137 case out : at(pos) = OUT; break;
138 case Point : at(pos) |= pointBit; numPoints++; break;
139 case tunnel : at(pos) = sq;
140 for (int e = 0; e < numTunnels; e++) { // if tunnel is already on board
141 if (tunnelPosition[e] == pos) // don't do it again.
142 pos = OUT;
143 }
144 if (pos != OUT) {
145 tunnelPosition[numTunnels] = pos;
146 numTunnels++;
147 }
148 break;
149 case energizer : at(pos) |= energizerBit;
150 for (int e = 0; e < numEnergizers; e++) {
151 if (energizerPosition[e] == pos)
152 pos = OUT;
153 }
154 if (pos != OUT) {
155 energizerPosition[numEnergizers] = pos;
156 numEnergizers++;
157 }
158 break;
159 case fruit : at(pos) |= fruitBit; fruitPosition = pos; break;
160 case pacman : at(pos) |= pacmanBit; pacmanPosition = pos; break;
161 case monster : at(pos) |= (monsterBit << m);
162 monsterPosition[m] = pos; break;
163 case prisonentry : prisonEntry = pos; at(pos) = empty; break;
164 case prisonexit : prisonExit = pos; at(pos) = empty; break;
165 case fruithome : fruitHome = pos; at(pos) = empty; break;
166 case pacmanhome : pacmanHome = pos; at(pos) = empty; break;
167 case monsterhome : monsterHome[m] = pos; at(pos) = empty;
168 if (m == 0 && prisonExit == OUT)
169 prisonExit = pos;
170 if (m == 1 && prisonEntry == OUT)
171 prisonEntry = pos;
172 numMonsters++;
173 break;
174 default : at(pos) = sq;
175 }
176}
177
178void Board::reset(int pos, Square sq, int m)
179{
180 bool found = FALSE;
181 if (inBounds(pos))
182 switch (sq) {
183 case out : at(pos) = empty; break;
184 case Point : at(pos) &= ~ pointBit; numPoints--; break;
185 case energizer : at(pos) &= ~ energizerBit;
186 for (int e = 0; e < numEnergizers; e++) { // delete the position of the eaten
187 if (found) // energizer in the position array
188 energizerPosition[e-1] = energizerPosition[e];
189 if (energizerPosition[e] == pos)
190 found = TRUE;
191 }
192 energizerPosition[numEnergizers--] = OUT;
193 break;
194 case fruit : at(pos) &= ~ fruitBit; fruitPosition = OUT; break;
195 case pacman : at(pos) &= ~ pacmanBit; pacmanPosition = OUT; break;
196 case monster : at(pos) &= ~ (monsterBit << m);
197 monsterPosition[m] = OUT; break;
198 default : at(pos) = at(pos) & varBits;
199 }
200}
201
202int Board::position(Square sq, int m)
203{
204 switch(sq) {
205 case prisonentry : return prisonEntry;
206 case prisonexit : return prisonExit;
207 case fruit : return fruitPosition;
208 case fruithome : return fruitHome;
209 case pacman : return pacmanPosition;
210 case pacmanhome : return pacmanHome;
211 case monster : return monsterPosition[m];
212 case monsterhome : return monsterHome[m];
213 case energizer : return energizerPosition[m];
214 case tunnel : return tunnelPosition[m];
215 default : return OUT;
216 }
217}
218
219bool Board::isOut(int pos)
220{
221 if (inBounds(pos))
222 return (at(pos) == OUT ? TRUE : FALSE);
223 return TRUE;
224}
225
226bool Board::isEmpty(int pos)
227{
228 if (inBounds(pos))
229 return ((at(pos) & fixBits) == empty ? TRUE : FALSE);
230 return TRUE;
231}
232
233bool Board::isBrick(int pos)
234{
235 if (inBounds(pos))
236 return ((at(pos) & fixBits) == brick ? TRUE : FALSE);
237 return FALSE;
238}
239
240bool Board::isPrison(int pos)
241{
242 if (inBounds(pos))
243 return ((at(pos) & fixBits) == prison ? TRUE : FALSE);
244 return FALSE;
245}
246
247bool Board::isGate(int pos)
248{
249 if (inBounds(pos))
250 return ((at(pos) & fixBits) == gate ? TRUE : FALSE);
251 return FALSE;
252}
253
254bool Board::isTunnel(int pos)
255{
256 if (inBounds(pos))
257 return ((at(pos) & fixBits) == tunnel ? TRUE : FALSE);
258 return FALSE;
259}
260
261bool Board::isPoint(int pos)
262{
263 if (inBounds(pos) && at(pos) != OUT)
264 return ((at(pos) & pointBit) != 0 ? TRUE : FALSE);
265 return FALSE;
266}
267
268bool Board::isEnergizer(int pos)
269{
270 if (inBounds(pos) && at(pos) != OUT)
271 return ((at(pos) & energizerBit) != 0 ? TRUE : FALSE);
272 return FALSE;
273}
274
275bool Board::isFruit(int pos)
276{
277 if (inBounds(pos) && at(pos) != OUT)
278 return ((at(pos) & fruitBit) != 0 ? TRUE : FALSE);
279 return FALSE;
280}
281
282bool Board::isPacman(int pos)
283{
284 if (inBounds(pos) && at(pos) != OUT)
285 return ((at(pos) & pacmanBit) != 0 ? TRUE : FALSE);
286 return FALSE;
287}
288
289bool Board::isMonster(int pos)
290{
291 if (inBounds(pos) && at(pos) != OUT)
292 return ((at(pos) & monsterBits) != 0 ? TRUE : FALSE);
293 return FALSE;
294}
295
296bool Board::isWay(int pos, int dir, Square sq) {
297 int p1 = move(pos, dir, 2);
298 if (p1 == OUT)
299 return (sq == out ? TRUE : FALSE);
300 int p2, p3;
301 if (dir == N || dir == S) {
302 p2 = move(p1, E);
303 p3 = move(p1, W);
304 } else {
305 p2 = move(p1, N);
306 p3 = move(p1, S);
307 }
308 switch (sq) {
309 case out : return isOut(p1) | isOut(p2) | isOut(p3);
310 case empty : return isEmpty(p1) & isEmpty(p2) & isEmpty(p3);
311 case brick : return isBrick(p1) | isBrick(p2) | isBrick(p3);
312 case prison : return isPrison(p1) | isPrison(p2) | isPrison(p3);
313 case gate : return isGate(p1) & isGate(p2) & isGate(p3);
314 case tunnel : return isTunnel(p1) &
315 (isTunnel(p2) || isEmpty(p2)) &
316 (isTunnel(p3) || isEmpty(p3));
317 default : return FALSE;
318 }
319}
320
321bool Board::isJump(int pos, int dir) {
322 switch (dir) {
323 case NW: return pos < BoardWidth || x(pos) == 0;
324 case N: return pos < BoardWidth;
325 case NE: return pos < BoardWidth || x(pos) == BoardWidth-1;
326 case W: return x(pos) == 0;
327 case E: return x(pos) == BoardWidth-1;
328 case SW: return pos >= sz-BoardWidth || x(pos) == 0;
329 case S: return pos >= sz-BoardWidth;
330 case SE: return pos >= sz-BoardWidth || x(pos) == BoardWidth-1;
331 }
332 return FALSE;
333}
334
335int Board::move(int pos, int dir, int steps)
336{
337 if (steps < 0) { // move backwards
338 dir = turn(dir); // turn around and do your steps
339 steps *= -1;
340 }
341
342 while (steps-- != 0) { // until all steps are gone
343 switch (dir) {
344 case NW: pos = pos >= BoardWidth && x(pos) > 0 ? (pos-BoardWidth)-1 : sz-1;
345 break;
346 case N: pos = pos >= BoardWidth ? pos-BoardWidth : (sz-BoardWidth)+x(pos);
347 break;
348 case NE: pos = pos >= BoardWidth && x(pos) < BoardWidth-1 ?
349 (pos-BoardWidth)+1 : sz-BoardWidth;
350 break;
351 case W: pos = x(pos) > 0 ? pos-1 : pos+(BoardWidth-1);
352 break;
353 case E: pos = x(pos) < BoardWidth-1 ? pos+1 : pos-(BoardWidth-1);
354 break;
355 case SW: pos = pos < sz-BoardWidth && x(pos) > 0 ? (pos+BoardWidth)-1 : BoardWidth-1;
356 break;
357 case S: pos = pos < sz-BoardWidth ? pos+BoardWidth : x(pos);
358 break;
359 case SE: pos = pos < sz-BoardWidth && x(pos) < BoardWidth-1 ? (pos+BoardWidth)+1 : 0;
360 break;
361 }
362 }
363 return pos; // here we are
364}
365
366int Board::closeup(int pos, int dir, int target)
367{
368 if (dir == N || dir == S) {
369 if (x(target) < x(pos))
370 return W;
371 if (x(target) > x(pos))
372 return E;
373 } else {
374 if (y(target) < y(pos))
375 return N;
376 if (y(target) > y(pos))
377 return S;
378 }
379 return dir;
380}
381
382int Board::x(int pos)
383{
384 return pos % BoardWidth;
385}
386
387int Board::y(int pos)
388{
389 return pos/BoardWidth;
390}
391
392int Board::turn(int dir)
393{
394 switch (dir) {
395 case N : return S;
396 case NE : return SW;
397 case E : return W;
398 case SE : return NW;
399 case S : return N;
400 case SW : return NE;
401 case W : return E;
402 case NW : return SE;
403 default : return dir;
404 }
405}
406
407int Board::points()
408{
409 return numPoints;
410}
411
412int Board::energizers()
413{
414 return numEnergizers;
415}
416
417int Board::monsters()
418{
419 return numMonsters;
420}
421
422int Board::tunnels()
423{
424 return numTunnels;
425}
diff --git a/noncore/games/kpacman/board.h b/noncore/games/kpacman/board.h
new file mode 100644
index 0000000..fffde95
--- a/dev/null
+++ b/noncore/games/kpacman/board.h
@@ -0,0 +1,102 @@
1#ifndef BOARD_H
2#define BOARD_H
3
4#include <qarray.h>
5#include <qstring.h>
6#include <qlist.h>
7#include <qrect.h>
8
9#define OUT -1
10
11enum Square {out = OUT, empty, brick, prison, gate, tunnel, prisonentry, prisonexit,
12 Point, energizer, fruit, pacman, monster,
13 fruithome, pacmanhome, monsterhome};
14
15enum Image { None, Intro, Demo, Level, File };
16
17#define X -1
18#define N 0
19#define S 1
20#define E 2
21#define W 3
22#define NE 4
23#define SE 5
24#define NW 6
25#define SW 7
26
27#define BoardWidth 59
28#define BoardHeight 65
29
30#define fixBits 0x0007
31#define varBits 0xFFF8
32#define monsterBits 0xFF00
33
34#define pointBit 0x0008
35#define energizerBit 0x0010
36#define fruitBit 0x0020
37#define pacmanBit 0x0040
38#define monsterBit 0x0100
39
40class Board : public QArray<int>
41{
42public:
43 Board (int size);
44 ~Board() {};
45 void init(Image image, QString levelName=0);
46 void setup(const uchar *buf);
47
48 void set(int pos, Square sq, int m = 0);
49 void reset(int pos, Square sq, int m = 0);
50 int position(Square sq, int m = 0);
51
52 bool isOut(int pos);
53 bool isEmpty(int pos);
54 bool isBrick(int pos);
55 bool isPrison(int pos);
56 bool isGate(int pos);
57 bool isTunnel(int pos);
58 bool isPoint(int pos);
59 bool isEnergizer(int pos);
60 bool isFruit(int pos);
61 bool isPacman(int pos);
62 bool isMonster(int pos);
63 bool isWay(int pos, int dir, Square sq);
64 bool isJump(int pos, int dir);
65
66 int move(int pos, int dir, int steps = 1);
67 int closeup(int pos, int dir, int target);
68 int x(int pos);
69 int y(int pos);
70 int turn(int dir);
71
72 int points();
73 int energizers();
74 int monsters();
75 int tunnels();
76
77private:
78 bool inBounds(int pos);
79 int sz; // size of board
80
81 QString map;
82 QString mapName; // Filename of the latest loaded map
83
84 int prisonEntry; // position of prisonentry
85 int prisonExit; // position of prisonexit
86 int pacmanHome; // startposition of pacman
87 int monsterHome[8]; // startposition of monsters
88 int fruitHome; // startposition of fruit
89
90 int pacmanPosition; // actual position of pacman
91 int monsterPosition[8]; // actual position of monsters
92 int fruitPosition; // actual position of fruit
93 int energizerPosition[8]; // actual position of energizers
94 int tunnelPosition[8]; // position of tunnels
95
96 int numMonsters; // number of monsters on the board
97 int numPoints; // number of points (left) on the board
98 int numEnergizers; // number of energizers (left)
99 int numTunnels; // number of tunnels on the board
100};
101
102#endif // BOARD_H
diff --git a/noncore/games/kpacman/colors.h b/noncore/games/kpacman/colors.h
new file mode 100644
index 0000000..6abf385
--- a/dev/null
+++ b/noncore/games/kpacman/colors.h
@@ -0,0 +1,21 @@
1#ifndef COLORS_H
2#define COLORS_H
3
4#include <qcolor.h>
5
6#define BLACK QColor(Qt::black)
7#define RED QColor(Qt::red)
8#define BROWN QColor(0xde, 0x95, 0x41)
9#define PINK QColor(0xff, 0xba, 0xde)
10#define CYAN QColor(0x00, 0xff, 0xde)
11#define LIGHTBLUE QColor(0x41, 0xba, 0xde)
12#define ORANGE QColor(0xff, 0xba, 0x41)
13#define YELLOW QColor(Qt::yellow)
14#define BLUE QColor(0x20, 0x20, 0xde)
15#define GREEN QColor(Qt::green)
16#define LIGHTGREEN QColor(0x41, 0xba, 0x94)
17#define FLESH QColor(0xff, 0xba, 0x94)
18#define WHITE QColor(0xd8, 0xdc, 0xd8)
19
20#endif // COLORS_H
21
diff --git a/noncore/games/kpacman/config.cpp b/noncore/games/kpacman/config.cpp
new file mode 100644
index 0000000..b9e3607
--- a/dev/null
+++ b/noncore/games/kpacman/config.cpp
@@ -0,0 +1,394 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19** $Id$
20**
21**********************************************************************/
22
23#include "config.h"
24
25#include <qfile.h>
26#include <qdir.h>
27#include <qfileinfo.h>
28#include <qtextstream.h>
29#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
30#include <qtextcodec.h>
31#endif
32#include <stdlib.h>
33#include <sys/stat.h>
34#include <sys/types.h>
35#include <fcntl.h>
36#include <unistd.h>
37
38/*!
39 \internal
40*/
41QString Config::configFilename(const QString& name, Domain d)
42{
43 switch (d) {
44 case File:
45 return name;
46 case User: {
47 QDir dir = (QString(getenv("HOME")) + "/Settings");
48 if ( !dir.exists() )
49 mkdir(dir.path().local8Bit(),0700);
50 return dir.path() + "/" + name + ".conf";
51 }
52 }
53 return name;
54}
55
56/*!
57 \class Config config.h
58 \brief The Config class provides for saving application cofniguration state.
59
60 You should keep a Config in existence only while you do not want others
61 to be able to change the state. There is no locking currently, but there
62 may be in the future.
63*/
64
65/*!
66 \enum Config::ConfigGroup
67 \internal
68*/
69
70/*!
71 \enum Config::Domain
72
73 \value File
74 \value User
75
76 See Config for details.
77*/
78
79/*!
80 Constructs a config that will load or create a configuration with the
81 given \a name in the given \a domain.
82
83 You must call setGroup() before doing much else with the Config.
84
85 In the default Domain, \e User,
86 the configuration is user-specific. \a name should not contain "/" in
87 this case, and in general should be the name of the C++ class that is
88 primarily responsible for maintaining the configuration.
89
90 In the File Domain, \a name is an absolute filename.
91*/
92Config::Config( const QString &name, Domain domain )
93 : filename( configFilename(name,domain) )
94{
95 git = groups.end();
96 read();
97
98 lang = getenv("LANG");
99 int i = lang.find(".");
100 if ( i > 0 )
101 lang = lang.left( i );
102 i = lang.find( "_" );
103 if ( i > 0 )
104 glang = lang.left(i);
105}
106
107/*!
108 Writes any changes to disk and destroys the in-memory object.
109*/
110Config::~Config()
111{
112 if ( changed )
113 write();
114}
115
116/*!
117 Returns whether the current group has an entry called \a key.
118*/
119bool Config::hasKey( const QString &key ) const
120{
121 if ( groups.end() == git )
122 return FALSE;
123 ConfigGroup::ConstIterator it = ( *git ).find( key );
124 return it != ( *git ).end();
125}
126
127/*!
128 Sets the current group for subsequent reading and writing of
129 entries to \a gname. Grouping allows the application to partition the namespace.
130
131 This function must be called prior to any reading or writing
132 of entries.
133
134 The \a gname must not be empty.
135*/
136void Config::setGroup( const QString &gname )
137{
138 QMap< QString, ConfigGroup>::Iterator it = groups.find( gname );
139 if ( it == groups.end() ) {
140 ConfigGroup *grp = new ConfigGroup;
141 git = groups.insert( gname, *grp );
142 changed = TRUE;
143 return;
144 }
145 git = it;
146}
147
148/*!
149 Writes a (\a key, \a value) entry to the current group.
150
151 \sa readEntry()
152*/
153void Config::writeEntry( const QString &key, const QString &value )
154{
155 if ( git == groups.end() ) {
156 qWarning( "no group set" );
157 return;
158 }
159 if ( (*git)[key] != value ) {
160 ( *git ).insert( key, value );
161 changed = TRUE;
162 }
163}
164
165/*!
166 Writes a (\a key, \a num) entry to the current group.
167
168 \sa readNumEntry()
169*/
170void Config::writeEntry( const QString &key, int num )
171{
172 QString s;
173 s.setNum( num );
174 writeEntry( key, s );
175}
176
177#ifdef Q_HAS_BOOL_TYPE
178/*!
179 Writes a (\a key, \a b) entry to the current group.
180
181 \sa readBoolEntry()
182*/
183void Config::writeEntry( const QString &key, bool b )
184{
185 QString s;
186 s.setNum( ( int )b );
187 writeEntry( key, s );
188}
189#endif
190
191/*!
192 Writes a (\a key, \a lst) entry to the current group. The list
193 is separated by \a sep, so the strings must not contain that character.
194
195 \sa readListEntry()
196*/
197void Config::writeEntry( const QString &key, const QStringList &lst, const QChar &sep )
198{
199 QString s;
200 QStringList::ConstIterator it = lst.begin();
201 for ( ; it != lst.end(); ++it )
202 s += *it + sep;
203 writeEntry( key, s );
204}
205
206
207
208/*!
209 Reads a string entry stored with \a key, defaulting to \a deflt if there is no entry.
210*/
211QString Config::readEntry( const QString &key, const QString &deflt )
212{
213 QString res = readEntryDirect( key+"["+lang+"]" );
214 if ( !res.isNull() )
215 return res;
216 if ( !glang.isEmpty() ) {
217 res = readEntryDirect( key+"["+glang+"]" );
218 if ( !res.isNull() )
219 return res;
220 }
221 return readEntryDirect( key, deflt );
222}
223
224/*!
225 \internal
226*/
227QString Config::readEntryDirect( const QString &key, const QString &deflt )
228{
229 if ( git == groups.end() ) {
230 //qWarning( "no group set" );
231 return deflt;
232 }
233 ConfigGroup::Iterator it = ( *git ).find( key );
234 if ( it != ( *git ).end() )
235 return *it;
236 else
237 return deflt;
238}
239
240/*!
241 Reads a numeric entry stored with \a key, defaulting to \a deflt if there is no entry.
242*/
243int Config::readNumEntry( const QString &key, int deflt )
244{
245 QString s = readEntry( key );
246 if ( s.isEmpty() )
247 return deflt;
248 else
249 return s.toInt();
250}
251
252/*!
253 Reads a bool entry stored with \a key, defaulting to \a deflt if there is no entry.
254*/
255bool Config::readBoolEntry( const QString &key, bool deflt )
256{
257 QString s = readEntry( key );
258 if ( s.isEmpty() )
259 return deflt;
260 else
261 return (bool)s.toInt();
262}
263
264/*!
265 Reads a string list entry stored with \a key, and with \a sep as the separator.
266*/
267QStringList Config::readListEntry( const QString &key, const QChar &sep )
268{
269 QString s = readEntry( key );
270 if ( s.isEmpty() )
271 return QStringList();
272 else
273 return QStringList::split( sep, s );
274}
275
276/*!
277 Removes all entries from the current group.
278*/
279void Config::clearGroup()
280{
281 if ( git == groups.end() ) {
282 qWarning( "no group set" );
283 return;
284 }
285 if ( !(*git).isEmpty() ) {
286 ( *git ).clear();
287 changed = TRUE;
288 }
289}
290
291/*!
292 \internal
293*/
294void Config::write( const QString &fn )
295{
296 if ( !fn.isEmpty() )
297 filename = fn;
298
299 QFile f( filename );
300 if ( !f.open( IO_WriteOnly ) ) {
301 qWarning( "could not open for writing `%s'", filename.latin1() );
302 git = groups.end();
303 return;
304 }
305
306 QTextStream s( &f );
307#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
308 // The below should work, but doesn't in Qt 2.3.0
309 s.setCodec( QTextCodec::codecForMib( 106 ) );
310#else
311 s.setEncoding( QTextStream::UnicodeUTF8 );
312#endif
313 QMap< QString, ConfigGroup >::Iterator g_it = groups.begin();
314 for ( ; g_it != groups.end(); ++g_it ) {
315 s << "[" << g_it.key() << "]" << "\n";
316 ConfigGroup::Iterator e_it = ( *g_it ).begin();
317 for ( ; e_it != ( *g_it ).end(); ++e_it )
318 s << e_it.key() << " = " << *e_it << "\n";
319 }
320
321 f.close();
322}
323
324/*!
325 Returns whether the Config is in a valid state.
326*/
327bool Config::isValid() const
328{
329 return groups.end() != git;
330}
331
332/*!
333 \internal
334*/
335void Config::read()
336{
337 changed = FALSE;
338
339 if ( !QFileInfo( filename ).exists() ) {
340 git = groups.end();
341 return;
342 }
343
344 QFile f( filename );
345 if ( !f.open( IO_ReadOnly ) ) {
346 git = groups.end();
347 return;
348 }
349
350 QTextStream s( &f );
351#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
352 // The below should work, but doesn't in Qt 2.3.0
353 s.setCodec( QTextCodec::codecForMib( 106 ) );
354#else
355 s.setEncoding( QTextStream::UnicodeUTF8 );
356#endif
357
358 QString line;
359 while ( !s.atEnd() ) {
360 line = s.readLine();
361 if ( !parse( line ) ) {
362 git = groups.end();
363 return;
364 }
365 }
366
367 f.close();
368}
369
370/*!
371 \internal
372*/
373bool Config::parse( const QString &l )
374{
375 QString line = l.stripWhiteSpace();
376 if ( line[ 0 ] == QChar( '[' ) ) {
377 QString gname = line;
378 gname = gname.remove( 0, 1 );
379 if ( gname[ (int)gname.length() - 1 ] == QChar( ']' ) )
380 gname = gname.remove( gname.length() - 1, 1 );
381 ConfigGroup *grp = new ConfigGroup;
382 git = groups.insert( gname, *grp );
383 } else if ( !line.isEmpty() ) {
384 if ( git == groups.end() )
385 return FALSE;
386 int eq = line.find( '=' );
387 if ( eq == -1 )
388 return FALSE;
389 QString key = line.left(eq).stripWhiteSpace();
390 QString value = line.mid(eq+1).stripWhiteSpace();
391 ( *git ).insert( key, value );
392 }
393 return TRUE;
394}
diff --git a/noncore/games/kpacman/config.h b/noncore/games/kpacman/config.h
new file mode 100644
index 0000000..3c26b5d
--- a/dev/null
+++ b/noncore/games/kpacman/config.h
@@ -0,0 +1,74 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Designer.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef CONFIG_H
22#define CONFIG_H
23
24// ##### could use QSettings with Qt 3.0
25
26#include <qmap.h>
27#include <qstringlist.h>
28
29class ConfigPrivate;
30class Config
31{
32public:
33 typedef QMap< QString, QString > ConfigGroup;
34
35 enum Domain { File, User };
36 Config( const QString &name, Domain domain=User );
37 ~Config();
38
39 bool isValid() const;
40 bool hasKey( const QString &key ) const;
41
42 void setGroup( const QString &gname );
43 void writeEntry( const QString &key, const QString &value );
44 void writeEntry( const QString &key, int num );
45#ifdef Q_HAS_BOOL_TYPE
46 void writeEntry( const QString &key, bool b );
47#endif
48 void writeEntry( const QString &key, const QStringList &lst, const QChar &sep );
49
50 QString readEntry( const QString &key, const QString &deflt = QString::null );
51 QString readEntryDirect( const QString &key, const QString &deflt = QString::null );
52 int readNumEntry( const QString &key, int deflt = -1 );
53 bool readBoolEntry( const QString &key, bool deflt = FALSE );
54 QStringList readListEntry( const QString &key, const QChar &sep );
55
56 void clearGroup();
57
58 void write( const QString &fn = QString::null );
59
60protected:
61 void read();
62 bool parse( const QString &line );
63
64 QMap< QString, ConfigGroup > groups;
65 QMap< QString, ConfigGroup >::Iterator git;
66 QString filename;
67 QString lang;
68 QString glang;
69 bool changed;
70 ConfigPrivate *d;
71 static QString configFilename(const QString& name, Domain);
72};
73
74#endif
diff --git a/noncore/games/kpacman/energizer.cpp b/noncore/games/kpacman/energizer.cpp
new file mode 100644
index 0000000..ca08f3b
--- a/dev/null
+++ b/noncore/games/kpacman/energizer.cpp
@@ -0,0 +1,61 @@
1#include "energizer.h"
2
3Energizer::Energizer(Board *b)
4{
5 board = b;
6 setOn();
7 actualPosition = OUT;
8 maxPixmaps = 0;
9}
10
11void Energizer::setMaxPixmaps(int max)
12{
13 maxPixmaps = max;
14}
15
16void Energizer::setOff()
17{
18 actualState = off;
19}
20
21void Energizer::setOn()
22{
23 actualState = on;
24 actualPix = 0;
25}
26
27void Energizer::setPosition(int pos)
28{
29 board->reset(actualPosition, energizer);
30 actualPosition = pos;
31 board->set(actualPosition, energizer);
32}
33
34energizerState Energizer::state()
35{
36 return actualState;
37}
38
39int Energizer::position()
40{
41 return actualPosition;
42}
43
44bool Energizer::move()
45{
46 if (actualPosition == OUT)
47 return FALSE;
48
49 if (++actualPix >= maxPixmaps)
50 actualPix = 0;
51
52 return TRUE;
53}
54
55int Energizer::pix()
56{
57 if (actualPosition == OUT || actualState == off)
58 return -1;
59
60 return actualPix;
61}
diff --git a/noncore/games/kpacman/energizer.h b/noncore/games/kpacman/energizer.h
new file mode 100644
index 0000000..377cd02
--- a/dev/null
+++ b/noncore/games/kpacman/energizer.h
@@ -0,0 +1,30 @@
1#ifndef ENERGIZER_H
2#define ENERGIZER_H
3
4#include "board.h"
5
6enum energizerState { on, off };
7
8class Energizer {
9public:
10 Energizer(Board *b);
11 void setMaxPixmaps(int max);
12 void setOff();
13 void setOn();
14 void setPosition(int pos);
15 energizerState state();
16 int position();
17 bool move();
18 int pix();
19
20private:
21 Board *board;
22
23 energizerState actualState; // the state of energizer
24
25 int actualPix; // last Pixmap-index
26 int maxPixmaps; // Number of Pixmaps (1..)
27 int actualPosition; // actual position on board
28};
29
30#endif // ENERGIZER_H
diff --git a/noncore/games/kpacman/fruit.cpp b/noncore/games/kpacman/fruit.cpp
new file mode 100644
index 0000000..e6ad2d5
--- a/dev/null
+++ b/noncore/games/kpacman/fruit.cpp
@@ -0,0 +1,176 @@
1#include <stdlib.h>
2
3#include "fruit.h"
4
5Fruit::Fruit(Board *b)
6{
7 board = b;
8 maxPixmaps = 0;
9 setLevel(0, 0, 0, 0);
10}
11
12void Fruit::setEaten(int duration)
13{
14 actualState = eaten;
15 timeLeft = duration;
16 actualDirection = X;
17}
18
19void Fruit::setLevel(int level, int wDuration, int fDuration, int ticks)
20{
21 actualLevel = level;
22 waitDuration = wDuration;
23 fruitDuration = fDuration;
24 pauseDuration = ticks;
25 pause = 0;
26 actualState = inactive;
27 timeLeft = waitDuration;
28 lastPosition = OUT;
29 setPosition(OUT);
30 setMovement(OUT, OUT, 0);
31 actualDirection = X;
32 setMaxPixmaps(maxPixmaps);
33}
34
35void Fruit::setMaxPixmaps(int max)
36{
37 maxPixmaps = max;
38 if (actualLevel-1 < maxPixmaps)
39 actualPix = actualLevel == 0 ? 0 : actualLevel-1;
40 else if (maxPixmaps > 0)
41 actualPix = rand() % maxPixmaps;
42 else
43 actualPix = -1;
44}
45
46void Fruit::setMovement(int entry, int tunnel, int iq)
47{
48 homePosition = board->position(fruithome);
49 entryPosition = entry;
50 tunnelPosition = tunnel;
51 IQ = iq;
52}
53
54void Fruit::setPosition(int pos)
55{
56 board->reset(lastPosition, fruit);
57 actualPosition = lastPosition = pos;
58 board->set(actualPosition, fruit);
59}
60
61void Fruit::setDirection(int dir)
62{
63 actualDirection = dir;
64}
65
66fruitState Fruit::state()
67{
68 return actualState;
69}
70
71int Fruit::position()
72{
73 return actualPosition;
74}
75
76int Fruit::direction()
77{
78 return actualDirection;
79}
80
81bool Fruit::move(bool activate)
82{
83 if (timeLeft > 0) {
84 timeLeft--;
85 }
86
87 if (actualDirection == X || actualState == inactive) {
88 if (timeLeft == 0 || (activate && actualState == inactive)) {
89 if (actualState == inactive) {
90 if (entryPosition == OUT || tunnelPosition == OUT) {
91 setPosition(board->position(fruithome));
92 } else {
93 setPosition(entryPosition);
94 actualDirection = 0;
95 while (!board->isWay(actualPosition, actualDirection, empty) ||
96 board->isJump(actualPosition, actualDirection))
97 actualDirection++;
98 }
99 timeLeft = fruitDuration;
100 setMaxPixmaps(maxPixmaps);
101 actualState = active;
102 } else {
103 actualState = inactive;
104 setPosition(OUT);
105 timeLeft = waitDuration;
106 actualDirection = X;
107 }
108 return TRUE;
109 }
110 return FALSE;
111 }
112
113 if (pause-- > 0)
114 return FALSE;
115 else
116 pause = pauseDuration;
117
118 if (actualPosition == OUT)
119 return FALSE;
120
121 if (actualDirection == X)
122 return TRUE;
123
124 int d = actualDirection;
125
126 if (rand() % (int) ((190-IQ)/10) == 0)
127 if (timeLeft > 0) // coming home or leaving again
128 d = board->closeup(actualPosition, d, homePosition);
129 else
130 d = board->closeup(actualPosition, d, tunnelPosition);
131 else
132 do // try new direction, but not the opposite
133 d = rand() % 4; // direction, to prevent hectic movement.
134 while (d == board->turn(actualDirection));
135
136 while ((!board->isWay(actualPosition, d, empty) &&
137 !board->isWay(actualPosition, d, tunnel)) ||
138 d == board->turn(actualDirection)) {
139 if (d != actualDirection) // if new direction is not possible,
140 d = actualDirection; // try current direction first.
141 else
142 d = rand() % 4;
143 }
144
145 actualDirection = d;
146 actualPosition = board->move(actualPosition, actualDirection);
147
148 if (actualPosition == homePosition) {
149 timeLeft = 0;
150 }
151
152 if (board->isTunnel(actualPosition)) {
153 setPosition(OUT);
154 timeLeft = waitDuration;
155 actualState = inactive;
156 actualDirection = X;
157 if (board->tunnels() > 0) {
158 entryPosition = board->position(tunnel, rand() % board->tunnels());
159 tunnelPosition = board->position(tunnel, rand() % board->tunnels());
160 }
161 }
162
163 if (actualPosition != lastPosition) {
164 setPosition(actualPosition);
165 }
166
167 return TRUE;
168}
169
170int Fruit::pix()
171{
172 if (actualPosition == OUT || actualState == inactive)
173 return -1;
174 else
175 return actualPix;
176}
diff --git a/noncore/games/kpacman/fruit.h b/noncore/games/kpacman/fruit.h
new file mode 100644
index 0000000..fbbd9c0
--- a/dev/null
+++ b/noncore/games/kpacman/fruit.h
@@ -0,0 +1,53 @@
1#ifndef FRUIT_H
2#define FRUIT_H
3
4#include <stdlib.h>
5
6#include "board.h"
7
8enum fruitState { inactive, active, eaten };
9
10class Fruit {
11public:
12 Fruit(Board *b);
13 void setEaten(int duration);
14 void setLevel(int level, int wDuration, int fDuration, int ticks = -1);
15 void setMaxPixmaps(int max);
16 void setMovement(int entry, int tunnel, int iq);
17 void setPosition(int pos);
18 void setDirection(int dir);
19 fruitState state();
20 int position();
21 int direction();
22 bool move(bool activate=FALSE);
23 int pix();
24
25private:
26 Board *board;
27
28 int IQ; // Intelligence of movement (0 = dumb..180=smart)
29
30 fruitState actualState; // the state of fruit
31
32 int pauseDuration; // number of ticks before next movement
33 int pause; // actual ticks before movement (0 = move)
34
35 int timeLeft; // Ticks remaining of current state
36
37 int waitDuration; // Time before fruit appears
38 int fruitDuration; // Length of active-time in ticks
39
40 int actualDirection; // actual direction of the fruit
41 int actualPosition; // actual position on board
42 int lastPosition; // the last position of the fruit
43 int actualLevel; // level for kind of fruit and score
44 int actualPix;
45 int maxPixmaps; // Number of Pixmaps (1..)
46
47 int entryPosition; // where to come in
48 int homePosition; // where to go, on the way in
49 int tunnelPosition; // where to exit
50};
51
52#endif // FRUIT_H
53
diff --git a/noncore/games/kpacman/keys.cpp b/noncore/games/kpacman/keys.cpp
new file mode 100644
index 0000000..c609373
--- a/dev/null
+++ b/noncore/games/kpacman/keys.cpp
@@ -0,0 +1,203 @@
1
2#include "portable.h"
3
4#if defined( KDE2_PORT )
5#include <kapp.h>
6#include <kconfig.h>
7#include <klocale.h>
8#include <kstddirs.h>
9#include <kaccel.h>
10
11#include <keys.h>
12#include <keys.moc>
13#elif defined( QPE_PORT )
14#include <qaccel.h>
15#include <qpe/qpeapplication.h>
16#include "config.h"
17#include "keys.h"
18#endif
19
20#include <qpushbt.h>
21#include <qlabel.h>
22#include <qframe.h>
23#include <qkeycode.h>
24#include <qpixmap.h>
25#include <qstring.h>
26
27Keys::Keys( QWidget *parent, const char *name)
28 : QDialog( parent, name, TRUE )
29{
30 //KStandardDirs *dirs = KGlobal::dirs();
31
32 QPushButton *okButton = new QPushButton(this);
33 okButton->setText(i18n("Ok"));
34 okButton->setFixedSize(okButton->size());
35 connect( okButton, SIGNAL(clicked()),this, SLOT(ok()) );
36 okButton->move(20,210);
37
38 QPushButton *defaultButton = new QPushButton(this);
39 defaultButton->setText(i18n("Defaults"));
40 defaultButton->setFixedSize(defaultButton->size());
41 connect( defaultButton, SIGNAL(clicked()),this, SLOT(defaults()) );
42 defaultButton->move(140,210);
43
44 QPushButton *cancelButton = new QPushButton(this);
45 cancelButton->setText(i18n("Cancel"));
46 cancelButton->setFixedSize(cancelButton->size());
47 connect( cancelButton, SIGNAL(clicked()),this, SLOT(reject()) );
48 cancelButton->move(260,210);
49
50 QFrame *separator = new QFrame(this);
51 separator->setFrameStyle( QFrame::HLine | QFrame::Sunken );
52 separator->setGeometry( 20, 190, 340, 4 );
53
54 for ( int x = 0; x < 4; x++) {
55 QLabel *l = new QLabel(this);
56 l->setAlignment(AlignCenter);
57 labels[x] = l;
58 }
59
60 labels[0]->setGeometry(120, 20, 140, 20 );
61 labels[1]->setGeometry(120,160, 140, 20 );
62 labels[2]->setGeometry( 20, 92, 100, 20 );
63 labels[3]->setGeometry(265, 92, 100, 20 );
64
65 QString pixPath;
66
67 QPushButton *up = new QPushButton(this);
68 pixPath = FIND_APP_DATA( "pics/up.xpm" );
69 up->setPixmap( QPixmap(pixPath));
70 up->setFixedSize(up->pixmap()->size());
71 connect( up, SIGNAL(clicked()),this, SLOT(butUp()) );
72 up->move(180, 50);
73
74 QPushButton *down = new QPushButton(this);
75 pixPath = FIND_APP_DATA( "pics/down.xpm");
76 down->setPixmap( QPixmap(pixPath));
77 down->setFixedSize(down->pixmap()->size());
78 connect( down, SIGNAL(clicked()),this, SLOT(butDown()) );
79 down->move(180, 130);
80
81 QPushButton *left = new QPushButton(this);
82 pixPath = FIND_APP_DATA( "pics/left.xpm");
83 left->setPixmap( QPixmap(pixPath));
84 left->setFixedSize(left->pixmap()->size());
85 connect( left, SIGNAL(clicked()),this, SLOT(butLeft()) );
86 left->move(140, 90);
87
88 QPushButton *right = new QPushButton(this);
89 pixPath = FIND_APP_DATA( "pics/right.xpm");
90 right->setPixmap( QPixmap(pixPath));
91 right->setFixedSize(right->pixmap()->size());
92 connect( right, SIGNAL(clicked()),this, SLOT(butRight()) );
93 right->move(220, 90);
94
95
96 setCaption(i18n("Change Direction Keys"));
97 setFixedSize(380, 260);
98 lab = 0;
99 init();
100}
101
102void Keys::keyPressEvent( QKeyEvent *e )
103{
104 uint kCode = e->key() & ~(SHIFT | CTRL | ALT);
105 QString string = KAccel::keyToString(kCode);
106
107 if (lab != 0) {
108 if ( string.isNull() )
109 lab->setText(i18n("Undefined key"));
110 else
111 lab->setText(string);
112 }
113 else if ( lab == 0 && e->key() == Key_Escape)
114 reject();
115}
116
117void Keys::butUp()
118{
119 getKey(0);
120}
121
122void Keys::butDown()
123{
124 getKey(1);
125}
126
127void Keys::butLeft()
128{
129 getKey(2);
130}
131
132void Keys::butRight()
133{
134 getKey(3);
135}
136
137void Keys::getKey(int i)
138{
139 if ( lab != 0)
140 focusOut(lab);
141
142 focusIn(labels[i]);
143}
144
145void Keys::focusOut(QLabel *l)
146{
147 l->setFrameStyle( QFrame::NoFrame );
148 l->setBackgroundColor(backgroundColor());
149 l->repaint();
150}
151
152void Keys::focusIn(QLabel *l)
153{
154 lab = l;
155 lab->setFrameStyle( QFrame::Panel | QFrame::Sunken );
156 lab->setBackgroundColor(white);
157 lab->repaint();
158}
159
160void Keys::defaults()
161{
162 if ( lab != 0)
163 focusOut(lab);
164
165 lab = 0;
166
167 labels[0]->setText("Up");
168 labels[1]->setText("Down");
169 labels[2]->setText("Left");
170 labels[3]->setText("Right");
171}
172
173void Keys::init()
174{
175 APP_CONFIG_BEGIN( cfg );
176 QString up("Up");
177 up = cfg->readEntry("upKey", (const char*) up);
178 labels[0]->setText(up);
179
180 QString down("Down");
181 down = cfg->readEntry("downKey", (const char*) down);
182 labels[1]->setText(down);
183
184 QString left("Left");
185 left = cfg->readEntry("leftKey", (const char*) left);
186 labels[2]->setText(left);
187
188 QString right("Right");
189 right = cfg->readEntry("rightKey", (const char*) right);
190 labels[3]->setText(right);
191 APP_CONFIG_END( cfg );
192}
193
194void Keys::ok()
195{
196 APP_CONFIG_BEGIN( cfg );
197 cfg->writeEntry("upKey", (const char*) labels[0]->text() );
198 cfg->writeEntry("downKey", (const char*) labels[1]->text() );
199 cfg->writeEntry("leftKey", (const char*) labels[2]->text() );
200 cfg->writeEntry("rightKey",(const char*) labels[3]->text() );
201 APP_CONFIG_END( cfg );
202 accept();
203}
diff --git a/noncore/games/kpacman/keys.h b/noncore/games/kpacman/keys.h
new file mode 100644
index 0000000..c0c9d82
--- a/dev/null
+++ b/noncore/games/kpacman/keys.h
@@ -0,0 +1,48 @@
1#ifndef KEYS_H
2#define KEYS_H
3
4#ifdef HAVE_CONFIG_H
5#include <config.h>
6#endif
7
8#include "portable.h"
9
10#if defined( KDE2_PORT )
11#include <kapp.h>
12#include <kaccel.h>
13#endif
14
15#include <qdialog.h>
16#include <qlabel.h>
17#include <qstring.h>
18
19class Keys : public QDialog
20{
21 Q_OBJECT
22public:
23 Keys( QWidget *parent=0, const char *name=0 );
24
25private slots:
26 void butRight();
27 void butLeft();
28 void butUp();
29 void butDown();
30
31 void getKey(int);
32 void defaults();
33 void focusIn(QLabel *);
34 void focusOut(QLabel *);
35
36 void ok();
37
38protected:
39 void keyPressEvent( QKeyEvent * );
40
41private:
42 void init();
43
44 QLabel *labels[4];
45 QLabel *lab;
46};
47
48#endif // KEYS_H
diff --git a/noncore/games/kpacman/kpacman.cpp b/noncore/games/kpacman/kpacman.cpp
new file mode 100644
index 0000000..4077085
--- a/dev/null
+++ b/noncore/games/kpacman/kpacman.cpp
@@ -0,0 +1,369 @@
1
2#include "portable.h"
3
4#if defined( KDE2_PORT )
5#include <kpacman.h>
6#include <kpacman.moc>
7#include <kcolordlg.h>
8#elif defined( QPE_PORT )
9#include <qmenubar.h>
10#include "config.h"
11#include <qapplication.h>
12#include "kpacman.h"
13#endif
14
15#include <qkeycode.h>
16#include <qcolor.h>
17#include <qstring.h>
18#include <qpopmenu.h>
19#include <qmsgbox.h>
20
21Kpacman::Kpacman(QWidget *parent, const char *name)
22 : KTMainWindow(parent, name)
23{
24 schemesPopup = new QList<QPopupMenu>;
25 schemesPopup->setAutoDelete(TRUE);
26
27 menu();
28
29 view = new KpacmanWidget( this, QString(name)+"widget");
30
31#ifndef QWS
32 setFixedSize(view->width(), view->height());
33#else
34 setCaption( "Kpacman" );
35#endif
36
37 view->referee->setFocus();
38
39 connect(view->referee, SIGNAL(setScore(int, int)),
40 view->score, SLOT(setScore(int, int)));
41 connect(view->referee, SIGNAL(setPoints(int)),
42 view->score, SLOT(set(int)));
43 connect(view->referee, SIGNAL(setLifes(int)),
44 view->status, SLOT(setLifes(int)));
45 connect(view->referee, SIGNAL(setLevel(int)),
46 view->status, SLOT(setLevel(int)));
47 connect(view->referee, SIGNAL(forcedHallOfFame(bool)),
48 this, SLOT(forcedHallOfFame(bool)));
49 connect(view->referee, SIGNAL(togglePaused()), this, SLOT(togglePaused()));
50 connect(view->referee, SIGNAL(toggleNew()), this, SLOT(toggleNew()));
51
52 connect(view->score, SIGNAL(toggleNew()), this, SLOT(toggleNew()));
53 connect(view->score, SIGNAL(forcedHallOfFame(bool)),
54 this, SLOT(forcedHallOfFame(bool)));
55
56 APP_CONFIG_BEGIN( cfg );
57 focusOutPause = !cfg->readBoolEntry("FocusOutPause", TRUE);
58 focusInContinue = !cfg->readBoolEntry("FocusInContinue", TRUE);
59 hideMouseCursor = !cfg->readBoolEntry("HideMouseCursor", TRUE);
60 APP_CONFIG_END( cfg );
61
62 toggleFocusOutPause();
63 toggleFocusInContinue();
64 toggleHideMouseCursor();
65
66#ifndef QWS
67 menuBar->show();
68 view->show();
69 setMenu(menuBar);
70 setView(view);
71#else
72 setCentralWidget( view );
73#endif
74}
75
76Kpacman::~Kpacman()
77{
78 APP_CONFIG_BEGIN( cfg );
79 cfg->writeEntry("FocusOutPause", focusOutPause);
80 cfg->writeEntry("FocusInContinue", focusInContinue);
81 cfg->writeEntry("HideMouseCursor", hideMouseCursor);
82 APP_CONFIG_END( cfg );
83 delete _menuBar;
84}
85
86void Kpacman::menu()
87{
88 gamePopup = new QPopupMenu();
89 CHECK_PTR( gamePopup );
90 newID = gamePopup->insertItem(i18n("&New"), this, SLOT(newKpacman()),Key_F2);
91 pauseID = gamePopup->insertItem(i18n("&Pause"),
92 this, SLOT(pauseKpacman()), Key_F3);
93 hofID = gamePopup->insertItem(i18n("&Hall of fame"),
94 this, SLOT(toggleHallOfFame()), Key_F4);
95 gamePopup->insertSeparator();
96 gamePopup->insertItem(i18n("&Quit"), this, SLOT(quitKpacman()), CTRL+Key_Q);
97 gamePopup->setCheckable(TRUE);
98
99 optionsPopup = new QPopupMenu();
100 CHECK_PTR(optionsPopup);
101
102 modesPopup = new QPopupMenu();
103 CHECK_PTR(modesPopup);
104
105 hideMouseCursorID = optionsPopup->insertItem(i18n("&Hide Mousecursor"),
106 this, SLOT(toggleHideMouseCursor()),
107 CTRL+Key_H);
108 optionsPopup->insertSeparator();
109
110 if (lookupSchemes() > 0) {
111 optionsPopup->insertItem(i18n("&Select graphic scheme"), modesPopup);
112 optionsPopup->insertSeparator();
113 }
114
115 focusOutPauseID = optionsPopup->insertItem(i18n("&Pause in Background"),
116 this, SLOT(toggleFocusOutPause()));
117 focusInContinueID = optionsPopup->insertItem(i18n("&Continue in Foreground"),
118 this, SLOT(toggleFocusInContinue()));
119 optionsPopup->insertSeparator();
120
121 optionsPopup->insertItem(i18n("Change &keys..."), this, SLOT(confKeys()));
122
123#ifndef QWS
124 QString aboutText = i18n("@PACKAGE@ - @VERSION@\n\n"
125 "Joerg Thoennissen (joe@dsite.de)\n\n"
126 "A pacman game for the KDE Desktop\n\n"
127 "The program based on the source of ksnake\n"
128 "by Michel Filippi (mfilippi@sade.rhein-main.de).\n"
129 "The design was strongly influenced by the pacman\n"
130 "(c) 1980 MIDWAY MFG.CO.\n\n"
131 "I like to thank my girlfriend Elke Krueers for\n"
132 "the last 10 years of her friendship.\n");
133 aboutText.replace(QRegExp("@PACKAGE@"), PACKAGE);
134 aboutText.replace(QRegExp("@VERSION@"), VERSION);
135 QPopupMenu *helpPopup = helpMenu(aboutText, FALSE);
136#endif
137
138 //_menuBar = new KMenuBar(this);
139 //CHECK_PTR( _menuBar );
140 //_menuBar->insertItem(i18n("&Game"), gamePopup);
141 //_menuBar->insertItem(i18n("&Options"), optionsPopup);
142 //_menuBar->insertSeparator();
143#ifndef QWS
144 _menuBar->insertItem(i18n("&Help"), helpPopup);
145#endif
146}
147
148int Kpacman::lookupSchemes()
149{
150 APP_CONFIG_BEGIN( cfg );
151 int ModeCount = cfg->readNumEntry("ModeCount", -1);
152 int Mode = cfg->readNumEntry("Mode", -1);
153 int SchemeCount = cfg->readNumEntry("SchemeCount");
154 int Scheme = cfg->readNumEntry("Scheme", -1);
155
156 if (SchemeCount == 0 || Scheme == -1) {
157 QMessageBox::warning(this, i18n("Configuration Error"),
158 i18n("There are no schemes defined,\n"
159 "or no scheme is selected."));
160 APP_CONFIG_END( cfg );
161 return 0;
162 }
163
164 connect(modesPopup, SIGNAL(activated(int)), this, SLOT(schemeChecked(int)));
165 modeID.resize(ModeCount > 0 ? ModeCount : 0);
166
167 if (!schemesPopup->isEmpty())
168 schemesPopup->clear();
169
170 SAVE_CONFIG_GROUP( cfg, oldgroup );
171
172 QString ModeGroup;
173 QString ModeName;
174
175 for (int m = 0; m < ModeCount; m++) {
176 ModeGroup.sprintf("Mode %d", m);
177 cfg->setGroup(ModeGroup);
178
179 ModeName = cfg->readEntry("Description", ModeGroup);
180
181 QPopupMenu *p = new QPopupMenu;
182 p->setCheckable(TRUE);
183 connect(p, SIGNAL(activated(int)), this, SLOT(schemeChecked(int)));
184 schemesPopup->append(p);
185
186 modeID[m] = modesPopup->insertItem(ModeName, schemesPopup->at(m));
187 modesPopup->setItemEnabled(modeID[m], FALSE);
188 modesPopup->setItemChecked(modeID[m], m == Mode);
189 }
190
191 schemeID.resize(SchemeCount);
192 schemeMode.resize(SchemeCount);
193
194 QString SchemeGroup;
195 QString SchemeName;
196 int SchemeMode;
197
198 for (int i = 0; i < SchemeCount; i++) {
199 SchemeGroup.sprintf("Scheme %d", i);
200 cfg->setGroup(SchemeGroup);
201
202 SchemeName = cfg->readEntry("Description", SchemeGroup);
203 SchemeMode = cfg->readNumEntry("Mode", -1);
204
205 schemeMode[i] = SchemeMode;
206 if (SchemeMode == -1) {
207 schemeID[i] = modesPopup->insertItem(SchemeName);
208 modesPopup->setItemChecked(schemeID[i], i == Scheme);
209 } else {
210 schemeID[i] = schemesPopup->at(SchemeMode)->insertItem(SchemeName);
211 schemesPopup->at(SchemeMode)->
212 setItemChecked(schemeID[i], i == Scheme);
213 modesPopup->setItemEnabled(modeID[SchemeMode], TRUE);
214 }
215 }
216
217 RESTORE_CONFIG_GROUP( cfg, oldgroup );
218
219 APP_CONFIG_END( cfg );
220 return SchemeCount;
221}
222
223void Kpacman::quitKpacman()
224{
225 APP_QUIT();
226}
227
228void Kpacman::newKpacman()
229{
230 if (!gamePopup->isItemEnabled(hofID))
231 gamePopup->setItemEnabled(hofID, TRUE);
232
233 if (gamePopup->isItemChecked(hofID))
234 toggleHallOfFame();
235
236 if (gamePopup->isItemChecked(pauseID))
237 pauseKpacman();
238
239 view->referee->play();
240}
241
242void Kpacman::pauseKpacman()
243{
244 view->referee->pause();
245 view->score->setPause(gamePopup->isItemChecked(pauseID));
246}
247
248void Kpacman::toggleHallOfFame()
249{
250 gamePopup->setItemChecked(hofID, !gamePopup->isItemChecked(hofID));
251 view->referee->toggleHallOfFame();
252
253 if (gamePopup->isItemChecked(hofID)) {
254 view->referee->lower();
255 view->status->lower();
256 } else {
257 view->status->raise();
258 view->referee->raise();
259 view->referee->setFocus();
260 }
261}
262
263/*
264 * Disable or enable the "Hall of fame"-menuitem if the referee says so.
265 * This is done, to disable turning off the "hall of fame"-display, in the automated
266 * sequence of displaying the introduction, the demonstration (or playing) and the
267 * hall of fame.
268 * If on == TRUE then also lower the referee and the status widgets.
269 */
270void Kpacman::forcedHallOfFame(bool on)
271{
272 if (!on && !gamePopup->isItemChecked(hofID))
273 return;
274
275 gamePopup->setItemEnabled(hofID, !on);
276 gamePopup->setItemChecked(hofID, on);
277
278 view->referee->toggleHallOfFame();
279 if (on) {
280 view->referee->lower();
281 view->status->lower();
282 } else {
283 view->status->raise();
284 view->referee->raise();
285 view->referee->setFocus();
286 view->referee->intro();
287 }
288}
289
290void Kpacman::togglePaused()
291{
292 static bool checked = FALSE;
293 checked = !checked;
294 gamePopup->setItemChecked( pauseID, checked );
295 view->score->setPause(gamePopup->isItemChecked(pauseID));
296}
297
298/*
299 * This disables the "New Game" menuitem to prevent interruptions of the current
300 * play.
301 */
302void Kpacman::toggleNew()
303{
304 gamePopup->setItemEnabled(newID, !gamePopup->isItemEnabled(newID));
305}
306
307void Kpacman::toggleHideMouseCursor()
308{
309 hideMouseCursor = !hideMouseCursor;
310 optionsPopup->setItemChecked(hideMouseCursorID, hideMouseCursor);
311 if (hideMouseCursor)
312 view->setCursor(blankCursor);
313 else
314 view->setCursor(arrowCursor);
315}
316
317void Kpacman::toggleFocusOutPause()
318{
319 focusOutPause = !focusOutPause;
320 optionsPopup->setItemChecked(focusOutPauseID, focusOutPause);
321 view->referee->setFocusOutPause(focusOutPause);
322}
323
324void Kpacman::toggleFocusInContinue()
325{
326 focusInContinue = !focusInContinue;
327 optionsPopup->setItemChecked(focusInContinueID, focusInContinue);
328 view->referee->setFocusInContinue(focusInContinue);
329}
330
331void Kpacman::confKeys()
332{
333 Keys *keys = new Keys();
334 if (keys->exec() == QDialog::Accepted) {
335 view->referee->initKeys();
336 view->score->initKeys();
337 }
338 delete keys;
339}
340
341void Kpacman::schemeChecked(int id)
342{
343 int mode = 0, scheme = -1;
344
345 for (uint s = 0; s < schemeID.size(); s++) {
346 if (schemeID[s] == id) {
347 scheme = s;
348 mode = schemeMode[s];
349 }
350 if (schemeMode[s] == -1) {
351 modesPopup->setItemChecked(schemeID[s], schemeID[s] == id);
352 } else {
353 modesPopup->setItemChecked(modeID[schemeMode[s]], schemeMode[s] == mode);
354 schemesPopup->at(schemeMode[s])->setItemChecked(schemeID[s], schemeID[s] == id);
355 }
356 }
357
358 APP_CONFIG_BEGIN( cfg );
359 cfg->writeEntry("Scheme", scheme);
360 cfg->writeEntry("Mode", mode);
361 APP_CONFIG_END( cfg );
362
363 view->setScheme(scheme, mode);
364 view->updateGeometry();
365 updateGeometry();
366 update();
367 repaint(TRUE);
368 show();
369}
diff --git a/noncore/games/kpacman/kpacman.h b/noncore/games/kpacman/kpacman.h
new file mode 100644
index 0000000..d7de9de
--- a/dev/null
+++ b/noncore/games/kpacman/kpacman.h
@@ -0,0 +1,95 @@
1#ifndef KPACMAN_H
2#define KPACMAN_H
3
4#ifdef HAVE_CONFIG_H
5#include <config.h>
6#endif
7
8#include "portable.h"
9
10#if defined( KDE2_PORT )
11#include <kapp.h>
12#include <klocale.h>
13#include <ktmainwindow.h>
14#include <kmenubar.h>
15#elif defined( QPE_PORT )
16#include <qmainwindow.h>
17class QMenuBar;
18#endif
19
20#include <qregexp.h>
21
22#include "kpacmanwidget.h"
23
24#include <qpopmenu.h>
25
26#include <qlist.h>
27#include <qfileinf.h>
28
29#if defined( KDE2_PORT )
30#include <referee.h>
31#include <status.h>
32#include <score.h>
33#include <keys.h>
34#elif defined( QPE_PORT )
35#include "referee.h"
36#include "status.h"
37#include "score.h"
38#include "keys.h"
39#endif
40
41class Kpacman : public KTMainWindow
42{
43 Q_OBJECT
44public:
45 Kpacman(QWidget *parent = 0, const char *name = 0);
46 virtual ~Kpacman();
47
48public slots:
49 void forcedHallOfFame(bool);
50
51private slots:
52 void newKpacman();
53 void pauseKpacman();
54 void toggleHallOfFame();
55 void toggleNew();
56 void togglePaused();
57 void quitKpacman();
58
59 void schemeChecked(int);
60 void toggleFocusOutPause();
61 void toggleFocusInContinue();
62 void toggleHideMouseCursor();
63 void confKeys();
64
65protected:
66
67private:
68 KpacmanWidget *view;
69
70 void menu();
71
72 int lookupSchemes();
73
74 KMenuBar *_menuBar;
75 QPopupMenu *gamePopup;
76 QPopupMenu *optionsPopup;
77 QPopupMenu *modesPopup;
78 QList<QPopupMenu> *schemesPopup;
79
80 int newID;
81 int pauseID;
82 int hofID;
83 QArray<int> modeID;
84 QArray<int> schemeID;
85 QArray<int> schemeMode;
86 int focusOutPauseID;
87 int focusInContinueID;
88 int hideMouseCursorID;
89
90 bool focusOutPause;
91 bool focusInContinue;
92 bool hideMouseCursor;
93};
94
95#endif // KPACMAN_H
diff --git a/noncore/games/kpacman/kpacman.moc.cpp b/noncore/games/kpacman/kpacman.moc.cpp
new file mode 100644
index 0000000..804e8c8
--- a/dev/null
+++ b/noncore/games/kpacman/kpacman.moc.cpp
@@ -0,0 +1,73 @@
1/****************************************************************************
2** Kpacman meta object code from reading C++ file 'kpacman.h'
3**
4** Created: Sat Jan 19 13:52:36 2002
5** by: The Qt MOC ($Id$)
6**
7** WARNING! All changes made in this file will be lost!
8*****************************************************************************/
9
10#if !defined(Q_MOC_OUTPUT_REVISION)
11#define Q_MOC_OUTPUT_REVISION 9
12#elif Q_MOC_OUTPUT_REVISION != 9
13#error "Moc format conflict - please regenerate all moc files"
14#endif
15
16#include "kpacman.h"
17#include <qmetaobject.h>
18#include <qapplication.h>
19
20
21
22const char *Kpacman::className() const
23{
24 return "Kpacman";
25}
26
27QMetaObject *Kpacman::metaObj = 0;
28
29void Kpacman::initMetaObject()
30{
31 if ( metaObj )
32 return;
33 if ( qstrcmp(QWidget::className(), "QWidget") != 0 )
34 badSuperclassWarning("Kpacman","QWidget");
35 (void) staticMetaObject();
36}
37
38#ifndef QT_NO_TRANSLATION
39
40QString Kpacman::tr(const char* s)
41{
42 return qApp->translate( "Kpacman", s, 0 );
43}
44
45QString Kpacman::tr(const char* s, const char * c)
46{
47 return qApp->translate( "Kpacman", s, c );
48}
49
50#endif // QT_NO_TRANSLATION
51
52QMetaObject* Kpacman::staticMetaObject()
53{
54 if ( metaObj )
55 return metaObj;
56 (void) QWidget::staticMetaObject();
57#ifndef QT_NO_PROPERTIES
58#endif // QT_NO_PROPERTIES
59 QMetaData::Access *slot_tbl_access = 0;
60 metaObj = QMetaObject::new_metaobject(
61 "Kpacman", "QWidget",
62 0, 0,
63 0, 0,
64#ifndef QT_NO_PROPERTIES
65 0, 0,
66 0, 0,
67#endif // QT_NO_PROPERTIES
68 0, 0 );
69 metaObj->set_slot_access( slot_tbl_access );
70#ifndef QT_NO_PROPERTIES
71#endif // QT_NO_PROPERTIES
72 return metaObj;
73}
diff --git a/noncore/games/kpacman/kpacman.pro b/noncore/games/kpacman/kpacman.pro
new file mode 100644
index 0000000..6577e5b
--- a/dev/null
+++ b/noncore/games/kpacman/kpacman.pro
@@ -0,0 +1,42 @@
1 TEMPLATE= app
2 #CONFIG = qt warn_on debug
3 CONFIG = qt warn_on release
4 #TMAKE_CXXFLAGS+=
5 HEADERS = kpacmanwidget.h \
6 referee.h \
7 status.h \
8 painter.h \
9 score.h \
10 pacman.h \
11 monster.h \
12 keys.h \
13 fruit.h \
14 energizer.h \
15 board.h \
16 bitfont.h \
17 kpacman.h \
18 bitmaps.h \
19 colors.h \
20 config.h \
21 portable.h
22 SOURCES = kpacmanwidget.cpp \
23 referee.cpp \
24 status.cpp \
25 painter.cpp \
26 score.cpp \
27 pacman.cpp \
28 monster.cpp \
29 keys.cpp \
30 fruit.cpp \
31 energizer.cpp \
32 board.cpp \
33 bitfont.cpp \
34 kpacman.cpp \
35 config.cpp \
36 main.cpp
37
38 #INCLUDEPATH+=
39 #DEPENDPATH+=
40LIBS += -lqpe -ljpeg
41DESTDIR = $(OPIEDIR)/bin
42 TARGET = kpacman
diff --git a/noncore/games/kpacman/kpacmanwidget.cpp b/noncore/games/kpacman/kpacmanwidget.cpp
new file mode 100644
index 0000000..330c88e
--- a/dev/null
+++ b/noncore/games/kpacman/kpacmanwidget.cpp
@@ -0,0 +1,162 @@
1
2#include "portable.h"
3
4#if defined( KDE2_PORT )
5#include <kapp.h>
6#include <kconfig.h>
7#include <kstddirs.h>
8#include <kpacmanwidget.h>
9#include <kpacmanwidget.moc>
10#elif defined( QPE_PORT )
11#include <qpe/qpeapplication.h>
12#include "config.h"
13#include "kpacmanwidget.h"
14#endif
15
16#include <qmessagebox.h>
17
18#include "bitfont.h"
19#include "score.h"
20#include "referee.h"
21#include "status.h"
22
23KpacmanWidget::KpacmanWidget( QWidget *parent, const char *name)
24 : QWidget( parent, name )
25{
26 bitfont = NULL;
27 fontName = "";
28
29 scheme = mode = -1;
30 confScheme();
31
32 score = new Score(this, name, scheme, mode, bitfont);
33 referee = new Referee( this, name, scheme, mode, bitfont);
34 status = new Status(this, name, scheme, mode);
35
36#ifndef QWS
37 setFixedSize(referee->width(), bitfont->height()*3 + referee->height() + status->height());
38#else
39 setBackgroundColor( black );
40#endif
41}
42
43KpacmanWidget::~KpacmanWidget()
44{
45}
46
47void KpacmanWidget::confMisc(bool defGroup)
48{
49 APP_CONFIG_BEGIN( cfg );
50 //KStandardDirs *dirs = KGlobal::dirs();
51 QString findPath;
52
53 if (defGroup || cfg->hasKey("Font")) {
54 fontName = cfg->readEntry("Font");
55
56 if (fontName.left(1) != "/" && fontName.left(1) != "~")
57 fontName.insert(0, "fonts/");
58 if (fontName.right(1) == "/")
59 fontName.append("font.xbm");
60
61 //findPath = dirs->findResource("appdata", fontName);
62 findPath = FIND_APP_DATA( fontName );
63 if (!findPath.isEmpty())
64 fontName = findPath;
65
66 bitfontFirstChar = cfg->readNumEntry("FontFirstChar", 0x0e);
67 bitfontLastChar = cfg->readNumEntry("FontLastChar", 0x5f);
68 }
69 APP_CONFIG_END( cfg );
70}
71
72void KpacmanWidget::confScheme()
73{
74 APP_CONFIG_BEGIN( cfg );
75 QString lastFontName = fontName;
76 SAVE_CONFIG_GROUP( cfg, oldgroup );
77 QString newgroup;
78
79 // if not set, read mode and scheme from the configfile
80 if (mode == -1 && scheme == -1) {
81 scheme = cfg->readNumEntry("Scheme", -1);
82 mode = cfg->readNumEntry("Mode", -1);
83
84 // if mode is not set in the defGroup-group, lookup the scheme group
85 if (scheme != -1 || mode == -1) {
86 newgroup.sprintf("Scheme %d", scheme);
87 cfg->setGroup(newgroup);
88
89 mode = cfg->readNumEntry("Mode", -1);
90 RESTORE_CONFIG_GROUP( cfg, oldgroup );
91 }
92 }
93
94 confMisc();
95
96 if (mode != -1) {
97 newgroup.sprintf("Mode %d", mode);
98 cfg->setGroup(newgroup);
99
100 confMisc(FALSE);
101 }
102
103 if (scheme != -1) {
104 newgroup.sprintf("Scheme %d", scheme);
105 cfg->setGroup(newgroup);
106
107 confMisc(FALSE);
108 }
109
110 if (lastFontName != fontName) {
111
112 if (bitfont != 0)
113 delete bitfont;
114
115 bitfont = new Bitfont(fontName, bitfontFirstChar, bitfontLastChar);
116 if (bitfont->width() == 0 || bitfont->height() == 0) {
117 QString msg = i18n("The bitfont could not be contructed.\n\n"
118 "The file '@FONTNAME@' does not exist,\n"
119 "or is of an unknown format.");
120 msg.replace(QRegExp("@FONTNAME@"), fontName);
121 // QMessageBox::critical(this, i18n("Initialization Error"), msg);
122 printf("%s\n", msg.data());
123 }
124 }
125
126 RESTORE_CONFIG_GROUP( cfg, oldgroup );
127 APP_CONFIG_END( cfg );
128}
129
130void KpacmanWidget::setScheme(int Scheme, int Mode)
131{
132 mode = Mode;
133 scheme = Scheme;
134
135 confScheme();
136
137 score->setScheme(Scheme, Mode, bitfont);
138 referee->setScheme(Scheme, Mode, bitfont);
139 status->setScheme(Scheme, Mode);
140
141#ifndef QWS
142 setFixedSize(referee->width(),
143 bitfont->height()*3 + referee->height() + status->height());
144#endif
145
146 score->repaint(FALSE);
147 referee->repaint(FALSE);
148 status->repaint(FALSE);
149}
150
151void KpacmanWidget::resizeEvent( QResizeEvent * )
152{
153 referee->setGeometry(0, bitfont->height()*3, referee->width(), referee->height());
154 referee->setBackgroundColor(BLACK);
155
156 status->setGeometry(0, bitfont->height()*3+referee->height(), referee->width(),
157 status->height());
158 status->setBackgroundColor(BLACK);
159
160 score->setGeometry(0, 0, referee->width(), bitfont->height()*3+referee->height()+status->height());
161 score->setBackgroundColor(BLACK);
162}
diff --git a/noncore/games/kpacman/kpacmanwidget.h b/noncore/games/kpacman/kpacmanwidget.h
new file mode 100644
index 0000000..13b4a15
--- a/dev/null
+++ b/noncore/games/kpacman/kpacmanwidget.h
@@ -0,0 +1,50 @@
1#ifndef KPACMANWIDGET_H
2#define KPACMANWIDGET_H
3
4#ifdef HAVE_CONFIG_H
5#include <config.h>
6#endif
7
8#include "portable.h"
9
10#if defined( KDE2_PORT )
11#include <kapp.h>
12#endif
13
14#include <qwidget.h>
15#include <qregexp.h>
16
17#include "score.h"
18#include "referee.h"
19#include "status.h"
20#include "painter.h"
21
22class KpacmanWidget : public QWidget
23{
24 Q_OBJECT
25public:
26 KpacmanWidget ( QWidget *parent = 0, const char *name = 0);
27 virtual ~KpacmanWidget();
28
29 void setScheme(int scheme=-1, int mode=-1);
30 Score *score;
31 Referee *referee;
32 Status *status;
33
34protected:
35 void confScheme();
36 void confMisc(bool defGroup=TRUE);
37 void resizeEvent( QResizeEvent * );
38
39private:
40 Bitfont *bitfont;
41 uchar bitfontFirstChar;
42 uchar bitfontLastChar;
43
44 QString fontName;
45
46 int scheme;
47 int mode;
48};
49
50#endif // KPACMANWIDGET_H
diff --git a/noncore/games/kpacman/main.cpp b/noncore/games/kpacman/main.cpp
new file mode 100644
index 0000000..76afb57
--- a/dev/null
+++ b/noncore/games/kpacman/main.cpp
@@ -0,0 +1,66 @@
1/***************************************************************************
2 main.cpp - description
3 -------------------
4 begin : Sam Jan 19 13:37:57 CET 2002
5 copyright : (C) 2002 by Jörg Thönnissen
6 email : joe@dsite.de
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include "portable.h"
19
20#if defined( KDE2_PORT )
21#include <kcmdlineargs.h>
22#include <kaboutdata.h>
23#include <klocale.h>
24#elif defined( QPE_PORT )
25#include <qpe/qpeapplication.h>
26#endif
27
28#include "kpacman.h"
29
30#ifdef KDE2_PORT
31static const char *description =
32 I18N_NOOP("Kpacman");
33// INSERT A DESCRIPTION FOR YOUR APPLICATION HERE
34
35
36static KCmdLineOptions options[] =
37{
38 { 0, 0, 0 }
39 // INSERT YOUR COMMANDLINE OPTIONS HERE
40};
41#endif
42
43int main(int argc, char *argv[])
44{
45#if defined( KDE2_PORT )
46 KAboutData aboutData( "kpacman", I18N_NOOP("Kpacman"),
47 VERSION, description, KAboutData::License_GPL,
48 "(c) 2002, Jörg Thönnissen", 0, 0, "joe@dsite.de");
49 aboutData.addAuthor("Jörg Thönnissen",0, "joe@dsite.de");
50 KCmdLineArgs::init( argc, argv, &aboutData );
51 KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
52 KApplication a;
53#elif defined( QPE_PORT )
54 QPEApplication a( argc, argv );
55#endif
56 Kpacman *kpacman = new Kpacman( NULL, "Kpacman" );
57 a.setMainWidget(kpacman);
58#if defined( KDE2_PORT )
59 a.setTopWidget(kpacman);
60 kpacman->show();
61#elif defined( QPE_PORT )
62 kpacman->showMaximized();
63#endif
64
65 return a.exec();
66}
diff --git a/noncore/games/kpacman/monster.cpp b/noncore/games/kpacman/monster.cpp
new file mode 100644
index 0000000..2f402b4
--- a/dev/null
+++ b/noncore/games/kpacman/monster.cpp
@@ -0,0 +1,262 @@
1#include "monster.h"
2#include "board.h"
3
4Monster::Monster(Board *b, int mid)
5{
6 board = b;
7 ID = mid;
8
9 setREM(0);
10 setHarmless(0, 0, 0);
11 setArrested(0, 0);
12 setFreedom(board->position(prisonexit));
13 if (mid == 0)
14 setPrison(board->position(prisonentry));
15 else
16 setPrison(board->position(monsterhome, mid));
17
18 actualPosition = lastPosition = OUT;
19 feetPosition = 0;
20 IQ = 0;
21 maxBodyPixmaps = 0;
22 maxEyesPixmaps = 0;
23}
24
25void Monster::setMaxPixmaps(int maxBody, int maxEyes)
26{
27 if (feetPosition >= (maxBody/10))
28 feetPosition = 0;
29 maxBodyPixmaps = maxBody;
30 maxEyesPixmaps = maxEyes;
31}
32
33void Monster::setArrested(int ticks, int duration)
34{
35 actualState = dangerous;
36 pauseDuration = ticks;
37 pause = 0;
38 arrestDuration = arrestLeft = duration;
39 arrestPause = ticks;
40 harmlessLeft = 0;
41}
42
43void Monster::setDangerous(int ticks, int iq)
44{
45 actualState = dangerous;
46 pauseDuration = ticks;
47 pause = 0;
48 dangerousPause = ticks;
49 harmlessLeft = 0;
50 IQ = iq;
51}
52
53void Monster::setHarmless(int ticks, int hDuration, int wDuration)
54{
55 actualState = harmless;
56 pauseDuration = ticks;
57 pause = 0;
58 harmlessDuration = harmlessLeft = hDuration;
59 warningDuration = wDuration;
60}
61
62void Monster::setREM(int ticks)
63{
64 actualState = rem;
65 pauseDuration = ticks;
66 pause = 0;
67}
68
69void Monster::setPosition(int pos)
70{
71 board->reset(lastPosition, monster, ID); // reset old position on the board
72 actualPosition = lastPosition = pos; // set position of monster
73 board->set(actualPosition, monster, ID);
74 feetPosition = 0;
75}
76
77void Monster::setPrison(int pos)
78{
79 prisonPosition = pos;
80}
81
82void Monster::setFreedom(int pos)
83{
84 freedomPosition = pos;
85}
86
87void Monster::setDirection(int dir)
88{
89 if (dir == X)
90 lastDirection = actualDirection;
91 actualDirection = dir;
92}
93
94monsterState Monster::state()
95{
96 return actualState;
97}
98
99int Monster::position()
100{
101 return actualPosition;
102}
103
104int Monster::direction()
105{
106 return actualDirection;
107}
108
109int Monster::id()
110{
111 return ID;
112}
113
114bool Monster::move()
115{
116 if (arrestLeft > 1)
117 arrestLeft--;
118
119 if (harmlessLeft > 0) {
120 harmlessLeft--;
121 if (harmlessLeft == 0 && actualState == harmless) {
122 actualState = dangerous;
123 pauseDuration = dangerousPause;
124 }
125 }
126
127 if (pause-- > 0)
128 return FALSE;
129 else
130 pause = pauseDuration;
131
132 if (actualPosition == OUT)
133 return FALSE;
134
135 if (actualDirection == X) {
136 if (++feetPosition >= (maxBodyPixmaps/10))
137 feetPosition = 0;
138 return TRUE;
139 }
140
141 lastPosition = actualPosition;
142 int d = actualDirection;
143
144 if (arrestLeft > 1) { // during the arrest, only up and down
145 if (!board->isWay(actualPosition, d, empty) &&
146 !board->isWay(actualPosition, d, tunnel))
147 d = board->turn(actualDirection);
148 }
149
150 if (arrestLeft == 1) { // going out of the prison
151 if (((d == W || d == E) &&
152 board->x(actualPosition) == board->x(freedomPosition)) ||
153 ((d == S || d == N) &&
154 board->y(actualPosition) == board->y(freedomPosition)) ||
155 board->isWay(actualPosition, d, brick) ||
156 board->isWay(actualPosition, d, prison)) {
157 d = board->closeup(actualPosition, d, freedomPosition);
158 }
159 while (board->isWay(actualPosition, d, brick) ||
160 board->isWay(actualPosition, d, prison)) {
161 if (d == actualDirection)
162 d = rand() % 4;
163 else
164 d = actualDirection;
165 }
166 if (actualState == dangerous)
167 pauseDuration = dangerousPause;
168
169 }
170
171 if (arrestLeft == 0)
172 if (actualState == rem) { // on the way to prison
173
174 d = board->closeup(actualPosition, d, prisonPosition);
175
176 while (board->isWay(actualPosition, d, brick) ||
177 board->isWay(actualPosition, d, prison)) {
178 if (d != actualDirection) // if new direction is not possible,
179 d = actualDirection; // try current direction first.
180 else
181 d = rand() % 4;
182 }
183
184 } else { // dangerous or harmless movement
185 if (rand() % (int) ((190-IQ)/10) == 0) {
186 d = board->closeup(actualPosition, d, board->position(pacman));
187 if (actualState == harmless)
188 d = board->turn(d);
189 } else
190 do // try new direction, but not the opposite
191 d = rand() % 4; // direction, to prevent hectic movement.
192 while (d == board->turn(actualDirection));
193
194 while ((!board->isWay(actualPosition, d, empty) &&
195 !board->isWay(actualPosition, d, tunnel)) ||
196 d == board->turn(actualDirection)) {
197 if (d != actualDirection) // if new direction is not possible,
198 d = actualDirection; // try current direction first.
199 else
200 d = rand() % 4;
201 }
202 }
203
204 actualDirection = d;
205 actualPosition = board->move(actualPosition, actualDirection);
206
207 if (arrestLeft == 1 && actualPosition == freedomPosition)
208 arrestLeft = 0;
209
210 if (actualState == rem && actualPosition == prisonPosition) {
211 actualState = dangerous;
212 pauseDuration = arrestPause;
213 arrestLeft = arrestDuration+1;
214 actualDirection = S;
215 }
216
217 if (actualPosition != lastPosition) {
218 board->reset(lastPosition, monster, ID);
219 board->set(actualPosition, monster, ID);
220 }
221
222 if (++feetPosition >= (maxBodyPixmaps/10))
223 feetPosition = 0;
224
225 return TRUE;
226}
227
228int Monster::body()
229{
230 if (actualState == rem || actualPosition == OUT)
231 return -1;
232 else
233 if (actualState == harmless)
234 if (harmlessLeft > warningDuration ||
235 harmlessLeft % (int) (warningDuration/4.5) > (int) (warningDuration/9))
236 return ((maxBodyPixmaps/10)*8)+feetPosition;
237 else
238 return ((maxBodyPixmaps/10)*9)+feetPosition;
239 else
240 return ((maxBodyPixmaps/10)*ID)+feetPosition;
241}
242
243int Monster::eyes()
244{
245 if (actualState == harmless || actualPosition == OUT)
246 return -1;
247 else
248 switch (actualDirection) {
249 case N : return 0;
250 case E : return 1;
251 case S : return 2;
252 case W : return 3;
253 case X : switch (lastDirection) {
254 case N : return 0;
255 case E : return 1;
256 case S : return 2;
257 default : return 3;
258 }
259 default : return -1;
260 }
261}
262
diff --git a/noncore/games/kpacman/monster.h b/noncore/games/kpacman/monster.h
new file mode 100644
index 0000000..b5d7f36
--- a/dev/null
+++ b/noncore/games/kpacman/monster.h
@@ -0,0 +1,62 @@
1#ifndef MONSTER_H
2#define MONSTER_H
3
4#include <stdlib.h>
5#include <qpixmap.h>
6#include <qwidget.h>
7
8#include "board.h"
9
10enum monsterState { dangerous, harmless, rem, arrested };
11
12class Monster {
13public:
14 Monster(Board *b, int mid = 0);
15 void setMaxPixmaps(int maxBody, int maxEyes);
16 void setArrested(int ticks, int duration);
17 void setDangerous(int ticks, int IQ);
18 void setHarmless(int ticks, int hDuration, int wDuration);
19 void setREM(int ticks);
20 void setPosition(int pos);
21 void setPrison(int pos);
22 void setFreedom(int pos);
23 void setDirection(int dir);
24 monsterState state();
25 int position();
26 int direction();
27 int id();
28 bool move();
29 int body();
30 int eyes();
31private:
32 Board *board;
33 int ID; // ID of monster (0 = 1st, 1 = 2nd ... 7 = last)
34 int IQ; // Intelligence of movement (0 = dumb..180 = smart)
35
36 monsterState actualState; // The state of the monster
37
38 int pauseDuration; // Number of ticks before movement
39 int pause; // actual ticks before moevment (0 = move)
40 int dangerousPause; // pause in dangerous-state
41
42 int harmlessDuration; // Length of harmless-time in ticks
43 int harmlessLeft; // rest of the time in harmless-state
44 int warningDuration; // warningtime before monster get dangerous again
45
46 int arrestDuration; // Length of arrest in ticks
47 int arrestLeft; // time left of arrest
48 int arrestPause; // pause in arrest-state
49
50 int actualDirection; // actual direction of monster
51 int lastDirection; // last direction, before no movement (X)
52 int actualPosition; // actual position on board
53 int lastPosition; // the last position of the monster
54 int feetPosition; // left, right, left, right, ...
55 int maxBodyPixmaps;
56 int maxEyesPixmaps;
57 int prisonPosition; // where to go, if arrested
58 int freedomPosition; // where to go, if released from prison
59};
60
61#endif // MONSTER_H
62
diff --git a/noncore/games/kpacman/opie-kpacman.control b/noncore/games/kpacman/opie-kpacman.control
new file mode 100644
index 0000000..814604e
--- a/dev/null
+++ b/noncore/games/kpacman/opie-kpacman.control
@@ -0,0 +1,11 @@
1Files: bin/kpacman apps/Games/kpacman.desktop pics/kpacman.png share/kpacman
2Package: opie-kpacman
3Version: 0.3.1
4Depends: opie-base ($QPE_VERSION)
5Priority: optional
6Section: opie/games
7Maintainer: Catalin Climov <catalin@climov.com>
8Architecture: arm
9License: GPL
10Description: Kpacman
11 A Pacman clone for Qtopia.
diff --git a/noncore/games/kpacman/opie-kpacman.postinst b/noncore/games/kpacman/opie-kpacman.postinst
new file mode 100755
index 0000000..ead1ef8
--- a/dev/null
+++ b/noncore/games/kpacman/opie-kpacman.postinst
@@ -0,0 +1,6 @@
1#!/bin/sh
2
3if [ ! -f $HOME/Settings/kpacman.conf ]
4then
5 cp $QPEDIR/share/kpacman/kpacman.conf $HOME/Settings/
6fi
diff --git a/noncore/games/kpacman/pacman.cpp b/noncore/games/kpacman/pacman.cpp
new file mode 100644
index 0000000..40f60a8
--- a/dev/null
+++ b/noncore/games/kpacman/pacman.cpp
@@ -0,0 +1,147 @@
1#include "pacman.h"
2#include "board.h"
3
4Pacman::Pacman(Board *b)
5{
6 board = b;
7 setDemo(FALSE);
8 setAlive(0);
9 actualPosition = lastPosition = OUT;
10 mouthPosition = 0;
11 lastPix = 0;
12 maxPixmaps = 0;
13}
14
15void Pacman::setMaxPixmaps(int max)
16{
17 if (actualDirection == X && lastPix >= 0) {
18 actualDirection = lastPix / (maxPixmaps/4);
19 if (max < maxPixmaps)
20 mouthPosition = 0;
21 else
22 mouthPosition = lastPix % (maxPixmaps/4);
23 maxPixmaps = max;
24
25 lastPix = pix();
26
27 actualDirection = X;
28 } else
29 maxPixmaps = max;
30}
31
32void Pacman::setAlive(int ticks)
33{
34 actualState = alive;
35 pauseDuration = ticks;
36 pause = 0;
37}
38
39void Pacman::setPosition(int pos)
40{
41 board->reset(lastPosition, pacman);
42 actualPosition = lastPosition = pos;
43 board->set(actualPosition, pacman);
44 mouthPosition = 0;
45}
46
47void Pacman::setDirection(int dir, bool forced)
48{
49 if (forced ||
50 board->isWay(actualPosition, dir, empty) ||
51 board->isWay(actualPosition, dir, tunnel)) {
52 if (dir == X)
53 lastPix = pix();
54 actualDirection = dir;
55 nextDirection = X;
56 } else
57 nextDirection = dir;
58}
59
60void Pacman::setDemo(bool yes)
61{
62 demo = yes;
63}
64
65pacmanState Pacman::state()
66{
67 return actualState;
68}
69
70int Pacman::position()
71{
72 return actualPosition;
73}
74
75int Pacman::direction()
76{
77 return actualDirection;
78}
79
80bool Pacman::move()
81{
82 if (pause-- > 0)
83 return FALSE;
84 else
85 pause = pauseDuration;
86
87 if (actualDirection == X || actualPosition == OUT)
88 return FALSE;
89
90 lastPosition = actualPosition;
91
92 if (demo) {
93 int d = actualDirection;
94
95 do // try new direction, but not the opposite
96 d = rand() % 4; // direction, to prevent hectic movement.
97 while (d == board->turn(actualDirection));
98
99 while (!board->isWay(actualPosition, d, empty) &&
100 !board->isWay(actualPosition, d, tunnel)) {
101 if (d != actualDirection) // if new actualDirection is not possible,
102 d = actualDirection; // try current actualDirection first.
103 else
104 d = rand() % 4;
105 }
106
107 actualDirection = d;
108 actualPosition = board->move(actualPosition, actualDirection);
109
110 } else {
111
112 if (nextDirection != X)
113 if (board->isWay(actualPosition, nextDirection, empty) ||
114 board->isWay(actualPosition, nextDirection, tunnel)) {
115 actualDirection = nextDirection;
116 nextDirection = X;
117 }
118
119 if (board->isWay(actualPosition, actualDirection, empty) ||
120 board->isWay(actualPosition, actualDirection, tunnel))
121 actualPosition = board->move(actualPosition, actualDirection);
122 }
123
124 if (actualPosition != lastPosition) {
125 board->reset(lastPosition, pacman);
126 board->set(actualPosition, pacman);
127
128 if (++mouthPosition >= (maxPixmaps/4))
129 mouthPosition = 0;
130 }
131 return TRUE;
132}
133
134int Pacman::pix()
135{
136 if (actualPosition != OUT && maxPixmaps > 0)
137 switch (actualDirection) {
138 case N : return ((maxPixmaps/4)*0)+mouthPosition;
139 case E : return ((maxPixmaps/4)*1)+mouthPosition;
140 case S : return ((maxPixmaps/4)*2)+mouthPosition;
141 case W : return ((maxPixmaps/4)*3)+mouthPosition;
142 case X : return lastPix;
143 }
144
145 return -1;
146}
147
diff --git a/noncore/games/kpacman/pacman.h b/noncore/games/kpacman/pacman.h
new file mode 100644
index 0000000..e81fdd2
--- a/dev/null
+++ b/noncore/games/kpacman/pacman.h
@@ -0,0 +1,47 @@
1#ifndef PACMAN_H
2#define PACMAN_H
3
4#include <stdlib.h>
5#include <qpixmap.h>
6#include <qwidget.h>
7
8#include "board.h"
9
10enum pacmanState { alive };
11
12class Pacman {
13public:
14 Pacman(Board *b);
15 void init(bool Demo = FALSE);
16 void setMaxPixmaps(int max);
17 void setAlive(int ticks);
18 void setPosition(int pos);
19 void setDirection(int dir, bool forced = FALSE);
20 void setDemo(bool yes);
21 pacmanState state();
22 int position();
23 int direction();
24 bool move();
25 int pix();
26
27private:
28 Board *board;
29
30 pacmanState actualState; // the state of pacman
31 bool demo; // real life or just demo
32
33 int pauseDuration; // number of ticks before next movement
34 int pause; // actual ticks before movement (0=move)
35
36 int actualDirection; // actual direction of pacman
37 int nextDirection; // where he wants to go
38 int lastPix; // last Pixmap-index before no movement
39 int maxPixmaps; // Number of Pixmaps (1..)
40 int actualPosition; // actual position on board
41 int lastPosition; // the last position of pacman
42 int mouthPosition; // eating
43
44};
45
46#endif // PACMAN_H
47
diff --git a/noncore/games/kpacman/painter.cpp b/noncore/games/kpacman/painter.cpp
new file mode 100644
index 0000000..16fed55
--- a/dev/null
+++ b/noncore/games/kpacman/painter.cpp
@@ -0,0 +1,972 @@
1
2#include "portable.h"
3
4#if defined( KDE2_PORT )
5#include <kapp.h>
6#include <kconfig.h>
7#include <kstddirs.h>
8#elif defined( QPE_PORT )
9#include <qpe/qpeapplication.h>
10#include "config.h"
11#endif
12
13#include <qcolor.h>
14#include <qpainter.h>
15#include <qpixmap.h>
16#include <qbitmap.h>
17#include <qrect.h>
18#include <qstring.h>
19
20#include <qmessagebox.h>
21#include <qfileinfo.h>
22
23#include "painter.h"
24#include "board.h"
25
26Painter::Painter( Board *b, QWidget *parent, int Scheme, int Mode, Bitfont *font)
27{
28 w = parent;
29 board = b;
30
31 pointPix = NULL;
32 wallPix = NULL;
33 prisonPix = NULL;
34 energizerPix = NULL;
35 fruitPix = NULL;
36 pacmanPix = NULL;
37 dyingPix = NULL;
38 eyesPix = NULL;
39 monsterPix = NULL;
40 fruitScorePix = NULL;
41 monsterScorePix = NULL;
42
43 lastPointPixmapName = "";
44 lastWallPixmapName = "";
45 lastPrisonPixmapName = "";
46 lastEnergizerPixmapName = "";
47 lastFruitPixmapName = "";
48 lastPacmanPixmapName = "";
49 lastDyingPixmapName = "";
50 lastEyesPixmapName = "";
51 lastMonsterPixmapName = "";
52 lastFruitScorePixmapName = "";
53 lastMonsterScorePixmapName = "";
54
55 bitfont = font;
56
57 scheme = Scheme;
58 mode = Mode;
59 level = 0;
60
61 confScheme();
62}
63
64QList<QPixmap> *Painter::loadPixmap(QWidget*, QString pixmapName,
65 QList<QPixmap> *pixmaps)
66{
67 if (pixmaps == NULL) {
68 pixmaps = new QList<QPixmap>;
69 pixmaps->setAutoDelete(TRUE);
70 }
71
72 if (!pixmaps->isEmpty())
73 pixmaps->clear();
74
75 QPixmap PIXMAP(pixmapName);
76 if (PIXMAP.isNull() || PIXMAP.mask() == NULL) {
77 QString msg = i18n("The pixmap could not be contructed.\n\n"
78 "The file '@PIXMAPNAME@' does not exist,\n"
79 "or is of an unknown format.");
80 msg.replace(QRegExp("@PIXMAPNAME@"), pixmapName);
81 // QMessageBox::critical(parent, i18n("Initialization Error"), msg);
82 printf("%s\n", msg.data());
83 return 0;
84 }
85
86 int height = PIXMAP.height();
87 int width = (height == 0) ? 0 : PIXMAP.width()/(PIXMAP.width()/height);
88
89 QBitmap BITMAP;
90 QBitmap MASK;
91
92 BITMAP = *PIXMAP.mask();
93 MASK.resize(width, height);
94
95 for (int x = 0; x < PIXMAP.width()/width; x++) {
96 QPixmap *pixmap = new QPixmap(width, height);
97 pixmaps->append(pixmap);
98 bitBlt(pixmap, 0, 0, &PIXMAP, x*width, 0, width, height, QPixmap::CopyROP, TRUE);
99 bitBlt(&MASK, 0, 0, &BITMAP, x*width, 0, width, height, QPixmap::CopyROP, TRUE);
100 pixmap->setMask(MASK);
101 }
102
103 return pixmaps;
104}
105
106QList<QPixmap> *Painter::textPixmap(QStrList &str, QList<QPixmap> *pixmaps,
107 QColor fg, QColor bg)
108{
109 if (pixmaps == NULL) {
110 pixmaps = new QList<QPixmap>;
111 pixmaps->setAutoDelete(TRUE);
112 }
113
114 if (!pixmaps->isEmpty())
115 pixmaps->clear();
116
117 for (uint s = 0; s < str.count(); s++) {
118 QPixmap *pixmap = new QPixmap(bitfont->text(str.at(s), fg, bg));
119 pixmaps->append(pixmap);
120 }
121
122 return pixmaps;
123}
124
125QList<QPixmap> *Painter::textPixmap(QString str, QList<QPixmap> *pixmaps,
126 QColor fg, QColor bg)
127{
128 if (pixmaps == NULL) {
129 pixmaps = new QList<QPixmap>;
130 pixmaps->setAutoDelete(TRUE);
131 }
132
133 if (!pixmaps->isEmpty())
134 pixmaps->clear();
135
136 QPixmap *pixmap = new QPixmap(bitfont->text(str, fg, bg));
137 pixmaps->append(pixmap);
138
139 return pixmaps;
140}
141
142/* Return the point of the upperleft pixel of the block representing that position
143 * on the board.
144 */
145QPoint Painter::point(int pos)
146{
147 return QPoint((board->x(pos)-1)*BlockWidth, (board->y(pos)-1)*BlockHeight);
148}
149
150
151QRect Painter::rect(int pos, PixMap pix, uint i)
152{
153 if (pos == OUT)
154 return QRect();
155
156 QPixmap *PIXMAP = NULL;
157 switch (pix) {
158 case PacmanPix : PIXMAP = pacmanPix->
159 at(checkRange(i, pacmanPix->count()-1));
160 break;
161 case DyingPix : PIXMAP = dyingPix->
162 at(checkRange(i, dyingPix->count()-1));
163 break;
164 case MonsterPix : PIXMAP = monsterPix->
165 at(checkRange(i, monsterPix->count()-1));
166 break;
167 case EyesPix : PIXMAP = eyesPix->
168 at(checkRange(i, eyesPix->count()-1));
169 break;
170 case FruitPix : PIXMAP = fruitPix->
171 at(checkRange(i, fruitPix->count()-1));
172 break;
173 case PointPix : PIXMAP = pointPix->
174 at(checkRange(i, pointPix->count()-1));
175 break;
176 case EnergizerPix : PIXMAP = energizerPix->
177 at(checkRange(i, energizerPix->count()-1));
178 break;
179 case FruitScorePix : PIXMAP = fruitScorePix->
180 at(checkRange(i, fruitScorePix->count()-1));
181 break;
182 case MonsterScorePix : PIXMAP = monsterScorePix->
183 at(checkRange(i,monsterScorePix->count()-1));
184 break;
185 default : PIXMAP = wallPix->
186 at(checkRange(i, wallPix->count()-1));
187 }
188 if (PIXMAP == NULL)
189 return QRect();
190
191 QRect rect = PIXMAP->rect();
192 QPoint point = this->point(pos);
193 rect.moveCenter(QPoint(point.x()-1, point.y()-1));
194
195 return rect;
196}
197
198QRect Painter::rect(int pos, QString str, int align)
199{
200 if (pos == OUT) // return an empty rect if the position
201 return QRect(); // is invalid
202 QPoint point = this->point(pos);
203 QRect rect = bitfont->rect(str);
204
205 rect.moveCenter(QPoint(point.x()-1, point.y()-1));
206
207 int dx = 0;
208 int dy = 0;
209
210 if (align & QLabel::AlignLeft || align & QLabel::AlignRight) {
211 dx = (str.length()-1) * (bitfont->width()/2);
212 if (align & QLabel::AlignRight)
213 dx *= -1;
214 }
215
216 if (align & QLabel::AlignTop || align & QLabel::AlignBottom) {
217 dy = bitfont->height()/2;
218 if (align & QLabel::AlignBottom)
219 dy *= -1;
220 }
221
222 if (dx != 0 || dy != 0)
223 rect.moveBy(dx, dy);
224
225 return rect;
226}
227
228QRect Painter::rect(QRect r1, QRect r2)
229{
230 QRect rect;
231 rect.setLeft(r1.left() < r2.left() ? r1.left() : r2.left());
232 rect.setTop(r1.top() < r2.top() ? r1.top() : r2.top());
233 rect.setRight(r1.right() > r2.right() ? r1.right() : r2.right());
234 rect.setBottom(r1.bottom() > r2.bottom() ? r1.bottom() : r2.bottom());
235
236 return rect;
237}
238
239void Painter::erase(int pos, PixMap pix, uint i)
240{
241 if (pos == OUT)
242 return;
243 QRect rect = this->rect(pos, pix, i);
244 bitBlt(&roomPix, rect.x(), rect.y(), &backPix,
245 rect.x(), rect.y(), rect.width(), rect.height());
246}
247
248int Painter::maxPixmaps(PixMap pix)
249{
250 switch (pix) {
251 case WallPix : return (int) wallPix->count();
252 case PrisonPix : return (int) prisonPix->count();
253 case PointPix : return (int) pointPix->count();
254 case EnergizerPix : return (int) energizerPix->count();
255 case FruitPix : return (int) fruitPix->count();
256 case PacmanPix : return (int) pacmanPix->count();
257 case DyingPix : return (int) dyingPix->count();
258 case EyesPix : return (int) eyesPix->count();
259 case MonsterPix : return (int) monsterPix->count();
260 case FruitScorePix : return (int) fruitScorePix->count();
261 case MonsterScorePix : return (int) monsterScorePix->count();
262 default : return 0;
263 }
264}
265
266void Painter::draw(QPoint point, DrawWidget where, QPixmap pix)
267{
268 switch (where) {
269 case Widget : bitBlt(w, point.x(), point.y(), &pix);
270 break;
271 case RoomPix : bitBlt(&roomPix, point.x(), point.y(), &pix);
272 break;
273 case BackPix : bitBlt(&backPix, point.x(), point.y(), &pix);
274 break;
275 }
276}
277
278void Painter::draw(QRect rect, DrawWidget where, QPixmap pix)
279{
280 draw(QPoint(rect.x(), rect.y()), where, pix);
281}
282
283void Painter::draw(int pos, DrawWidget where, PixMap pix, uint i)
284{
285 QPixmap *PIXMAP = NULL;
286 switch (pix) {
287 case PacmanPix : PIXMAP = pacmanPix->
288 at(checkRange(i, pacmanPix->count()-1));
289 break;
290 case DyingPix : PIXMAP = dyingPix->
291 at(checkRange(i, dyingPix->count()-1));
292 break;
293 case MonsterPix : PIXMAP = monsterPix->
294 at(checkRange(i, monsterPix->count()-1));
295 break;
296 case EyesPix : PIXMAP = eyesPix->
297 at(checkRange(i, eyesPix->count()-1));
298 break;
299 case FruitPix : PIXMAP = fruitPix->
300 at(checkRange(i, fruitPix->count()-1));
301 break;
302 case EnergizerPix : PIXMAP = energizerPix->
303 at(checkRange(i, energizerPix->count()-1));
304 break;
305 case FruitScorePix : PIXMAP = fruitScorePix->
306 at(checkRange(i, fruitScorePix->count()-1));
307 break;
308 case MonsterScorePix : PIXMAP = monsterScorePix->
309 at(checkRange(i,monsterScorePix->count()-1));
310 break;
311 default : ;
312 }
313
314 if (PIXMAP == NULL)
315 return;
316
317 QRect rect = PIXMAP->rect();
318 QPoint point = this->point(pos);
319 rect.moveCenter(QPoint(point.x()-1, point.y()-1));
320
321 switch (where) {
322 case Widget : bitBlt(w, rect.x(), rect.y(), PIXMAP);
323 break;
324 case RoomPix : bitBlt(&roomPix, rect.x(), rect.y(), PIXMAP);
325 break;
326 case BackPix : bitBlt(&backPix, rect.x(), rect.y(), PIXMAP);
327 break;
328 }
329}
330
331QPixmap Painter::draw(int pos, DrawWidget where,
332 QString str, QColor fg, QColor bg, int align)
333{
334 QPixmap TEXT = bitfont->text(str, fg, bg);
335
336 QRect rect = this->rect(pos, str, align);
337 QPixmap SAVE = QPixmap(rect.width(), rect.height());
338
339 switch (where) {
340 case Widget : bitBlt(&SAVE, 0, 0, w, rect.x(), rect.y());
341 bitBlt(w, rect.x(), rect.y(), &TEXT);
342 break;
343 case RoomPix : bitBlt(&SAVE, 0, 0, &roomPix, rect.x(), rect.y());
344 bitBlt(&roomPix, rect.x(), rect.y(), &TEXT);
345 break;
346 case BackPix : bitBlt(&SAVE, 0, 0, &backPix, rect.x(), rect.y());
347 bitBlt(&backPix, rect.x(), rect.y(), &TEXT);
348 break;
349 }
350
351 return SAVE;
352}
353
354QRect Painter::draw(int col, int row, DrawWidget where,
355 QString str, QColor fg, QColor bg, int align)
356{
357 QPixmap TEXT = bitfont->text(str, fg, bg);
358
359 QRect rect = this->rect(row*BoardWidth+col, str, align);
360 draw(rect, where, TEXT);
361
362 return rect;
363}
364
365void Painter::initPixmaps()
366{
367 if (lastPointPixmapName != pointPixmapName.at(level)) {
368 pointPix = loadPixmap(w, pointPixmapName.at(level), pointPix);
369 lastPointPixmapName = pointPixmapName.at(level);
370 }
371 if (lastPrisonPixmapName != prisonPixmapName.at(level)) {
372 prisonPix = loadPixmap(w, prisonPixmapName.at(level), prisonPix);
373 lastPrisonPixmapName = prisonPixmapName.at(level);
374 }
375 if (lastEnergizerPixmapName != energizerPixmapName.at(level)) {
376 energizerPix = loadPixmap(w, energizerPixmapName.at(level), energizerPix);
377 lastEnergizerPixmapName = energizerPixmapName.at(level);
378 }
379 if (lastFruitPixmapName != fruitPixmapName.at(level)) {
380 fruitPix = loadPixmap(w, fruitPixmapName.at(level), fruitPix);
381 lastFruitPixmapName = fruitPixmapName.at(level);
382 }
383 if (lastPacmanPixmapName != pacmanPixmapName.at(level)) {
384 pacmanPix = loadPixmap(w, pacmanPixmapName.at(level), pacmanPix);
385 lastPacmanPixmapName = pacmanPixmapName.at(level);
386 }
387 if (lastDyingPixmapName != dyingPixmapName.at(level)) {
388 dyingPix = loadPixmap(w, dyingPixmapName.at(level), dyingPix);
389 lastDyingPixmapName = dyingPixmapName.at(level);
390 }
391 if (lastEyesPixmapName != eyesPixmapName.at(level)) {
392 eyesPix = loadPixmap(w, eyesPixmapName.at(level), eyesPix);
393 lastEyesPixmapName = eyesPixmapName.at(level);
394 }
395 if (lastMonsterPixmapName != monsterPixmapName.at(level)) {
396 monsterPix = loadPixmap(w, monsterPixmapName.at(level), monsterPix);
397 lastMonsterPixmapName = monsterPixmapName.at(level);
398 }
399
400 if (lastFruitScorePixmapName != fruitScorePixmapName.at(level) ||
401 (const char *) *fruitScorePixmapName.at(level) == '\0') {
402 if ((const char *) *fruitScorePixmapName.at(level) == '\0') {
403 fruitScorePix = textPixmap(fruitScoreString, fruitScorePix, PINK);
404 } else {
405 fruitScorePix = loadPixmap(w, fruitScorePixmapName.at(level),
406 fruitScorePix);
407 lastFruitScorePixmapName = fruitScorePixmapName.at(level);
408 }
409 }
410
411 if (lastMonsterScorePixmapName != monsterScorePixmapName.at(level) ||
412 (const char *) *monsterScorePixmapName.at(level) == '\0') {
413 if ((const char *) *monsterScorePixmapName.at(level) == '\0') {
414 monsterScorePix = textPixmap(monsterScoreString, monsterScorePix, CYAN);
415 } else {
416 monsterScorePix = loadPixmap(w, monsterScorePixmapName.at(level),
417 monsterScorePix);
418 lastMonsterScorePixmapName = monsterScorePixmapName.at(level);
419 }
420 }
421
422 if (lastWallPixmapName != wallPixmapName.at(level)) {
423 wallPix = loadPixmap(w, wallPixmapName.at(level), wallPix);
424 if (wallPix->isEmpty()) {
425 BlockWidth = 0;
426 BlockHeight = 0;
427 } else {
428 BlockWidth = wallPix->at(0)->width();
429 BlockHeight = wallPix->at(0)->height();
430 }
431 lastWallPixmapName = wallPixmapName.at(level);
432 }
433}
434
435void Painter::initbackPixmaps()
436{
437 backgroundColor = BLACK;
438
439 backPix.resize((BoardWidth-3)*BlockWidth, (BoardHeight-3)*BlockHeight );
440 backPix.fill(backgroundColor);
441}
442
443void Painter::initRoomPixmap()
444{
445 roomPix.resize((BoardWidth-3)*BlockWidth, (BoardHeight-3)*BlockHeight );
446 bitBlt(&roomPix,0,0, &backPix);
447
448 for (unsigned int x = 0; x < board->size(); x++) {
449 if (board->isBrick(x))
450 drawBrick(x);
451 if (board->isPrison(x) || board->isGate(x))
452 drawPrison(x);
453 if (board->isPoint(x))
454 drawPoint(x);
455 }
456}
457
458void Painter::drawBrick(int pos)
459{
460 int border = 0;
461 if (board->isBrick(board->move(pos, N ))) border |= (1 << 0);
462 if (board->isBrick(board->move(pos, NE))) border |= (1 << 1);
463 if (board->isBrick(board->move(pos, E ))) border |= (1 << 2);
464 if (board->isBrick(board->move(pos, SE))) border |= (1 << 3);
465 if (board->isBrick(board->move(pos, S ))) border |= (1 << 4);
466 if (board->isBrick(board->move(pos, SW))) border |= (1 << 5);
467 if (board->isBrick(board->move(pos, W ))) border |= (1 << 6);
468 if (board->isBrick(board->move(pos, NW))) border |= (1 << 7);
469
470 if (board->isOut(board->move(pos, N ))) border |= (1 << 8);
471 if (board->isOut(board->move(pos, NE))) border |= (1 << 9);
472 if (board->isOut(board->move(pos, E ))) border |= (1 << 10);
473 if (board->isOut(board->move(pos, SE))) border |= (1 << 11);
474 if (board->isOut(board->move(pos, S ))) border |= (1 << 12);
475 if (board->isOut(board->move(pos, SW))) border |= (1 << 13);
476 if (board->isOut(board->move(pos, W ))) border |= (1 << 14);
477 if (board->isOut(board->move(pos, NW))) border |= (1 << 15);
478
479 switch (border & 0xFF) {
480 case 31 : border = 0; break;
481 case 159 : border = 0; break;
482 case 63 : border = 0; break;
483 case 191 : border = 0; break;
484 case 241 : border = 1; break;
485 case 249 : border = 1; break;
486 case 243 : border = 1; break;
487 case 251 : border = 1; break;
488 case 124 : border = 2; break;
489 case 252 : border = 2; break;
490 case 126 : border = 2; break;
491 case 199 : border = 3; break;
492 case 231 : border = 3; break;
493 case 207 : border = 3; break;
494 case 28 : if ((border >> 8) > 0)
495 border = 24;
496 else
497 border = 4;
498 break;
499 case 112 : if ((border >> 8) > 0)
500 border = 27;
501 else
502 border = 5;
503 break;
504 case 7 : if ((border >> 8) > 0)
505 border = 25;
506 else
507 border = 6;
508 break;
509 case 193 : if ((border >> 8) > 0)
510 border = 26;
511 else
512 border = 7;
513 break;
514 case 247 : if ((border & (1 << 11)) > 0)
515 border = 23;
516 else
517 border = 8;
518 break;
519 case 119 : if ((border & (1 << 15)) > 0)
520 border = 8;
521 if ((border & (1 << 11)) > 0)
522 border = 11;
523 break;
524 case 223 : if ((border & (1 << 13)) > 0)
525 border = 20;
526 else
527 border = 9;
528 break;
529 case 221 : if ((border & (1 << 13)) > 0)
530 border = 10;
531 if ((border & (1 << 9)) > 0)
532 border = 9;
533 break;
534 case 253 : if ((border & (1 << 9)) > 0)
535 border = 21;
536 else
537 border = 10;
538 break;
539 case 127 : if ((border & (1 << 15)) > 0)
540 border = 22;
541 else
542 border = 11;
543 break;
544 case 30 : border = 12; break;
545 case 240 : border = 13; break;
546 case 15 : border = 14; break;
547 case 225 : border = 15; break;
548 case 135 : border = 16; break;
549 case 195 : border = 17; break;
550 case 60 : border = 18; break;
551 case 120 : border = 19; break;
552 case 255 : border = 28; break;
553 default : border = -1;
554 }
555 if (border != -1 && border < (int) wallPix->count()) {
556 QRect rect = this->rect(pos, WallPix);
557 bitBlt(&roomPix, rect.x(), rect.y(), wallPix->at((uint) border));
558 }
559}
560
561void Painter::drawPrison(int pos)
562{
563 int border = 0;
564 if (board->isPrison(board->move(pos, N ))) border |= (1 << 0);
565 if (board->isPrison(board->move(pos, NE))) border |= (1 << 1);
566 if (board->isPrison(board->move(pos, E ))) border |= (1 << 2);
567 if (board->isPrison(board->move(pos, SE))) border |= (1 << 3);
568 if (board->isPrison(board->move(pos, S ))) border |= (1 << 4);
569 if (board->isPrison(board->move(pos, SW))) border |= (1 << 5);
570 if (board->isPrison(board->move(pos, W ))) border |= (1 << 6);
571 if (board->isPrison(board->move(pos, NW))) border |= (1 << 7);
572
573 if (board->isGate(board->move(pos, N ))) border |= (1 << 8);
574 if (board->isGate(board->move(pos, NE))) border |= (1 << 9);
575 if (board->isGate(board->move(pos, E ))) border |= (1 << 10);
576 if (board->isGate(board->move(pos, SE))) border |= (1 << 11);
577 if (board->isGate(board->move(pos, S ))) border |= (1 << 12);
578 if (board->isGate(board->move(pos, SW))) border |= (1 << 13);
579 if (board->isGate(board->move(pos, W ))) border |= (1 << 14);
580 if (board->isGate(board->move(pos, NW))) border |= (1 << 15);
581
582 switch (border & 0xFF) {
583 case 31 : border = 0; break;
584 case 159 : border = 0; break;
585 case 63 : border = 0; break;
586 case 241 : border = 1; break;
587 case 249 : border = 1; break;
588 case 243 : border = 1; break;
589 case 124 : border = 2; break;
590 case 252 : border = 2; break;
591 case 126 : border = 2; break;
592 case 199 : border = 3; break;
593 case 231 : border = 3; break;
594 case 207 : border = 3; break;
595 case 28 : if ((border >> 8) != 0)
596 border = 12;
597 else
598 border = 4;
599 break;
600 case 112 : if ((border >> 8) != 0)
601 border = 13;
602 else
603 border = 5;
604 break;
605 case 7 : if ((border >> 8) != 0)
606 border = 14;
607 else
608 border = 6;
609 break;
610 case 193 : if ((border >> 8) != 0)
611 border = 15;
612 else
613 border = 7;
614 break;
615 case 247 : border = 8; break;
616 case 223 : border = 9; break;
617 case 253 : border = 10; break;
618 case 127 : border = 11; break;
619 default : border = -1;
620 }
621 if (board->isGate(pos)) {
622 if (board->isGate(board->move(pos, N)))
623 border = 17;
624 else
625 border = 16;
626 }
627
628 if (border != -1 && border < (int) prisonPix->count()) {
629 QRect rect = this->rect(pos, PrisonPix);
630 bitBlt(&roomPix, rect.x(), rect.y(), prisonPix->at((uint) border));
631 }
632}
633
634void Painter::drawPoint(int pos)
635{
636 if (!pointPix->isEmpty()) {
637 QRect rect = this->rect(pos, PointPix);
638 bitBlt(&roomPix, rect.x(), rect.y(), pointPix->at(0));
639 }
640}
641
642QString Painter::decodeHexOctString(QString s)
643{
644 QString value;
645 QString valids;
646 int pos, xpos = 0, opos = 0;
647 int v, len, leadin;
648 const char *ptr;
649 uchar c;
650
651 while (((xpos = s.find(QRegExp("\\\\x[0-9a-fA-F]+"), xpos)) != -1) ||
652 ((opos = s.find(QRegExp("\\\\[0-7]+"), opos)) != -1)) {
653 if (xpos != -1) {
654 valids = "0123456789abcdef";
655 leadin = 2;
656 pos = xpos;
657 } else {
658 valids = "01234567";
659 leadin = 1;
660 pos = opos;
661 }
662
663 c = '\0';
664 len = 0;
665 value = s.mid(pos+leadin, 3);
666 ptr = (const char *) value;
667
668 while (*ptr != '\0' && (v = valids.find(*ptr++, 0, FALSE)) != -1) {
669 c = (c * valids.length()) + v;
670 len++;
671 }
672
673 value.fill(c, 1);
674 s.replace(pos, len+leadin, value);
675 }
676
677 return s;
678}
679
680void Painter::fillScoreString(QStrList &list, QArray<int> &values)
681{
682 if( !list.isEmpty())
683 list.clear();
684
685 QString s;
686
687 for (uint i = 0; i < values.size(); i++) {
688
689 if (values[i] < 10 || values[i] > 10000)
690 s = "?";
691 else if (values[i] == 1600)
692 s = "\x1a\x1b";
693 else if (values[i] < 100) {
694 s = "\x0e";
695 s.insert(0, char (values[i] / 10 + 0x10));
696 } else if (values[i] < 1000) {
697 s = "\x0f";
698 s.insert(0, char (values[i] / 100 + 0x10));
699 } else {
700 s = "\x0f\x10";
701 s.insert(0, char (values[i] / 1000 + 0x10));
702 }
703
704 list.append(s.data());
705 }
706}
707
708void Painter::fillArray(QArray<int> &array, QString values, int max)
709{
710 array.resize(max);
711 int last = 0;
712 bool ok;
713 QString value;
714
715 for (uint i = 0; i < array.size(); i++) {
716 if (values.find(',') < 0 && values.length() > 0) {
717 value = values;
718 values = "";
719 }
720 if (values.find(',') >= 0) {
721 value = values.left(values.find(','));
722 values.remove(0,values.find(',')+1);
723 }
724 array[i] = value.toInt(&ok);
725 if (ok)
726 last = array[i];
727 else
728 array[i] = last;
729 }
730}
731
732void Painter::fillStrList(QStrList &list, QString values, int max)
733{
734 if (!list.isEmpty())
735 list.clear();
736
737 QString last = "";
738 QString value;
739
740 for (uint i = 0; i < (uint) max; i++) {
741 if (values.find(',') < 0 && values.length() > 0) {
742 value = values;
743 values = "";
744 }
745 if (values.find(',') >= 0) {
746 value = values.left(values.find(','));
747 values.remove(0,values.find(',')+1);
748 }
749 if (!value.isEmpty())
750 last = decodeHexOctString(value);
751 list.append(last);
752 }
753}
754
755void Painter::fillPixmapName(QStrList &pixmapName)
756{
757 QStrList list = pixmapName;
758
759 if (!pixmapName.isEmpty())
760 pixmapName.clear();
761
762 QString pixmap;
763
764 QFileInfo fileInfo;
765
766 for (uint i = 0; i < list.count(); i++) {
767 pixmap = list.at(i);
768
769 if (pixmap.left(1) != "/" && pixmap.left(1) != "~")
770 pixmap = FIND_APP_DATA( pixmapDirectory+pixmap );
771
772 fileInfo.setFile(pixmap);
773 if (!fileInfo.isReadable() || !fileInfo.isFile())
774 pixmap = "";
775
776 pixmapName.append(pixmap);
777 }
778}
779
780void Painter::confLevels(bool defGroup)
781{
782 APP_CONFIG_BEGIN( cfg );
783 if (defGroup || cfg->hasKey("Levels"))
784 maxLevel = cfg->readNumEntry("Levels", 13);
785 APP_CONFIG_END( cfg );
786}
787
788void Painter::confMisc(bool defGroup)
789{
790 APP_CONFIG_BEGIN( cfg );
791 if (defGroup || cfg->hasKey("PixmapDirectory")) {
792 pixmapDirectory = cfg->readEntry("PixmapDirectory");
793
794 if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~")
795 pixmapDirectory.insert(0, "pics/");
796 if (pixmapDirectory.right(1) != "/")
797 pixmapDirectory.append("/");
798 }
799
800 if (defGroup || cfg->hasKey("PointPixmapName"))
801 fillStrList(pointPixmapName,
802 cfg->readEntry("PointPixmapName", "point.xpm"), maxLevel+1);
803 if (defGroup || cfg->hasKey("WallPixmapName"))
804 fillStrList(wallPixmapName,
805 cfg->readEntry("WallPixmapName", "wall.xpm"), maxLevel+1);
806 if (defGroup || cfg->hasKey("PrisonPixmapName"))
807 fillStrList(prisonPixmapName,
808 cfg->readEntry("PrisonPixmapName", "prison.xpm"), maxLevel+1);
809 if (defGroup || cfg->hasKey("EnergizerPixmapName"))
810 fillStrList(energizerPixmapName,
811 cfg->readEntry("EnergizerPixmapName", "switch.xpm"),maxLevel+1);
812 if (defGroup || cfg->hasKey("FruitPixmapName"))
813 fillStrList(fruitPixmapName,
814 cfg->readEntry("FruitPixmapName", "fruit.xpm"), maxLevel+1);
815 if (defGroup || cfg->hasKey("PacmanPixmapName"))
816 fillStrList(pacmanPixmapName,
817 cfg->readEntry("PacmanPixmapName", "pacman.xpm"), maxLevel+1);
818 if (defGroup || cfg->hasKey("DyingPixmapName"))
819 fillStrList(dyingPixmapName,
820 cfg->readEntry("DyingPixmapName", "dying.xpm"), maxLevel+1);
821 if (defGroup || cfg->hasKey("EyesPixmapName"))
822 fillStrList(eyesPixmapName,
823 cfg->readEntry("EyesPixmapName", "eyes.xpm"), maxLevel+1);
824 if (defGroup || cfg->hasKey("MonsterPixmapName"))
825 fillStrList(monsterPixmapName,
826 cfg->readEntry("MonsterPixmapName", "monster.xpm"), maxLevel+1);
827
828 if (defGroup || cfg->hasKey("FruitScorePixmapName"))
829 fillStrList(fruitScorePixmapName,
830 cfg->readEntry("FruitScorePixmapName"), maxLevel+1);
831 if (defGroup || cfg->hasKey("MonsterScorePixmapName"))
832 fillStrList(monsterScorePixmapName,
833 cfg->readEntry("MonsterScorePixmapName"), maxLevel+1);
834 APP_CONFIG_END( cfg );
835}
836
837void Painter::confScoring(bool defGroup)
838{
839 APP_CONFIG_BEGIN( cfg );
840 if (defGroup || cfg->hasKey("FruitScore"))
841 fillArray(fruitScore,
842 cfg->readEntry("FruitScore",
843 "100,300,500,,700,,1000,,2000,,3000,,5000"),
844 maxLevel+1);
845 if (defGroup || cfg->hasKey("MonsterScore"))
846 fillArray(monsterScore,
847 cfg->readEntry("MonsterScore", "200,400,800,1600"), 4);
848
849 if (defGroup || cfg->hasKey("FruitScoreString"))
850 fillStrList(fruitScoreString,
851 cfg->readEntry("FruitScoreString"), maxLevel+1);
852 if (defGroup || cfg->hasKey("MonsterScoreString"))
853 fillStrList(monsterScoreString,
854 cfg->readEntry("MonsterScoreString"), 4);
855 APP_CONFIG_END( cfg );
856}
857
858void Painter::confScheme()
859{
860 APP_CONFIG_BEGIN( cfg );
861 SAVE_CONFIG_GROUP( cfg, oldgroup );
862 QString newgroup;
863
864 // if not set, read mode and scheme from the configfile
865 if (mode == -1 && scheme == -1) {
866 scheme = cfg->readNumEntry("Scheme", -1);
867 mode = cfg->readNumEntry("Mode", -1);
868
869 // if mode is not set in the defGroup-group, lookup the scheme group
870 if (scheme != -1 || mode == -1) {
871 newgroup.sprintf("Scheme %d", scheme);
872 cfg->setGroup(newgroup);
873
874 mode = cfg->readNumEntry("Mode", -1);
875 RESTORE_CONFIG_GROUP( cfg, oldgroup );
876 }
877 }
878
879 confLevels();
880
881 if (mode != -1) {
882 newgroup.sprintf("Mode %d", mode);
883 cfg->setGroup(newgroup);
884
885 confLevels(FALSE);
886 }
887
888 if (scheme != -1) {
889 newgroup.sprintf("Scheme %d", scheme);
890 cfg->setGroup(newgroup);
891
892 confLevels(FALSE);
893 }
894
895 RESTORE_CONFIG_GROUP( cfg, oldgroup );
896
897 confMisc();
898 confScoring();
899
900 if (mode != -1) {
901 newgroup.sprintf("Mode %d", mode);
902 cfg->setGroup(newgroup);
903
904 confMisc(FALSE);
905 confScoring(FALSE);
906 }
907
908 if (scheme != -1) {
909 newgroup.sprintf("Scheme %d", scheme);
910 cfg->setGroup(newgroup);
911
912 confMisc(FALSE);
913 confScoring(FALSE);
914 }
915
916 if ((const char *) *fruitScoreString.at(0) == '\0')
917 fillScoreString(fruitScoreString, fruitScore);
918 if ((const char *) *monsterScoreString.at(0) == '\0')
919 fillScoreString(monsterScoreString, monsterScore);
920
921 fillPixmapName(pointPixmapName);
922 fillPixmapName(wallPixmapName);
923 fillPixmapName(prisonPixmapName);
924 fillPixmapName(energizerPixmapName);
925 fillPixmapName(fruitPixmapName);
926 fillPixmapName(pacmanPixmapName);
927 fillPixmapName(dyingPixmapName);
928 fillPixmapName(eyesPixmapName);
929 fillPixmapName(monsterPixmapName);
930 fillPixmapName(fruitScorePixmapName);
931 fillPixmapName(monsterScorePixmapName);
932
933 initPixmaps();
934 initbackPixmaps();
935 initRoomPixmap();
936
937 RESTORE_CONFIG_GROUP( cfg, oldgroup );
938 APP_CONFIG_END( cfg );
939}
940
941void Painter::setScheme(int Scheme, int Mode, Bitfont *font)
942{
943 bitfont = font;
944
945 mode = Mode;
946 scheme = Scheme;
947
948 confScheme();
949}
950
951void Painter::setLevel(int Level)
952{
953 level = Level;
954
955 initPixmaps();
956 initbackPixmaps();
957 initRoomPixmap();
958}
959
960int Painter::checkRange(int value, int max, int min)
961{
962 if (value < min) {
963 printf("Painter::checkRange (value = %d, max = %d, min = %d)\n",
964 value, max, min);
965 return min;
966 } else if (value > max) {
967 printf("Painter::checkRange (value = %d, max = %d, min = %d)\n",
968 value, max, min);
969 return max;
970 } else
971 return value;
972}
diff --git a/noncore/games/kpacman/painter.h b/noncore/games/kpacman/painter.h
new file mode 100644
index 0000000..3a4eae2
--- a/dev/null
+++ b/noncore/games/kpacman/painter.h
@@ -0,0 +1,148 @@
1#ifndef PAINTER_H
2#define PAINTER_H
3
4#include "portable.h"
5
6#if defined( KDE2_PORT )
7#include <kapp.h>
8#include <klocale.h>
9#endif
10
11#include <qpixmap.h>
12#include <qbitmap.h>
13#include <qlabel.h>
14#include <qcolor.h>
15#include <qlist.h>
16#include <qstrlist.h>
17#include <qregexp.h>
18
19#include "board.h"
20#include "bitfont.h"
21#include "colors.h"
22
23enum PixMap { PacmanPix, DyingPix, MonsterPix, EyesPix, FruitPix,
24 PointPix, EnergizerPix, WallPix, PrisonPix,
25 FruitScorePix, MonsterScorePix };
26enum DrawWidget { Widget, RoomPix, BackPix };
27
28class Painter
29{
30public:
31 Painter (Board *, QWidget *parent=0, int scheme=-1, int mode=-1,Bitfont *font=0);
32 QPixmap levelPix() { return roomPix; }
33
34 void setScheme(int scheme=-1, int mode=-1, Bitfont *font=0);
35 void setLevel(int level=0);
36
37 QRect rect(int pos, PixMap pix, uint i = 0);
38 QRect rect(int pos, QString str, int align = QLabel::AlignCenter );
39 QRect rect(QRect r1, QRect r2);
40
41 void draw(QPoint point, DrawWidget where, QPixmap pix);
42 void draw(QRect rect, DrawWidget where, QPixmap pix);
43 void draw(int pos, DrawWidget where, PixMap pix, uint i = 0);
44 QPixmap draw(int pos, DrawWidget where, QString str,
45 QColor fg, QColor bg = QColor(), int align = QLabel::AlignCenter);
46 QRect draw(int col, int row, DrawWidget where, QString str,
47 QColor fg, QColor bg = QColor(), int align = QLabel::AlignCenter);
48
49 void drawBrick(int pos);
50 void drawPrison(int pos);
51 void drawPoint(int pos);
52
53 void erase(int pos, PixMap pix, uint i = 0);
54
55 int maxPixmaps(PixMap pix);
56
57protected:
58 QString decodeHexOctString(QString str);
59
60 void fillScoreString(QStrList &, QArray<int> &);
61 void fillArray(QArray<int> &, QString, int);
62 void fillStrList(QStrList &, QString, int);
63 void fillPixmapName(QStrList &);
64
65 void confScheme();
66 void confLevels(bool defGroup=TRUE);
67 void confMisc(bool defGroup=TRUE);
68 void confScoring(bool defGroup=TRUE);
69
70 void initPixmaps();
71 void initRoomPixmap();
72 void initbackPixmaps();
73
74private:
75 QWidget *w;
76 Board *board;
77 Bitfont *bitfont;
78
79 int BlockWidth;
80 int BlockHeight;
81
82 QArray<int> fruitScore;
83 QStrList fruitScoreString;
84 QArray<int> monsterScore;
85 QStrList monsterScoreString;
86
87 QString pixmapDirectory;
88
89 QStrList pointPixmapName;
90 QStrList wallPixmapName;
91 QStrList prisonPixmapName;
92 QStrList energizerPixmapName;
93 QStrList fruitPixmapName;
94 QStrList pacmanPixmapName;
95 QStrList dyingPixmapName;
96 QStrList eyesPixmapName;
97 QStrList monsterPixmapName;
98 QStrList fruitScorePixmapName;
99 QStrList monsterScorePixmapName;
100
101 QString lastPointPixmapName;
102 QString lastWallPixmapName;
103 QString lastPrisonPixmapName;
104 QString lastEnergizerPixmapName;
105 QString lastFruitPixmapName;
106 QString lastPacmanPixmapName;
107 QString lastDyingPixmapName;
108 QString lastEyesPixmapName;
109 QString lastMonsterPixmapName;
110 QString lastFruitScorePixmapName;
111 QString lastMonsterScorePixmapName;
112
113 QList<QPixmap> *loadPixmap(QWidget *parent, QString pixmapName,
114 QList<QPixmap> *pixmaps=0);
115 QList<QPixmap> *textPixmap(QStrList &, QList<QPixmap> *pixmaps=0,
116 QColor fg = BLACK, QColor bg = QColor());
117 QList<QPixmap> *textPixmap(QString str, QList<QPixmap> *pixmaps=0,
118 QColor fg = BLACK, QColor bg = QColor());
119
120 QPoint point(int pos);
121 int checkRange(int value, int max, int min=0);
122
123 QList<QPixmap> *wallPix;
124 QList<QPixmap> *prisonPix;
125 QList<QPixmap> *pointPix;
126 QList<QPixmap> *energizerPix;
127 QList<QPixmap> *fruitPix;
128 QList<QPixmap> *pacmanPix;
129 QList<QPixmap> *dyingPix;
130 QList<QPixmap> *eyesPix;
131 QList<QPixmap> *monsterPix;
132 QList<QPixmap> *fruitScorePix;
133 QList<QPixmap> *monsterScorePix;
134
135 QPixmap roomPix;
136 QPixmap backPix;
137
138 bool plainColor;
139 QColor backgroundColor;
140
141 int maxLevel;
142 int level;
143
144 int scheme;
145 int mode;
146};
147
148#endif // PAINTER_H
diff --git a/noncore/games/kpacman/portable.h b/noncore/games/kpacman/portable.h
new file mode 100644
index 0000000..ff0912b
--- a/dev/null
+++ b/noncore/games/kpacman/portable.h
@@ -0,0 +1,63 @@
1/***************************************************************************
2 portable.h - various bits that ease porting kpacman to other platforms.
3 Currently KDE2 and Qtopia ports exist.
4 -------------------
5 begin : Mon Mar 18 12:35:24 EET 2002
6 copyright : (C) 2002 by Catalin Climov
7 email : catalin@climov.com
8 ***************************************************************************/
9
10/***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18
19#ifndef PORTABLE_H
20#define PORTABLE_H
21
22#ifdef QWS
23#define QPE_PORT
24#else
25#define KDE2_PORT
26#define KDE_PORT
27#endif
28
29#if defined( KDE2_PORT )
30
31#define APP kapp
32
33#define APP_CONFIG_BEGIN( cfgname ) KConfig cfgname = kapp->config()
34#define APP_CONFIG_END( cfgname ) cfgname->sync()
35#define SAVE_CONFIG_GROUP( cfgname, groupname ) QString groupname = configname->group()
36#define RESTORE_CONFIG_GROUP( cfgname, groupname ) configname->setGroup( groupname )
37
38#define FIND_APP_DATA( dataname ) KGlobal::dirs()->findResource( "appdata", dataname )
39
40#elif defined( QPE_PORT )
41
42#define i18n( x ) x
43#define KTMainWindow QMainWindow
44#define KMenuBar QMenuBar
45#define KAccel QAccel
46#define APP qApp
47
48#define APP_CONFIG_BEGIN( cfgname ) Config* cfgname = new Config("kpacman"); cfgname->setGroup("Default");
49#define APP_CONFIG_END( cfgname ) delete cfgname
50#define SAVE_CONFIG_GROUP( cfgname, groupname )
51#define RESTORE_CONFIG_GROUP( cfgname, groupname ) cfgname->setGroup("Default")
52
53#define FIND_APP_DATA( dataname ) (QPEApplication::qpeDir()+"share/kpacman/"+dataname)
54
55#else
56
57#error "Err, I don't know what platform to compile for (KDE2 or Qtopia)"
58
59#endif
60
61#define APP_QUIT() APP->quit()
62
63#endif // PORTABLE_H
diff --git a/noncore/games/kpacman/referee.cpp b/noncore/games/kpacman/referee.cpp
new file mode 100644
index 0000000..567a8ed
--- a/dev/null
+++ b/noncore/games/kpacman/referee.cpp
@@ -0,0 +1,1426 @@
1
2#include "portable.h"
3
4#if defined( KDE2_PORT )
5#include <kapp.h>
6#include <kconfig.h>
7#include <kstddirs.h>
8#include <kaccel.h>
9#include <referee.h>
10#include <referee.moc>
11#elif defined( QPE_PORT )
12#include <qaccel.h>
13#include <qpe/qpeapplication.h>
14#include "config.h"
15#include "referee.h"
16#endif
17
18#include <qdatetm.h>
19#include <stdlib.h>
20#include <qtimer.h>
21#include <qevent.h>
22#include <qcolor.h>
23#include <qkeycode.h>
24#include <qfileinfo.h>
25
26#include "board.h"
27#include "pacman.h"
28#include "monster.h"
29#include "fruit.h"
30#include "painter.h"
31
32Referee::Referee( QWidget *parent, const char *name, int Scheme, int Mode, Bitfont *font)
33 : QWidget( parent, name )
34{
35 gameState.resize(12);
36 gameTimer = 0;
37 energizerTimer = 0;
38
39 focusedPause = FALSE;
40 setFocusPolicy(QWidget::StrongFocus);
41
42 initKeys();
43
44 scheme = Scheme;
45 mode = Mode;
46 confScheme();
47
48 board = new Board(BoardWidth*BoardHeight);
49
50 pix = new Painter(board, this, scheme, mode, font);
51 setFixedSize(pix->levelPix().size());
52
53 pacman = new Pacman(board);
54
55 fruit = new Fruit(board);
56
57 monsters = new QList<Monster>;
58 monsters->setAutoDelete(TRUE);
59
60 monsterRect = new QList<QRect>;
61 monsterRect->setAutoDelete(TRUE);
62
63 energizers = new QList<Energizer>;
64 energizers->setAutoDelete(TRUE);
65
66 energizerRect = new QList<QRect>;
67 energizerRect->setAutoDelete(TRUE);
68
69 pacmanRect.setRect(0, 0, 0, 0);
70 fruitRect.setRect(0, 0, 0, 0);
71
72 QTime midnight( 0, 0, 0 );
73 srand( midnight.secsTo(QTime::currentTime()) );
74
75 lifes = 0;
76 points = 0;
77
78 emit setLifes(lifes);
79 emit setPoints(points);
80
81 intro();
82}
83
84void Referee::paintEvent( QPaintEvent *e)
85{
86 if (gameState.testBit(HallOfFame))
87 return;
88
89 QRect rect = e->rect();
90
91 if (!rect.isEmpty()) {
92 QPixmap p = pix->levelPix();
93 bitBlt(this, rect.x(), rect.y(),
94 &p, rect.x(), rect.y(), rect.width(), rect.height());
95 }
96
97 if ((gameState.testBit(GameOver) || gameState.testBit(Demonstration)) &&
98 rect.intersects(pix->rect(board->position(fruithome), i18n("GAME OVER"))))
99 pix->draw(board->position(fruithome), Widget, i18n("GAME OVER"), RED);
100
101 for (Energizer *e = energizers->first(); e != 0; e = energizers->next()) {
102 if (e && e->state() == on &&
103 rect.intersects(pix->rect(e->position(), EnergizerPix)) &&
104 !(e->position() == pacman->position() && gameState.testBit(Scoring))) {
105 if (e->pix() != -1)
106 pix->draw(e->position(), Widget, EnergizerPix, e->pix());
107 }
108 }
109
110 if (!gameState.testBit(Init)) {
111
112 if (!gameState.testBit(Dying) && (fruit->pix() != -1))
113 if (fruit->state() != active) {
114 if (rect.intersects(pix->rect(fruit->position(), FruitScorePix, fruit->pix())))
115 pix->draw(fruit->position(), Widget, FruitScorePix, fruit->pix());
116 } else {
117 if (rect.intersects(pix->rect(fruit->position(), FruitPix, fruit->pix())))
118 pix->draw(fruit->position(), Widget, FruitPix, fruit->pix());
119 }
120
121 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
122 if (m && m->state() == harmless &&
123 rect.intersects(pix->rect(m->position(), MonsterPix)) &&
124 !(m->position() == pacman->position() && gameState.testBit(Scoring))) {
125 if (m->body() != -1)
126 pix->draw(m->position(), Widget, MonsterPix, m->body());
127 if (m->eyes() != -1)
128 pix->draw(m->position(), Widget, EyesPix, m->eyes());
129 }
130
131 if (!gameState.testBit(Scoring) && !gameState.testBit(LevelDone) &&
132 rect.intersects(pix->rect(pacman->position(), PacmanPix)) && pacman->pix() != -1)
133 pix->draw(pacman->position(), Widget, PacmanPix, pacman->pix());
134
135 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
136 if (m && m->state() != harmless &&
137 rect.intersects(pix->rect(m->position(), MonsterPix)) &&
138 !(m->position() == pacman->position() && gameState.testBit(Scoring))) {
139 if (m->body() != -1)
140 pix->draw(m->position(), Widget, MonsterPix, m->body());
141 if (m->eyes() != -1)
142 pix->draw(m->position(), Widget, EyesPix, m->eyes());
143 }
144 }
145
146 if (gameState.testBit(Scoring) &&
147 rect.intersects(pix->rect(pacman->position(), MonsterScorePix, monstersEaten-1)))
148 pix->draw(pacman->position(), Widget, MonsterScorePix, monstersEaten-1);
149
150 if (gameState.testBit(Init) && gameState.testBit(Dying) &&
151 timerCount < pix->maxPixmaps(DyingPix) &&
152 rect.intersects(pix->rect(pacman->position(), PacmanPix)))
153 pix->draw(pacman->position(), Widget, DyingPix, timerCount);
154
155 if (gameState.testBit(LevelDone) &&
156 rect.intersects(pix->rect(pacman->position(), PacmanPix)))
157 pix->draw(pacman->position(), Widget, PacmanPix, pacman->pix());
158
159 if (gameState.testBit(Player) &&
160 rect.intersects(pix->rect(board->position(monsterhome, 0), i18n("PLAYER ONE"))))
161 pix->draw(board->position(monsterhome, 0), Widget, i18n("PLAYER ONE"), CYAN);
162
163 if (gameState.testBit(Ready) &&
164 rect.intersects(pix->rect(board->position(fruithome), i18n("READY!"))))
165 pix->draw(board->position(fruithome), Widget, i18n("READY!"), YELLOW);
166
167 if (gameState.testBit(Paused) &&
168 rect.intersects(pix->rect((BoardWidth*BoardHeight)/2-BoardWidth, i18n("PAUSED"))))
169 pix->draw((BoardWidth*BoardHeight)/2-BoardWidth, Widget, i18n("PAUSED"), RED, BLACK);
170}
171
172void Referee::timerEvent( QTimerEvent *e )
173{
174 if (gameState.testBit(HallOfFame))
175 return;
176
177 QRect lastRect;
178 int lastPix;
179 bool moved = FALSE;
180 int eated = 0;
181
182 if (e->timerId() == energizerTimer) {
183 for (int e = 0; e < board->energizers(); e++) {
184 lastRect = pix->rect(energizers->at(e)->position(), EnergizerPix);
185 lastPix = energizers->at(e)->pix();
186 if (energizers->at(e)->move()) {
187 moved = TRUE;
188 *energizerRect->at(e) = pix->rect(energizers->at(e)->position(), EnergizerPix);
189 if (lastPix == energizers->at(e)->pix() &&
190 lastRect == pix->rect(energizers->at(e)->position(), EnergizerPix))
191 energizerRect->at(e)->setRect(0, 0, 0, 0);
192 else
193 *energizerRect->at(e) = pix->rect(*energizerRect->at(e), lastRect);
194 }
195 }
196
197 for (int e = 0; e < board->energizers(); e++)
198 if (!energizerRect->at(e)->isNull())
199 repaint(*energizerRect->at(e), FALSE);
200
201 return;
202 }
203
204 timerCount++;
205
206 lastRect = pix->rect(pacman->position(), PacmanPix);
207 lastPix = pacman->pix();
208
209 if (moved = pacman->move()) { // pacman really moved
210 pacmanRect = pix->rect(pacman->position(), PacmanPix);
211 if (lastPix == pacman->pix() &&
212 lastRect == pix->rect(pacman->position(), PacmanPix))
213 pacmanRect.setRect(0, 0, 0, 0); // nothing to do, because the pixmap
214 else // and the position isn't changed.
215 pacmanRect = pix->rect(pacmanRect, lastRect);
216 } else
217 pacmanRect.setRect(0, 0, 0, 0);
218
219 int pos = pacman->position();
220
221 if (moved && board->isMonster(pos) && !gameState.testBit(Dying)) {
222 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
223 if (m && m->position() == pos) {
224 if (m->state() == harmless && !gameState.testBit(Dying)) {
225 m->setREM(remTicks[level]);
226 m->setDirection(X); // prevent movement before eaten()
227 eated++;
228 if (gameState.testBit(Introducing))
229 m->setPosition(OUT);
230 }
231 if (m->state() == dangerous && !gameState.testBit(Dying))
232 killed();
233 }
234 }
235
236 if (moved && !gameState.testBit(Dying)) {
237 if (board->isPoint(pos)) {
238 board->reset(pos, Point);
239 score(pointScore);
240 pix->erase(pos, PointPix);
241 }
242 if (board->isEnergizer(pos)) {
243 for (int e = 0; e < board->energizers();e++) {
244 if (energizers->at(e)->position() == pos) {
245 energizers->at(e)->setOff();
246 energizers->remove(e);
247 energizerRect->remove(e);
248 e = board->energizers();
249 }
250 }
251 board->reset(pos, energizer);
252 score(energizerScore);
253 monstersEaten = 0;
254 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
255 if (m && m->state() != rem) {
256 m->setHarmless(harmlessTicks[level], harmlessDurTicks[level],
257 harmlessWarnTicks[level]);
258 if (gameState.testBit(Introducing))
259 m->setDirection(board->turn(m->direction()));
260 }
261 }
262 if (pos == fruit->position() && fruit->state() == active) {
263 fruit->setEaten(fruitScoreDurTicks[level]);
264 initFruit(FALSE);
265 score(fruitScore[fruit->pix()]);
266 }
267 }
268
269 if (!gameState.testBit(Introducing)) {
270 if (fruit->state() != active && fruit->pix() >= 0)
271 lastRect = pix->rect(fruit->position(), FruitScorePix, fruit->pix());
272 else
273 lastRect = pix->rect(fruit->position(), FruitPix, fruit->pix());
274
275 lastPix = fruit->pix();
276 if (fruit->move()) {
277 if (pos == fruit->position() && fruit->state() == active) {
278 fruit->setEaten(fruitScoreDurTicks[level]);
279 initFruit(FALSE);
280 score(fruitScore[fruit->pix()]);
281 }
282 if (fruit->state() != active && fruit->pix() >= 0)
283 fruitRect = pix->rect(fruit->position(), FruitScorePix, fruit->pix());
284 else
285 fruitRect = pix->rect(fruit->position(), FruitPix, fruit->pix());
286 if (lastPix == fruit->pix() && lastRect == fruitRect)
287 fruitRect.setRect(0, 0, 0, 0);
288 else
289 fruitRect = pix->rect(fruitRect, lastRect);
290 } else
291 fruitRect.setRect(0, 0, 0, 0);
292 } else
293 fruitRect.setRect(0, 0, 0, 0);
294
295 int lastBodyPix;
296 int lastEyesPix;
297
298 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
299 if (m) {
300 lastRect = pix->rect(m->position(), MonsterPix);
301 lastBodyPix = m->body();
302 lastEyesPix = m->eyes();
303 if (m->move()) {
304 moved = TRUE;
305 *monsterRect->at(m->id()) = pix->rect(m->position(), MonsterPix);
306 if (lastBodyPix == m->body() && lastEyesPix == m->eyes() &&
307 lastRect == pix->rect(m->position(), MonsterPix))
308 monsterRect->at(m->id())->setRect(0, 0, 0, 0);
309 else
310 *monsterRect->at(m->id()) = pix->rect(*monsterRect->at(m->id()), lastRect);
311 if (m->position() == pos && !gameState.testBit(Dying)) {
312 if (m->state() == harmless && !gameState.testBit(Dying)) {
313 m->setREM(remTicks[level]);
314 eated++;
315 if (gameState.testBit(Introducing)) {
316 m->setPosition(OUT);
317 m->setDirection(X);
318 }
319 }
320 if (m->state() == dangerous && !gameState.testBit(Dying))
321 killed();
322 }
323 } else
324 monsterRect->at(m->id())->setRect(0, 0, 0, 0);
325 }
326
327 for (int m = 0; m < board->monsters(); m++)
328 if (pacmanRect.intersects(*monsterRect->at(m))) {
329 pacmanRect = pix->rect(pacmanRect, *monsterRect->at(m));
330 monsterRect->at(m)->setRect(0, 0, 0, 0);
331 } else
332 for (int im = m+1; im < board->monsters(); im++)
333 if (monsterRect->at(m)->intersects(*monsterRect->at(im))) {
334 *monsterRect->at(m) = pix->rect(*monsterRect->at(m), *monsterRect->at(im));
335 monsterRect->at(im)->setRect(0, 0, 0, 0);
336 }
337
338 if (!pacmanRect.isNull())
339 repaint(pacmanRect, FALSE);
340
341 if (!fruitRect.isNull())
342 repaint(fruitRect, FALSE);
343
344 for (int m = 0; m < board->monsters(); m++)
345 if (!monsterRect->at(m)->isNull())
346 repaint(*monsterRect->at(m), FALSE);
347
348 if (board->points() == 0 && !gameState.testBit(Dying))
349 levelUp();
350
351 if (eated > 0 && !gameState.testBit(Dying)) {
352 timerCount = eated;
353 eaten();
354 }
355
356 if (gameState.testBit(Introducing) && moved)
357 introPlay();
358}
359
360void Referee::repaintFigures()
361{
362 pacmanRect = pix->rect(pacman->position(), PacmanPix);
363
364 for (int e = 0; e < board->energizers(); e++) {
365 *energizerRect->at(e) = pix->rect(board->position(energizer, e), EnergizerPix);
366
367 if (pacmanRect.intersects(*energizerRect->at(e))) {
368 pacmanRect = pix->rect(pacmanRect, *energizerRect->at(e));
369 energizerRect->at(e)->setRect(0, 0, 0, 0);
370 } else
371 for (int ie = e+1; ie < board->energizers(); ie++)
372 if (energizerRect->at(e)->intersects(*energizerRect->at(ie))) {
373 *energizerRect->at(e) = pix->rect(*energizerRect->at(e), *energizerRect->at(ie));
374 energizerRect->at(ie)->setRect(0, 0, 0, 0);
375 }
376 }
377
378 if (fruit->pix() != -1 && fruit->state() != active)
379 fruitRect = pix->rect(fruit->position(), FruitScorePix, fruit->pix());
380 else
381 fruitRect = pix->rect(fruit->position(), FruitPix, fruit->pix());
382
383 if (pacmanRect.intersects(fruitRect)) {
384 pacmanRect = pix->rect(pacmanRect, fruitRect);
385 fruitRect.setRect(0, 0, 0, 0);
386 }
387
388 for (int m = 0; m < board->monsters(); m++) {
389 *monsterRect->at(m) = pix->rect(board->position(monster, m), MonsterPix);
390
391 if (pacmanRect.intersects(*monsterRect->at(m))) {
392 pacmanRect = pix->rect(pacmanRect, *monsterRect->at(m));
393 monsterRect->at(m)->setRect(0, 0, 0, 0);
394 } else
395 for (int im = m+1; im < board->monsters(); im++)
396 if (monsterRect->at(m)->intersects(*monsterRect->at(im))) {
397 *monsterRect->at(m) = pix->rect(*monsterRect->at(m), *monsterRect->at(im));
398 monsterRect->at(im)->setRect(0, 0, 0, 0);
399 }
400 }
401
402 if (!pacmanRect.isNull())
403 repaint(pacmanRect, FALSE);
404
405 if (!fruitRect.isNull())
406 repaint(fruitRect, FALSE);
407
408 for (int m = 0; m < board->monsters(); m++)
409 if (!monsterRect->at(m)->isNull())
410 repaint(*monsterRect->at(m), FALSE);
411
412 for (int e = 0; e < board->energizers(); e++)
413 if (!energizerRect->at(e)->isNull())
414 repaint(*energizerRect->at(e), FALSE);
415
416}
417
418void Referee::initKeys()
419{
420 APP_CONFIG_BEGIN( cfg );
421 QString up("Up");
422 up = cfg->readEntry("upKey", (const char*) up);
423 UpKey = KAccel::stringToKey(up);
424
425 QString down("Down");
426 down = cfg->readEntry("downKey", (const char*) down);
427 DownKey = KAccel::stringToKey(down);
428
429 QString left("Left");
430 left = cfg->readEntry("leftKey", (const char*) left);
431 LeftKey = KAccel::stringToKey(left);
432
433 QString right("Right");
434 right = cfg->readEntry("rightKey", (const char*) right);
435 RightKey = KAccel::stringToKey(right);
436 APP_CONFIG_END( cfg );
437}
438
439void Referee::fillArray(QArray<int> &array, QString values, int max)
440{
441 if (max < 0)
442 max = values.contains(',')+1;
443
444 array.resize(max);
445 int last = 0;
446 bool ok;
447 QString value;
448
449 for (uint i = 0; i < array.size(); i++) {
450 if (values.find(',') < 0 && values.length() > 0) {
451 value = values;
452 values = "";
453 }
454 if (values.find(',') >= 0) {
455 value = values.left(values.find(','));
456 values.remove(0,values.find(',')+1);
457 }
458 array[i] = value.toInt(&ok);
459 if (ok)
460 last = array[i];
461 else
462 array[i] = last;
463 }
464}
465
466void Referee::fillStrList(QStrList &list, QString values, int max)
467{
468 if (!list.isEmpty())
469 list.clear();
470
471 QString last = "";
472 QString value;
473
474 for (uint i = 0; i < (uint) max; i++) {
475 if (values.find(',') < 0 && values.length() > 0) {
476 value = values;
477 values = "";
478 }
479 if (values.find(',') >= 0) {
480 value = values.left(values.find(','));
481 values.remove(0,values.find(',')+1);
482 }
483 if (!value.isEmpty())
484 last = value;
485
486 list.append(last);
487 }
488}
489
490void Referee::fillMapName()
491{
492 QStrList list = mapName;
493
494 if (!mapName.isEmpty())
495 mapName.clear();
496
497 QString map;
498
499 QFileInfo fileInfo;
500
501 for (uint i = 0; i < list.count(); i++) {
502 map = list.at(i);
503
504 if (map.left(1) != "/" && map.left(1) != "~")
505 map = FIND_APP_DATA( mapDirectory+map );
506
507 fileInfo.setFile(map);
508 if (!fileInfo.isReadable())
509 map = "";
510
511 mapName.append(map);
512 }
513}
514
515void Referee::confLevels(bool defGroup)
516{
517 APP_CONFIG_BEGIN( cfg );
518 if (defGroup || cfg->hasKey("Levels"))
519 maxLevel = cfg->readNumEntry("Levels", 13);
520 APP_CONFIG_END( cfg );
521}
522
523void Referee::confMisc(bool defGroup)
524{
525 APP_CONFIG_BEGIN( cfg );
526 if (defGroup || cfg->hasKey("PixmapDirectory")) {
527 pixmapDirectory = cfg->readEntry("PixmapDirectory");
528
529 if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~")
530 pixmapDirectory.insert(0, "pics/");
531 if (pixmapDirectory.right(1) != "/")
532 pixmapDirectory.append("/");
533 }
534
535 if (defGroup || cfg->hasKey("MapDirectory")) {
536 mapDirectory = cfg->readEntry("MapDirectory");
537
538 if (mapDirectory.left(1) != "/" && mapDirectory.left(1) != "~")
539 mapDirectory.insert(0, "maps/");
540 if (mapDirectory.right(1) != "/")
541 mapDirectory.append("/");
542 }
543
544 if (defGroup || cfg->hasKey("MapName"))
545 fillStrList(mapName, cfg->readEntry("MapName", "map"), maxLevel+1);
546
547 if (defGroup || cfg->hasKey("MonsterIQ"))
548 fillArray(monsterIQ, cfg->readEntry("MonsterIQ", "0,170,180,170,180,170,180"), maxLevel+1);
549 if (defGroup || cfg->hasKey("FruitIQ"))
550 fillArray(fruitIQ, cfg->readEntry("FruitIQ", "0,170,180,170,180,170,180"), maxLevel+1);
551 if (defGroup || cfg->hasKey("FruitIndex"))
552 fillArray(fruitIndex, cfg->readEntry("FruitIndex", "0"), maxLevel+1);
553 APP_CONFIG_END( cfg );
554}
555
556void Referee::confTiming(bool defGroup)
557{
558 APP_CONFIG_BEGIN( cfg );
559 if (defGroup || cfg->hasKey("SpeedMS"))
560 fillArray(speed, cfg->readEntry("SpeedMS", "20"), maxLevel+1);
561 if (defGroup || cfg->hasKey("PacmanTicks"))
562 fillArray(pacmanTicks,cfg->readEntry("PacmanTicks", "3"), maxLevel+1);
563 if (defGroup || cfg->hasKey("RemTicks"))
564 fillArray(remTicks, cfg->readEntry("RemTicks", "1"), maxLevel+1);
565 if (defGroup || cfg->hasKey("DangerousTicks"))
566 fillArray(dangerousTicks, cfg->readEntry("DangerousTicks", "3"), maxLevel+1);
567 if (defGroup || cfg->hasKey("HarmlessTicks"))
568 fillArray(harmlessTicks, cfg->readEntry("HarmlessTicks", "7,6,,5,,4"), maxLevel+1);
569 if (defGroup || cfg->hasKey("HarmlessDurationTicks"))
570 fillArray(harmlessDurTicks, cfg->readEntry("HarmlessDurationTicks", "375,,,300,,250,200,150"), maxLevel+1);
571 if (defGroup || cfg->hasKey("HarmlessWarningTicks"))
572 fillArray(harmlessWarnTicks, cfg->readEntry("HarmlessWarningTicks", "135"), maxLevel+1);
573 if (defGroup || cfg->hasKey("ArrestTicks"))
574 fillArray(arrestTicks, cfg->readEntry("ArrestTicks", "6"), maxLevel+1);
575 if (defGroup || cfg->hasKey("ArrestDurationTicks"))
576 fillArray(arrestDurTicks, cfg->readEntry("ArrestDurationTicks", "200,,,150"), maxLevel+1);
577 if (defGroup || cfg->hasKey("FruitTicks"))
578 fillArray(fruitTicks, cfg->readEntry("FruitTicks", "7,6,,5,,4"), maxLevel+1);
579 if (defGroup || cfg->hasKey("FruitAppearsTicks"))
580 fillArray(fruitAppearsTicks, cfg->readEntry("FruitAppearsTicks", "1000,,1500,2000,2500,3000,3500,4000"), maxLevel+1);
581 if (defGroup || cfg->hasKey("FruitDurationTicks"))
582 fillArray(fruitDurTicks, cfg->readEntry("FruitDurationTicks", "500,,,400,350,300,,250,200,150"), maxLevel+1);
583 if (defGroup || cfg->hasKey("FruitScoreDurationTicks"))
584 fillArray(fruitScoreDurTicks, cfg->readEntry("FruitScoreDurationTicks", "150"), maxLevel+1);
585
586 if (defGroup || cfg->hasKey("MonsterScoreDurationMS"))
587 monsterScoreDurMS = cfg->readNumEntry("MonsterScoreDurationMS", 1000);
588 if (defGroup || cfg->hasKey("PlayerDurationMS"))
589 playerDurMS = cfg->readNumEntry("PlayerDurationMS", 3000);
590 if (defGroup || cfg->hasKey("ReadyDurationMS"))
591 readyDurMS = cfg->readNumEntry("ReadyDurationMS", 2000);
592 if (defGroup || cfg->hasKey("GameOverDurationMS"))
593 gameOverDurMS = cfg->readNumEntry("GameOverDurationMS", 3000);
594 if (defGroup || cfg->hasKey("AfterPauseMS"))
595 afterPauseMS = cfg->readNumEntry("AfterPauseMS", 1000);
596 if (defGroup || cfg->hasKey("DyingPreAnimationMS"))
597 dyingPreAnimationMS = cfg->readNumEntry("DyingPreAnimationMS", 1000);
598 if (defGroup || cfg->hasKey("DyingAnimationMS"))
599 dyingAnimationMS = cfg->readNumEntry("DyingAnimationMS", 100);
600 if (defGroup || cfg->hasKey("DyingPostAnimationMS"))
601 dyingPostAnimationMS = cfg->readNumEntry("DyingPostAnimationMS", 500);
602 if (defGroup || cfg->hasKey("IntroAnimationMS"))
603 introAnimationMS = cfg->readNumEntry("IntroAnimationMS", 800);
604 if (defGroup || cfg->hasKey("IntroPostAnimationMS"))
605 introPostAnimationMS = cfg->readNumEntry("IntroPostAnimationMS", 1000);
606 if (defGroup || cfg->hasKey("LevelUpPreAnimationMS"))
607 levelUpPreAnimationMS = cfg->readNumEntry("LevelUpPreAnimationMS", 2000);
608 if (defGroup || cfg->hasKey("LevelUpAnimationMS"))
609 levelUpAnimationMS = cfg->readNumEntry("LevelUpAnimationMS", 2000);
610 if (defGroup || cfg->hasKey("EnergizerAnimationMS"))
611 energizerAnimationMS = cfg->readNumEntry("EnergizerAnimationMS", 200);
612 APP_CONFIG_END( cfg );
613}
614
615void Referee::confScoring(bool defGroup)
616{
617 APP_CONFIG_BEGIN( cfg );
618 if (defGroup || cfg->hasKey("PointScore"))
619 pointScore = cfg->readNumEntry("PointScore", 10);
620 if (defGroup || cfg->hasKey("EnergizerScore"))
621 energizerScore = cfg->readNumEntry("EnergizerScore", 50);
622 if (defGroup || cfg->hasKey("FruitScore"))
623 fillArray(fruitScore, cfg->readEntry("FruitScore", "100,300,500,,700,,1000,,2000,,3000,,5000"), maxLevel+1);
624 if (defGroup || cfg->hasKey("MonsterScore"))
625 fillArray(monsterScore, cfg->readEntry("MonsterScore", "200,400,800,1600"), 4);
626 if (defGroup || cfg->hasKey("ExtraLifeScore"))
627 fillArray(extraLifeScore, cfg->readEntry("ExtraLifeScore", "10000"), -1);
628 APP_CONFIG_END( cfg );
629}
630
631void Referee::confScheme()
632{
633 APP_CONFIG_BEGIN( cfg );
634 SAVE_CONFIG_GROUP( cfg, oldgroup );
635 QString newgroup;
636
637 // if not set, read mode and scheme from the configfile
638 if (mode == -1 && scheme == -1) {
639 scheme = cfg->readNumEntry("Scheme", -1);
640 mode = cfg->readNumEntry("Mode", -1);
641
642 // if mode is not set in the defGroup-group, lookup the scheme group
643 if (scheme != -1 || mode == -1) {
644 newgroup.sprintf("Scheme %d", scheme);
645 cfg->setGroup(newgroup);
646
647 mode = cfg->readNumEntry("Mode", -1);
648 RESTORE_CONFIG_GROUP( cfg, oldgroup );
649 }
650 }
651
652 confLevels();
653
654 if (mode != -1) {
655 newgroup.sprintf("Mode %d", mode);
656 cfg->setGroup(newgroup);
657
658 confLevels(FALSE);
659 }
660
661 if (scheme != -1) {
662 newgroup.sprintf("Scheme %d", scheme);
663 cfg->setGroup(newgroup);
664
665 confLevels(FALSE);
666 }
667
668 RESTORE_CONFIG_GROUP( cfg, oldgroup );
669
670 confMisc();
671 confTiming();
672 confScoring();
673
674 if (mode != -1) {
675 newgroup.sprintf("Mode %d", mode);
676 cfg->setGroup(newgroup);
677
678 confMisc(FALSE);
679 confTiming(FALSE);
680 confScoring(FALSE);
681 }
682
683 if (scheme != -1) {
684 newgroup.sprintf("Scheme %d", scheme);
685 cfg->setGroup(newgroup);
686
687 confMisc(FALSE);
688 confTiming(FALSE);
689 confScoring(FALSE);
690 }
691
692 fillMapName();
693
694 RESTORE_CONFIG_GROUP( cfg, oldgroup );
695 APP_CONFIG_END( cfg );
696}
697
698void Referee::setScheme(int Scheme, int Mode, Bitfont *font)
699{
700 mode = Mode;
701 scheme = Scheme;
702
703 confScheme();
704
705 pix->setScheme(scheme, mode, font);
706
707 pacman->setMaxPixmaps(pix->maxPixmaps(PacmanPix));
708 fruit->setMaxPixmaps(pix->maxPixmaps(FruitPix));
709
710 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
711 if (m)
712 m->setMaxPixmaps(pix->maxPixmaps(MonsterPix), pix->maxPixmaps(EyesPix));
713
714 for (Energizer *e = energizers->first(); e != 0; e = energizers->next())
715 if (e)
716 e->setMaxPixmaps(pix->maxPixmaps(EnergizerPix));
717
718 if (gameState.testBit(Introducing))
719 for (int i = 0; i < (gameState.testBit(Init) ? timerCount : 15); i++)
720 introPaint(i);
721
722 setFixedSize(pix->levelPix().size());
723 repaint();
724}
725
726void Referee::keyPressEvent( QKeyEvent *k )
727{
728 uint key = k->key();
729#ifdef QWS
730 // "OK" => new game
731 if ( key == Key_F33 || key == Key_F2 || key == Key_Enter )
732 play();
733 else if ( !gameState.testBit(Playing) && key == Key_Space )
734 play();
735 // "Space" => pause
736 //else if ( key == Key_Space || key == Key_F3 )
737 // pause();
738 // "Menu" => hall of fame
739 //else if ( key == Key_F11 || key == Key_F4 )
740 // toggleHallOfFame();
741#endif
742
743 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame) ||
744 gameState.testBit(Demonstration) || gameState.testBit(Dying) ||
745 gameState.testBit(Ready) || gameState.testBit(LevelDone) ||
746 !gameState.testBit(Playing))
747 return;
748
749 if (key == UpKey)
750 pacman->setDirection(N);
751 else if (key == DownKey)
752 pacman->setDirection(S);
753 else if (key == RightKey)
754 pacman->setDirection(E);
755 else if (key == LeftKey)
756 pacman->setDirection(W);
757
758#ifdef CHEATS
759 else if (key == Key_L) { printf("levelUp()\n"); levelUp(); }
760 else if (key == Key_F) { printf("fruit->move(TRUE)\n"); fruit->move(TRUE); repaint(FALSE); }
761 else if (key == Key_E) { printf("setLifes(++lifes)\n"); emit setLifes(++lifes); }
762#endif
763
764 else {
765 k->ignore();
766 return;
767 }
768 k->accept();
769}
770
771void Referee::score(int p)
772{
773 if (!gameState.testBit(Playing))
774 return;
775
776 if ((points += p) < 0)
777 points = 0;
778
779 emit setPoints(points);
780
781 if (points >= nextExtraLifeScore) {
782 emit setLifes(++lifes);
783 if (extraLifeScoreIndex < (int) extraLifeScore.size()-1)
784 extraLifeScoreIndex++;
785 if (extraLifeScore[extraLifeScoreIndex] < 0)
786 nextExtraLifeScore = extraLifeScore[extraLifeScoreIndex] * -1;
787 else
788 nextExtraLifeScore += extraLifeScore[extraLifeScoreIndex];
789 }
790}
791
792void Referee::eaten()
793{
794 if (gameState.testBit(Ready))
795 return;
796
797 stop();
798
799 if (monstersEaten < 4)
800 monstersEaten++;
801
802 gameState.setBit(Scoring);
803 score(monsterScore[monstersEaten-1]);
804
805 repaint(pix->rect(pix->rect(pacman->position(), MonsterPix),
806 pix->rect(pacman->position(), MonsterScorePix, monstersEaten-1)));
807
808 if (--timerCount > 0)
809 QTimer::singleShot( monsterScoreDurMS, this, SLOT(eaten()));
810 else {
811 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
812 if (m && m->direction() == X && !gameState.testBit(Introducing))
813 m->setDirection(N);
814 if (monstersEaten != 4 || !gameState.testBit(Introducing))
815 QTimer::singleShot( monsterScoreDurMS, this, SLOT(start()));
816 }
817}
818
819void Referee::toggleHallOfFame()
820{
821 gameState.toggleBit(HallOfFame);
822}
823
824void Referee::hallOfFame()
825{
826 if (gameState.testBit(HallOfFame)) // If the HallOfFame is switched on manually, toggle the
827 toggleHallOfFame(); // bit twice.
828
829 emit setLevel(0); // Clear status display for hall of fame
830 emit setScore(level, 0);
831 emit forcedHallOfFame(TRUE);
832}
833
834void Referee::pause()
835{
836 static int pausedTimer = 0;
837
838 if (!gameState.testBit(Paused)) {
839 pausedTimer = gameTimer;
840 stop();
841 stopEnergizer();
842 gameState.setBit(Paused);
843 repaint(pix->rect((BoardWidth*BoardHeight)/2-BoardWidth, i18n("PAUSED")), FALSE);
844 } else {
845 gameState.clearBit(Paused);
846 repaint(pix->rect((BoardWidth*BoardHeight)/2-BoardWidth, i18n("PAUSED")), FALSE);
847 if (pausedTimer) {
848 pausedTimer = 0;
849 start();
850 }
851 }
852 emit togglePaused();
853}
854
855void Referee::intro()
856{
857 stop();
858 stopEnergizer();
859 bool paused = gameState.testBit(Paused);
860
861 gameState.fill(FALSE);
862 gameState.setBit(Introducing);
863 gameState.setBit(Init);
864
865 if (paused)
866 gameState.setBit(Paused);
867
868 level = 0;
869 emit setLevel(level);
870
871 board->init(Intro);
872 pix->setLevel(level);
873
874 initPacman();
875 initFruit();
876 initMonsters();
877 initEnergizers();
878
879 repaint();
880
881 monstersEaten = 0;
882 timerCount = 0;
883 introPlay();
884}
885
886void Referee::introMonster(int id)
887{
888 Monster *m = new Monster(board, id);
889
890 m->setPosition((10+id*6)*BoardWidth+10);
891 m->setDirection(E);
892 m->setDangerous(dangerousTicks[level], monsterIQ[level]);
893 m->setMaxPixmaps(pix->maxPixmaps(MonsterPix), pix->maxPixmaps(EyesPix));
894
895 if (m->body() != -1)
896 pix->draw(m->position(), RoomPix, MonsterPix, m->body());
897 if (m->eyes() != -1)
898 pix->draw(m->position(), RoomPix, EyesPix, m->eyes());
899
900 repaint(pix->rect(m->position(), MonsterPix), FALSE);
901 m->setPosition(OUT);
902}
903
904void Referee::introPaint(int t)
905{
906 QString pts;
907
908 switch (t) {
909 case 0 : repaint(pix->draw(16, 6, RoomPix, i18n("CHARACTER"), WHITE, QColor(), AlignLeft), FALSE);
910 repaint(pix->draw(36, 6, RoomPix, i18n("/"), WHITE, QColor(), AlignLeft), FALSE);
911 repaint(pix->draw(40, 6, RoomPix, i18n("NICKNAME"), WHITE, QColor(), AlignLeft), FALSE);
912 break;
913 case 1 : introMonster(0);
914 break;
915 case 2 : repaint(pix->draw(16, 10, RoomPix, i18n("-SHADOW"), RED, QColor(), AlignLeft), FALSE);
916 break;
917 case 3 : repaint(pix->draw(38, 10, RoomPix, i18n("\"BLINKY\""), RED, QColor(), AlignLeft), FALSE);
918 break;
919 case 4 : introMonster(1);
920 break;
921 case 5 : repaint(pix->draw(16, 16, RoomPix, i18n("-SPEEDY"), PINK, QColor(), AlignLeft), FALSE);
922 break;
923 case 6 : repaint(pix->draw(38, 16, RoomPix, i18n("\"PINKY\""), PINK, QColor(), AlignLeft), FALSE);
924 break;
925 case 7 : introMonster(2);
926 break;
927 case 8 : repaint(pix->draw(16, 22, RoomPix, i18n("-BASHFUL"), CYAN, QColor(), AlignLeft), FALSE);
928 break;
929 case 9 : repaint(pix->draw(38, 22, RoomPix, i18n("\"INKY\""), CYAN, QColor(), AlignLeft), FALSE);
930 break;
931 case 10 : introMonster(3);
932 break;
933 case 11 : repaint(pix->draw(16, 28, RoomPix, i18n("-POKEY"), ORANGE, QColor(), AlignLeft), FALSE);
934 break;
935 case 12 : repaint(pix->draw(38, 28, RoomPix, i18n("\"CLYDE\""), ORANGE, QColor(), AlignLeft), FALSE);
936 break;
937 case 13 : pts.sprintf("%d", pointScore);
938 repaint(pix->draw(28, 44, RoomPix, pts.data(), WHITE, QColor(), AlignRight), FALSE);
939 repaint(pix->draw(31, 44, RoomPix, "\x1C\x1D\x1E", WHITE, QColor(), AlignLeft), FALSE);
940 pts.sprintf("%d", energizerScore);
941 repaint(pix->draw(28, 48, RoomPix, pts.data(), WHITE, QColor(), AlignRight), FALSE);
942 repaint(pix->draw(31, 48, RoomPix, "\x1C\x1D\x1E", WHITE, QColor(), AlignLeft), FALSE);
943 break;
944 case 14 : // "@ 1980 MIDWAY MFG.CO."
945#if defined( KDE2_PORT )
946 repaint(pix->draw(30, 58, RoomPix, "© 1998-2002 J.THÖNNISSEN", PINK), FALSE);
947#elif defined( QPE_PORT )
948 repaint(pix->draw(30, 55, RoomPix, "© 1998-2002 J.THÖNNISSEN", PINK), FALSE);
949 repaint(pix->draw(29, 60, RoomPix, "Qtopia port: Catalin CLIMOV", GREEN), FALSE);
950#endif
951 break;
952 }
953}
954
955void Referee::introPlay()
956{
957 if (!gameState.testBit(Introducing) || gameState.testBit(Ready))
958 return;
959 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
960 QTimer::singleShot(afterPauseMS, this, SLOT(introPlay()));
961 return;
962 }
963
964 if (!gameState.testBit(Init)) {
965 if (monstersEaten == 4) {
966 stop();
967 QTimer::singleShot(introPostAnimationMS, this, SLOT(demo()));
968 }
969 if (pacman->direction() == W) {
970 int id = -1;
971 if (pacman->position() == 37*BoardWidth-6)
972 id = 0;
973 else
974 if (board->isMonster(37*BoardWidth-6))
975 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
976 if (m && m->position() == 37*BoardWidth-6) {
977 id = m->id();
978 id++;
979 break;
980 }
981
982 if (id >= 0 && id <= 4)
983 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
984 if (m && m->id() == id && m->position() == OUT) {
985 m->setPosition(37*BoardWidth-1);
986 m->setDirection(W);
987 m->setDangerous(dangerousTicks[level], monsterIQ[level]);
988 board->set(37*BoardWidth-1, monsterhome, id);
989 repaint(pix->rect(m->position(), MonsterPix));
990 break;
991 }
992 }
993 return;
994 }
995
996 if (timerCount < 15)
997 introPaint(timerCount);
998
999 switch (timerCount) {
1000 case 13 : board->set(44*BoardWidth+22, Point);
1001 pix->drawPoint(44*BoardWidth+22);
1002 repaint(pix->rect(44*BoardWidth+22, PointPix), FALSE);
1003 energizers->at(0)->setPosition(48*BoardWidth+22);
1004 energizers->at(0)->setOn();
1005 repaint(pix->rect(48*BoardWidth+22, EnergizerPix), FALSE);
1006 break;
1007 case 14 : energizers->at(1)->setPosition(36*BoardWidth+10);
1008 energizers->at(1)->setOn();
1009 repaint(pix->rect(36*BoardWidth+10, EnergizerPix), FALSE);
1010 for (int pos = 8; pos < BoardWidth; pos++) {
1011 board->set(34*BoardWidth+pos, out);
1012 board->set(38*BoardWidth+pos, out);
1013 }
1014 board->set(36*BoardWidth+8, out);
1015 break;
1016 case 15 : gameState.clearBit(Init);
1017 initPacman();
1018 pacman->setDemo(TRUE);
1019 pacman->setPosition(37*BoardWidth-1);
1020 repaintFigures();
1021 start();
1022 return;
1023 }
1024
1025 if (timerCount++ < 15)
1026 QTimer::singleShot(introAnimationMS, this, SLOT(introPlay()));
1027}
1028
1029void Referee::demo()
1030{
1031 if (gameState.testBit(Ready))
1032 return;
1033
1034 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
1035 QTimer::singleShot(afterPauseMS, this, SLOT(demo()));
1036 return;
1037 }
1038
1039 stop();
1040 stopEnergizer();
1041
1042 gameState.fill(FALSE);
1043 gameState.setBit(Init);
1044 gameState.setBit(Demonstration);
1045
1046 level = 0;
1047 emit setLevel(level);
1048
1049 board->init(Demo, mapName.at(0));
1050 pix->setLevel(level);
1051
1052 initPacman();
1053 initFruit();
1054 initMonsters();
1055 initEnergizers();
1056
1057 gameState.clearBit(Init);
1058
1059 repaint();
1060
1061 timerCount = 0;
1062 QTimer::singleShot(playerDurMS, this, SLOT(start()));
1063}
1064
1065void Referee::play()
1066{
1067 stop();
1068 stopEnergizer();
1069
1070 gameState.fill(FALSE);
1071 gameState.setBit(Init);
1072 gameState.setBit(Playing);
1073 gameState.setBit(Player);
1074 gameState.setBit(Ready);
1075
1076 lifes = 3;
1077 level = 1;
1078 points = 0;
1079
1080 extraLifeScoreIndex = 0;
1081 nextExtraLifeScore = extraLifeScore[extraLifeScoreIndex];
1082 if (nextExtraLifeScore < 0)
1083 nextExtraLifeScore *= -1;
1084
1085 board->init(Level, mapName.at(level));
1086 pix->setLevel(level);
1087
1088 initPacman();
1089 initFruit();
1090 initMonsters();
1091 initEnergizers();
1092
1093 repaint();
1094 emit toggleNew();
1095 emit setLifes(lifes);
1096 emit setLevel(level);
1097 emit setPoints(points);
1098
1099 repaint(pix->rect(board->position(monsterhome, 0), i18n("PLAYER ONE")), FALSE);
1100 repaint(pix->rect(board->position(fruithome), i18n("READY!")), FALSE);
1101
1102 timerCount = 0;
1103 QTimer::singleShot(playerDurMS, this, SLOT(ready()));
1104}
1105
1106void Referee::ready()
1107{
1108 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
1109 QTimer::singleShot(afterPauseMS, this, SLOT(ready()));
1110 return;
1111 }
1112
1113 if (gameState.testBit(Player)) {
1114 emit setLifes(--lifes);
1115 gameState.clearBit(Player);
1116 gameState.clearBit(Init);
1117 repaint(pix->rect(board->position(monsterhome, 0), i18n("PLAYER ONE")), FALSE);
1118 repaintFigures();
1119 QTimer::singleShot(playerDurMS, this, SLOT(ready()));
1120 return;
1121 }
1122
1123 if (gameState.testBit(Ready)) {
1124 gameState.clearBit(Ready);
1125 repaint(pix->rect(board->position(fruithome), i18n("READY!")), FALSE);
1126 start();
1127 } else {
1128 gameState.setBit(Ready);
1129 gameState.clearBit(Init);
1130 repaint(pix->rect(board->position(fruithome), i18n("READY!")), FALSE);
1131 QTimer::singleShot(readyDurMS, this, SLOT(ready()));
1132 }
1133}
1134
1135
1136void Referee::levelUp()
1137{
1138 stop();
1139 stopEnergizer();
1140
1141 gameState.setBit(LevelDone);
1142 pacman->setPosition(pacman->position()); // set mouthPosition to "0"
1143 repaint(pix->rect(pacman->position(), PacmanPix));
1144
1145 timerCount = 0;
1146 QTimer::singleShot(levelUpPreAnimationMS, this, SLOT(levelUpPlay()));
1147}
1148
1149void Referee::levelUpPlay()
1150{
1151 if (gameState.testBit(Ready))
1152 return;
1153
1154 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
1155 QTimer::singleShot(afterPauseMS, this, SLOT(levelUpPlay()));
1156 return;
1157 }
1158
1159 switch (timerCount) {
1160 case 0 : gameState.setBit(Init);
1161 setOnEnergizers();
1162 repaintFigures();
1163 break;
1164 case 1 : gameState.clearBit(LevelDone);
1165 repaint(pix->rect(pacman->position(), PacmanPix));
1166 break;
1167 }
1168
1169 if (timerCount++ < 2) {
1170 QTimer::singleShot(levelUpAnimationMS, this, SLOT(levelUpPlay()));
1171 return;
1172 }
1173
1174 gameState.clearBit(Init);
1175
1176 if (gameState.testBit(Demonstration)) {
1177 hallOfFame();
1178 return;
1179 }
1180
1181 if (level < maxLevel)
1182 level++;
1183
1184 board->init(Level, mapName.at(level));
1185 pix->setLevel(level);
1186
1187 initPacman();
1188 initFruit();
1189 initMonsters();
1190 initEnergizers();
1191
1192 repaint();
1193 emit setLevel(level);
1194
1195 ready();
1196}
1197
1198void Referee::start()
1199{
1200 if (gameState.testBit(Ready))
1201 return;
1202
1203 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
1204 QTimer::singleShot(afterPauseMS, this, SLOT(start()));
1205 return;
1206 }
1207
1208 if (gameState.testBit(Scoring)) {
1209 gameState.clearBit(Scoring);
1210 repaint(pix->rect(pix->rect(pacman->position(), MonsterPix),
1211 pix->rect(pacman->position(), MonsterScorePix, monstersEaten-1)));
1212 }
1213
1214 if (!gameTimer)
1215 gameTimer = startTimer( speed [level] );
1216
1217 if (!energizerTimer)
1218 energizerTimer = startTimer( energizerAnimationMS );
1219}
1220
1221void Referee::start(int t)
1222{
1223 gameTimer = startTimer(t);
1224}
1225
1226void Referee::stop()
1227{
1228 if (gameTimer) {
1229 killTimer (gameTimer);
1230 gameTimer = 0;
1231 }
1232}
1233
1234void Referee::stopEnergizer()
1235{
1236 if (energizerTimer) {
1237 killTimer (energizerTimer);
1238 energizerTimer = 0;
1239 }
1240}
1241
1242void Referee::killed()
1243{
1244 if (gameState.testBit(Ready))
1245 return;
1246
1247 if (!gameState.testBit(Dying)) {
1248 gameState.setBit(Dying);
1249
1250 pacman->setDirection(X, TRUE);
1251 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
1252 if (m)
1253 m->setDirection(X);
1254 QTimer::singleShot(dyingPreAnimationMS, this, SLOT(killed()));
1255 } else {
1256 stop();
1257 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
1258 QTimer::singleShot(afterPauseMS, this, SLOT(killed()));
1259 return;
1260 }
1261
1262 gameState.setBit(Init);
1263
1264 repaintFigures();
1265
1266 timerCount = 0;
1267 killedPlay();
1268 }
1269}
1270
1271void Referee::killedPlay()
1272{
1273 if (!gameState.testBit(Dying) || gameState.testBit(Ready))
1274 return;
1275 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
1276 QTimer::singleShot(afterPauseMS, this, SLOT(killedPlay()));
1277 return;
1278 }
1279
1280 if (timerCount <= pix->maxPixmaps(DyingPix)) {
1281 repaint(pix->rect(pacman->position(), PacmanPix), FALSE);
1282 if (timerCount >= pix->maxPixmaps(DyingPix)-1 || timerCount == 0)
1283 QTimer::singleShot(dyingPostAnimationMS, this, SLOT(killedPlay()));
1284 else
1285 QTimer::singleShot(dyingAnimationMS, this, SLOT(killedPlay()));
1286 timerCount++;
1287 } else {
1288 gameState.clearBit(Dying);
1289 stopEnergizer();
1290 if (lifes == 0) {
1291 gameState.setBit(GameOver);
1292 gameState.clearBit(Playing);
1293 for (int e = 0; e < board->energizers(); e++) {
1294 energizers->at(e)->setOff();
1295 repaint(pix->rect(board->position(energizer, e), EnergizerPix), FALSE);
1296 }
1297 repaint(pix->rect(board->position(fruithome), i18n("GAME OVER")), FALSE);
1298 QTimer::singleShot(gameOverDurMS, this, SLOT(hallOfFame()));
1299 } else {
1300 gameState.clearBit(Init);
1301 initPacman();
1302 initFruit();
1303 initMonsters();
1304 initEnergizers();
1305 emit setLifes(--lifes);
1306 repaintFigures();
1307 ready();
1308 }
1309 }
1310}
1311
1312void Referee::initPacman()
1313{
1314 pacman->setMaxPixmaps(pix->maxPixmaps(PacmanPix));
1315 pacman->setDemo(gameState.testBit(Demonstration));
1316 pacman->setPosition(board->position(pacmanhome));
1317 pacman->setDirection(W, TRUE);
1318 pacman->setAlive(pacmanTicks[level]);
1319}
1320
1321void Referee::initFruit(bool fullInitialization)
1322{
1323 if (fullInitialization) {
1324 fruit->setMaxPixmaps(pix->maxPixmaps(FruitPix));
1325 if (fruitIndex[level] == 0)
1326 fruit->setLevel(level, fruitAppearsTicks[level],
1327 fruitDurTicks[level], fruitTicks[level]);
1328 else if (fruitIndex[level] < 0)
1329 fruit->setLevel(pix->maxPixmaps(FruitPix)+1,
1330 fruitAppearsTicks[level],
1331 fruitDurTicks[level], fruitTicks[level]);
1332 else
1333 fruit->setLevel(fruitIndex[level], fruitAppearsTicks[level],
1334 fruitDurTicks[level], fruitTicks[level]);
1335 }
1336
1337 if (board->tunnels() > 0)
1338 fruit->setMovement(board->position(tunnel, rand() % board->tunnels()),
1339 board->position(tunnel, rand() % board->tunnels()),
1340 fruitIQ[level]);
1341}
1342
1343void Referee::initMonsters()
1344{
1345 if( !monsters->isEmpty())
1346 monsters->clear();
1347 if( !monsterRect->isEmpty())
1348 monsterRect->clear();
1349
1350 for (int id = 0; id < (gameState.testBit(Introducing) ? 4 : board->monsters()); id++) {
1351 Monster *m = new Monster(board, id);
1352 monsters->append(m);
1353 QRect *r = new QRect();
1354 monsterRect->append(r);
1355 if (!gameState.testBit(Introducing)) {
1356 m->setFreedom(board->position(prisonexit));
1357 m->setDangerous(dangerousTicks[level], monsterIQ[level]);
1358 if (id == 0)
1359 m->setPrison(board->position(prisonentry));
1360 else {
1361 m->setPrison(board->position(monsterhome, id));
1362 m->setArrested(arrestTicks[level], arrestDurTicks[level]*id);
1363 }
1364 m->setPosition(board->position(monsterhome, id));
1365 switch(id) {
1366 case 0 : m->setDirection(W); break;
1367 case 1 : m->setDirection(N); break;
1368 default : m->setDirection(S);
1369 }
1370 }
1371 m->setMaxPixmaps(pix->maxPixmaps(MonsterPix), pix->maxPixmaps(EyesPix));
1372 }
1373}
1374
1375void Referee::initEnergizers()
1376{
1377 if( !energizers->isEmpty())
1378 energizers->clear();
1379 if( !energizerRect->isEmpty())
1380 energizerRect->clear();
1381
1382 for (int id = 0; id < (gameState.testBit(Introducing) ? 2 : board->energizers()); id++) {
1383 Energizer *e = new Energizer(board);
1384 energizers->append(e);
1385 QRect *r = new QRect();
1386 energizerRect->append(r);
1387 if (!gameState.testBit(Introducing)) {
1388 e->setPosition(board->position(energizer, id));
1389 e->setOn();
1390 }
1391 e->setMaxPixmaps(pix->maxPixmaps(EnergizerPix));
1392 }
1393}
1394
1395void Referee::setOnEnergizers()
1396{
1397 for (int e = 0; e < board->energizers(); e++) {
1398 energizers->at(e)->setOn();
1399 }
1400}
1401
1402void Referee::setFocusOutPause(bool FocusOutPause)
1403{
1404 focusOutPause = FocusOutPause;
1405}
1406
1407void Referee::setFocusInContinue(bool FocusInContinue)
1408{
1409 focusInContinue = FocusInContinue;
1410}
1411
1412void Referee::focusInEvent(QFocusEvent *)
1413{
1414 if (focusInContinue && focusedPause &&
1415 gameState.testBit(Paused) && gameState.testBit(Playing)) {
1416 pause();
1417 }
1418}
1419
1420void Referee::focusOutEvent(QFocusEvent *)
1421{
1422 if (focusOutPause && !gameState.testBit(Paused) && gameState.testBit(Playing)) {
1423 focusedPause = TRUE;
1424 pause();
1425 }
1426}
diff --git a/noncore/games/kpacman/referee.h b/noncore/games/kpacman/referee.h
new file mode 100644
index 0000000..f812de4
--- a/dev/null
+++ b/noncore/games/kpacman/referee.h
@@ -0,0 +1,196 @@
1#ifndef REFEREE_H
2#define REFEREE_H
3
4#ifdef HAVE_CONFIG_H
5#include <config.h>
6#endif
7
8#include "portable.h"
9
10#if defined( KDE2_PORT )
11#include <kapp.h>
12#endif
13
14#include <qwidget.h>
15#include <qlist.h>
16#include <qstrlist.h>
17#include <qarray.h>
18#include <qbitarry.h>
19
20#include "board.h"
21#include "pacman.h"
22#include "monster.h"
23#include "fruit.h"
24#include "energizer.h"
25#include "bitfont.h"
26#include "painter.h"
27
28enum { Init, Introducing, Playing, Demonstration, Paused, Player, Ready,
29 Scoring, LevelDone, Dying, GameOver, HallOfFame };
30
31
32class Referee : public QWidget
33{
34 Q_OBJECT
35public:
36 Referee (QWidget *parent=0, const char *name=0, int scheme=-1, int mode=-1, Bitfont *font=0);
37
38 void setSkill(int);
39 void setRoom(int);
40
41public slots:
42 void setScheme(int scheme, int mode, Bitfont *font=0);
43
44 void levelUp();
45 void levelUpPlay();
46
47 void pause();
48 void ready();
49 void intro();
50 void introPlay();
51 void hallOfFame();
52 void demo();
53 void play();
54 void killed();
55 void killedPlay();
56 void eaten();
57 void toggleHallOfFame();
58
59 void setFocusOutPause(bool focusOutPause);
60 void setFocusInContinue(bool focusInContinue);
61 void initKeys();
62
63 void repaintFigures();
64
65private slots:
66 void start();
67 void stop();
68 void stopEnergizer();
69
70signals:
71 void setScore(int, int);
72 void setPoints(int);
73 void setLevel(int);
74 void setLifes(int);
75
76 void toggleNew();
77 void togglePaused();
78 void forcedHallOfFame(bool);
79
80protected:
81 void timerEvent(QTimerEvent *);
82 void paintEvent(QPaintEvent *);
83 void keyPressEvent(QKeyEvent *);
84
85 void focusOutEvent(QFocusEvent *);
86 void focusInEvent(QFocusEvent *);
87
88 void fillArray(QArray<int> &, QString, int);
89 void fillStrList(QStrList &, QString, int);
90 void fillMapName();
91
92 void confScheme();
93 void confLevels(bool defGroup=TRUE);
94 void confMisc(bool defGroup=TRUE);
95 void confTiming(bool defGroup=TRUE);
96 void confScoring(bool defGroup=TRUE);
97
98private:
99 QBitArray gameState;
100 int timerCount;
101 int maxLevel;
102
103 int scheme;
104 int mode;
105
106 QString pixmapDirectory;
107 QString mapDirectory;
108 QStrList mapName;
109
110 QArray<int> speed;
111 QArray<int> monsterIQ;
112 QArray<int> fruitIQ;
113 QArray<int> fruitIndex;
114 QArray<int> pacmanTicks;
115 QArray<int> remTicks;
116 QArray<int> dangerousTicks;
117 QArray<int> harmlessTicks;
118 QArray<int> harmlessDurTicks;
119 QArray<int> harmlessWarnTicks;
120 QArray<int> arrestTicks;
121 QArray<int> arrestDurTicks;
122 QArray<int> fruitTicks;
123 QArray<int> fruitAppearsTicks;
124 QArray<int> fruitDurTicks;
125 QArray<int> fruitScoreDurTicks;
126
127 int monsterScoreDurMS;
128 int playerDurMS;
129 int readyDurMS;
130 int gameOverDurMS;
131 int afterPauseMS;
132 int dyingPreAnimationMS;
133 int dyingAnimationMS;
134 int dyingPostAnimationMS;
135 int introAnimationMS;
136 int introPostAnimationMS;
137 int levelUpPreAnimationMS;
138 int levelUpAnimationMS;
139 int energizerAnimationMS;
140
141 int pointScore;
142 int energizerScore;
143 QArray<int> fruitScore;
144 QArray<int> monsterScore;
145 QArray<int> extraLifeScore;
146
147 int extraLifeScoreIndex;
148 int nextExtraLifeScore;
149
150 int monstersEaten;
151 int points;
152 int lifes;
153 int level;
154
155 bool focusedPause;
156 bool focusOutPause;
157 bool focusInContinue;
158
159 Board *board;
160 Painter *pix;
161 Pacman *pacman;
162 Fruit *fruit;
163
164 QList<Monster> *monsters;
165 QList<QRect> *monsterRect;
166
167 QList<Energizer> *energizers;
168 QList<QRect> *energizerRect;
169
170 QRect pacmanRect;
171 QRect fruitRect;
172
173 void introMonster(int id);
174 void introPaint(int t);
175
176 void initMonsters();
177 void initPacman();
178 void initFruit(bool fullInitialization=TRUE);
179 void initEnergizers();
180
181 void setOnEnergizers();
182
183 int gameTimer;
184 int energizerTimer;
185 void start(int);
186 void init(bool);
187
188 void score(int);
189
190 uint UpKey;
191 uint DownKey;
192 uint RightKey;
193 uint LeftKey;
194};
195
196#endif // REFEREE_H
diff --git a/noncore/games/kpacman/score.cpp b/noncore/games/kpacman/score.cpp
new file mode 100644
index 0000000..6e660e8
--- a/dev/null
+++ b/noncore/games/kpacman/score.cpp
@@ -0,0 +1,642 @@
1
2#include "portable.h"
3
4#if defined( KDE2_PORT )
5#include <score.h>
6#include <score.moc>
7
8#include <kaccel.h>
9#include <kapp.h>
10#include <kconfig.h>
11#include <kstddirs.h>
12#include <kmessagebox.h>
13#elif defined( QPE_PORT )
14#include <qaccel.h>
15#include "config.h"
16#include "score.h"
17#endif
18
19#include <stdlib.h>
20#include <ctype.h>
21
22#include <qpixmap.h>
23#include <qstring.h>
24#include <qdstream.h>
25#include <qkeycode.h>
26#include <qtimer.h>
27#include <qfileinfo.h>
28
29#include "bitfont.h"
30
31Score::Score(QWidget *parent, const char *name, int Scheme, int Mode, Bitfont *font) : QWidget(parent, name)
32{
33 setFocusPolicy(QWidget::StrongFocus);
34
35 paused = FALSE;
36
37 lastScore = -1;
38 lastPlayer = -1;
39
40 cursorBlinkTimer = 0;
41 cursorBlinkMS = -1;
42 cursor.x = -1;
43 cursor.y = -1;
44 cursor.on = FALSE;
45 cursor.chr = QChar('?');
46
47 initKeys();
48
49 scheme = Scheme;
50 mode = Mode;
51 confScheme();
52
53 bitfont = font;
54
55 highscoreFile.setName(locateHighscoreFilePath().filePath());
56 read();
57
58 for (int p = 0; p < maxPlayer; p++) {
59 playerScore[p] = 0;
60 playerName[p] = getenv("LOGNAME");
61 if (playerName[p].length() < minPlayerNameLength)
62 playerName[p].setExpand(minPlayerNameLength-1, ' ');
63
64 for (uint i = 0; i < playerName[p].length(); i++)
65 if (playerName[p].at(i) < bitfont->firstChar() ||
66 playerName[p].at(i) > bitfont->lastChar())
67 playerName[p].at(i) = playerName[p].at(i).upper();
68 }
69}
70
71Score::~Score()
72{
73 // write();
74}
75
76void Score::paintEvent( QPaintEvent *e)
77{
78 if (rect(1, 0, i18n(" 1UP ")).intersects(e->rect())) {
79 QPixmap pix;
80 QColor fg = BLACK;
81 if (cursor.on || paused || lastPlayer != 0)
82 fg = WHITE;
83 pix = bitfont->text(i18n(" 1UP "), fg, BLACK);
84 bitBlt(this, x(1), y(0), &pix);
85 }
86
87 if (rect(8, 0, i18n(" HIGH SCORE ")).intersects(e->rect())) {
88 QPixmap pix = bitfont->text(i18n(" HIGH SCORE "), WHITE, BLACK);
89 bitBlt(this, x(8), y(0), &pix);
90 }
91
92 if (maxPlayer > 1 && rect(21, 0, i18n(" 2UP ")).intersects(e->rect())) {
93 QPixmap pix;
94 QColor fg = BLACK;
95 if (cursor.on || paused || lastPlayer != 1)
96 fg = WHITE;
97 pix = bitfont->text(i18n(" 2UP "), fg, BLACK);
98 bitBlt(this, x(21), y(0), &pix);
99 }
100
101 QString s;
102
103 s.sprintf("%6d0", playerScore[0]/10);
104 if (rect(0, 1, s).intersects(e->rect())) {
105 QPixmap pix = bitfont->text(s, WHITE, BLACK);
106 bitBlt(this, x(0), y(1), &pix);
107 }
108
109 s.sprintf("%8d0", HighScore/10);
110 if (rect(8, 1, s).intersects(e->rect())) {
111 QPixmap pix = bitfont->text(s, WHITE, BLACK);
112 bitBlt(this, x(8), y(1), &pix);
113 }
114
115 if (lastScore >= 0) {
116 if (rect(1, 4*1.25, i18n(" CONGRATULATIONS ")).intersects(e->rect())) {
117 QPixmap pix = bitfont->text(i18n(" CONGRATULATIONS "), YELLOW, BLACK);
118 bitBlt(this, x(1), y(4*1.25), &pix);
119 }
120 if (rect(1, 6*1.25, i18n(" YOU HAVE ARCHIEVED ")).intersects(e->rect())) {
121 QPixmap pix = bitfont->text(i18n(" YOU HAVE ARCHIEVED "), CYAN, BLACK);
122 bitBlt(this, x(1), y(6*1.25), &pix);
123 }
124 if (rect(1, 7*1.25, i18n(" A SCORE IN THE TOP 10. ")).intersects(e->rect())) {
125 QPixmap pix = bitfont->text(i18n(" A SCORE IN THE TOP 10. "), CYAN, BLACK);
126 bitBlt(this, x(1), y(7*1.25), &pix);
127 }
128 if (rect(1, 8*1.25, i18n(" ")).intersects(e->rect())) {
129 QPixmap pix = bitfont->text(i18n(" "), CYAN, BLACK);
130 bitBlt(this, x(1), y(8*1.25), &pix);
131 }
132 }
133
134 if (rect(1, 9.5*1.25, i18n("RNK SCORE NAME DATE")).intersects(e->rect())) {
135 QPixmap pix = bitfont->text(i18n("RNK SCORE NAME DATE"), WHITE, BLACK);
136 bitBlt(this, x(1), y(9.5*1.25), &pix);
137 }
138
139 for (int i = 0; i < 10; i++) {
140 s.sprintf("%2d%9d %-3.3s %-8.8s",
141 i+1, hallOfFame[i].points, hallOfFame[i].name.utf8().data(),
142 formatDate(hallOfFame[i].moment.date()).data());
143 if (rect(1, (11+i)*1.25, s).intersects(e->rect())) {
144 QPixmap pix = bitfont->text(s, (i == lastScore) ? YELLOW : WHITE, BLACK);
145 bitBlt(this, x(1), y((11+i)*1.25), &pix);
146 }
147 }
148
149 if (cursor.x != -1 && cursor.y != -1 && cursor.on) {
150 if (rect(cursor.x, (cursor.y*1.25), cursor.chr).intersects(e->rect())) {
151 QPixmap pix = bitfont->text(cursor.chr, BLACK, YELLOW);
152 bitBlt(this, x(cursor.x), y(cursor.y*1.25), &pix);
153 }
154 }
155
156 if (paused) {
157
158 QPixmap pix = bitfont->text(i18n("PAUSED"), RED, BLACK);
159 QRect r = bitfont->rect(i18n("PAUSED"));
160 r.moveCenter(QPoint(this->width()/2, this->height()/2));
161
162 bitBlt(this, r.x(), r.y(), &pix);
163 }
164}
165
166void Score::timerEvent(QTimerEvent*)
167{
168 cursor.on = !cursor.on;
169
170 if (paused)
171 return;
172
173 if (cursor.x != -1 && cursor.y != -1)
174 repaint(rect(cursor.x, cursor.y*1.25, cursor.chr), FALSE);
175 scrollRepeat = FALSE;
176
177 if (lastPlayer == 0)
178 repaint(rect(1, 0, i18n(" 1UP ")), FALSE);
179
180 if (lastPlayer == 1)
181 repaint(rect(21, 0, i18n(" 2UP ")), FALSE);
182}
183
184void Score::keyPressEvent(QKeyEvent *k)
185{
186 if (lastScore < 0 || lastPlayer < 0 || lastPlayer >= maxPlayer || paused) {
187 k->ignore();
188 return;
189 }
190
191 int x = cursor.x;
192 int y = cursor.y;
193
194 uint key = k->key();
195
196 if (scrollRepeat && (key == UpKey || key == Key_Up || key == DownKey || key == Key_Down)) {
197 k->ignore();
198 return;
199 }
200
201 if (key != Key_Return) {
202 if (key == RightKey || key == Key_Right)
203 if (++cursor.x > 16)
204 cursor.x = 14;
205 if (key == LeftKey || key == Key_Left)
206 if (--cursor.x < 14)
207 cursor.x = 16;
208 if (key == UpKey || key == Key_Up)
209 if (cursor.chr.unicode() < bitfont->lastChar())
210 cursor.chr = cursor.chr.unicode()+1;
211 else
212 cursor.chr = bitfont->firstChar();
213 if (key == DownKey || key == Key_Down)
214 if (cursor.chr.unicode() > bitfont->firstChar())
215 cursor.chr = cursor.chr.unicode()-1;
216 else
217 cursor.chr = bitfont->lastChar();
218
219 if (cursor.x == x && cursor.y == y &&
220 cursor.chr == hallOfFame[lastScore].name.at(cursor.x-14)) {
221 uint ascii = k->ascii();
222
223 if (ascii < bitfont->firstChar() || ascii > bitfont->lastChar())
224 ascii = toupper(ascii);
225
226 if (ascii >= bitfont->firstChar() && ascii <= bitfont->lastChar()) {
227 cursor.chr = ascii;
228 hallOfFame[lastScore].name.at(cursor.x-14) = cursor.chr;
229 if (++cursor.x > 16)
230 cursor.x = 14;
231 }
232 }
233 }
234
235 if (key == Key_Return) {
236 playerName[lastPlayer] = hallOfFame[lastScore].name;
237 write();
238 read();
239 lastScore = -1;
240 cursor.x = -1;
241 cursor.y = -1;
242// killTimers();
243 emit toggleNew();
244 end();
245 }
246
247 if (x != cursor.x || y != cursor.y) {
248 if (cursor.x != -1)
249 cursor.chr = hallOfFame[lastScore].name.at(cursor.x-14);
250 scrollRepeat = FALSE;
251 repaint(rect(x, y*1.25, cursor.chr), FALSE);
252 } else
253 hallOfFame[lastScore].name.at(cursor.x-14) = cursor.chr;
254
255 if (key == UpKey || key == Key_Up || key == DownKey || key == Key_Down)
256 scrollRepeat = TRUE;
257 else
258 repaint(rect(cursor.x, cursor.y*1.25, cursor.chr), FALSE);
259}
260
261void Score::initKeys()
262{
263 APP_CONFIG_BEGIN( cfg );
264 QString up("Up");
265 up = cfg->readEntry("upKey", (const char*) up);
266 UpKey = KAccel::stringToKey(up);
267
268 QString down("Down");
269 down = cfg->readEntry("downKey", (const char*) down);
270 DownKey = KAccel::stringToKey(down);
271
272 QString left("Left");
273 left = cfg->readEntry("leftKey", (const char*) left);
274 LeftKey = KAccel::stringToKey(left);
275
276 QString right("Right");
277 right = cfg->readEntry("rightKey", (const char*) right);
278 RightKey = KAccel::stringToKey(right);
279 APP_CONFIG_END( cfg );
280}
281
282void Score::confTiming(bool defGroup)
283{
284 APP_CONFIG_BEGIN( cfg );
285 if (defGroup || cfg->hasKey("CursorBlinkMS"))
286 cursorBlinkMS = cfg->readNumEntry("CursorBlinkMS", 250);
287 if (defGroup || cfg->hasKey("HallOfFameMS"))
288 hallOfFameMS = cfg->readNumEntry("HallOfFameMS", 7000);
289 if (defGroup || cfg->hasKey("AfterPauseMS"))
290 afterPauseMS = cfg->readNumEntry("AfterPauseMS", 1000);
291 APP_CONFIG_END( cfg );
292}
293
294void Score::confScheme()
295{
296 APP_CONFIG_BEGIN( cfg );
297 SAVE_CONFIG_GROUP( cfg, oldgroup );
298 QString newgroup;
299
300 // if not set, read mode and scheme from the configfile
301 if (mode == -1 && scheme == -1) {
302 scheme = cfg->readNumEntry("Scheme", -1);
303 mode = cfg->readNumEntry("Mode", -1);
304
305 // if mode is not set in the defGroup-group, lookup the scheme group
306 if (scheme != -1 || mode == -1) {
307 newgroup.sprintf("Scheme %d", scheme);
308 cfg->setGroup(newgroup);
309
310 mode = cfg->readNumEntry("Mode", -1);
311 RESTORE_CONFIG_GROUP( cfg, oldgroup );
312 }
313 }
314
315 int oldCursorBlinkMS = cursorBlinkMS;
316
317 confTiming();
318
319 if (mode != -1) {
320 newgroup.sprintf("Mode %d", mode);
321 cfg->setGroup(newgroup);
322
323 confTiming(FALSE);
324 }
325
326 if (scheme != -1) {
327 newgroup.sprintf("Scheme %d", scheme);
328 cfg->setGroup(newgroup);
329
330 confTiming(FALSE);
331 }
332
333 if (cursorBlinkMS != oldCursorBlinkMS) {
334 if (cursorBlinkTimer)
335 killTimer(cursorBlinkTimer);
336 cursorBlinkTimer = startTimer(cursorBlinkMS);
337 }
338
339 RESTORE_CONFIG_GROUP( cfg, oldgroup );
340 APP_CONFIG_END( cfg );
341}
342
343void Score::setScheme(int Scheme, int Mode, Bitfont *font)
344{
345 mode = Mode;
346 scheme = Scheme;
347
348 confScheme();
349
350 bitfont = font;
351
352 for (int p = 0; p < maxPlayer; p++)
353 for (uint i = 0; i < playerName[p].length(); i++)
354 if (playerName[p].at(i) < bitfont->firstChar() ||
355 playerName[p].at(i) > bitfont->lastChar())
356 playerName[p].at(i) = playerName[p].at(i).upper();
357
358 for (int i = 0; i < 10; i++)
359 for (uint j = 0; j < hallOfFame[i].name.length(); j++)
360 if (hallOfFame[i].name.at(j) < bitfont->firstChar() ||
361 hallOfFame[i].name.at(j) > bitfont->lastChar())
362 hallOfFame[i].name.at(j) = hallOfFame[i].name.at(j).upper();
363
364 if (cursor.chr.unicode() < bitfont->firstChar() ||
365 cursor.chr.unicode() > bitfont->lastChar())
366 cursor.chr = cursor.chr.upper();
367}
368
369void Score::set(int score)
370{
371 set(score, 0);
372}
373
374void Score::set(int score, int player)
375{
376 if (player < 0 || player >= maxPlayer)
377 return;
378
379 lastPlayer = player;
380 playerScore[lastPlayer] = score;
381
382 QString s;
383
384 s.sprintf("%6d0", playerScore[lastPlayer]/10);
385 repaint(rect(0, 1, s), FALSE);
386
387 if (score > HighScore) {
388 HighScore = score;
389 s.sprintf("%8d0", HighScore/10);
390 repaint(rect(8, 1, s), FALSE);
391 }
392}
393
394/*
395 * Set the score for player after the game if over. If the score is in the
396 * high scores then the hall of fame is updated (shifted) and the scoreboard
397 * is shown.
398 */
399
400void Score::setScore(int level, int player)
401{
402 lastScore = -1;
403
404 if (player < 0 || player >= maxPlayer || level == 0) {
405 if (level != 0)
406 emit toggleNew();
407 QTimer::singleShot(hallOfFameMS, this, SLOT(end()));
408 return;
409 }
410
411 lastPlayer = player;
412
413 for (int i = 0; i < 10; i++)
414 if ( playerScore[lastPlayer] > hallOfFame[i].points) {
415 lastScore = i;
416 break;
417 }
418
419 if (lastScore < 0) {
420 emit toggleNew();
421 QTimer::singleShot(hallOfFameMS, this, SLOT(end()));
422 return;
423 }
424
425 for (int i = 9; i > lastScore && i > 0; i--)
426 hallOfFame[i] = hallOfFame[i-1];
427
428 hallOfFame[lastScore].points = playerScore[lastPlayer];
429 hallOfFame[lastScore].levels = level;
430 hallOfFame[lastScore].moment = QDateTime::currentDateTime();
431 hallOfFame[lastScore].name = playerName[lastPlayer];
432
433 cursor.x = 14;
434 cursor.y = 11+lastScore;
435 cursor.chr = hallOfFame[lastScore].name.at(cursor.x-14);
436
437// startTimer(cursorBlinkMS);
438 setFocus();
439}
440
441/*
442 * Read the highscores, if no file or a file shorter than 4 bytes (versions before 0.2.4 stores only
443 * the points of one highscore) exists - the highscores were initialized with default values.
444 */
445void Score::read()
446{
447 if (highscoreFile.exists() && highscoreFile.size() > 4) {
448 if (highscoreFile.open(IO_ReadOnly)) {
449 QDataStream s(&highscoreFile);
450 char *name;
451 for (int i = 0; i < 10; i++) {
452 s >> hallOfFame[i].points >> hallOfFame[i].levels >> hallOfFame[i].duration >>
453 hallOfFame[i].moment >> name;
454 hallOfFame[i].name = QString::fromLatin1(name);
455 delete(name);
456 }
457 highscoreFile.close();
458 }
459 } else {
460 for (int i = 0; i < 10; i++) {
461 hallOfFame[i].points = 5000;
462 hallOfFame[i].levels = 0;
463 hallOfFame[i].duration = QTime();
464 hallOfFame[i].moment = QDateTime();
465 hallOfFame[i].name = "???";
466 }
467 // write();
468 }
469
470 for (int i = 0; i < 10; i++)
471 for (uint j = 0; j < hallOfFame[i].name.length(); j++)
472 if (hallOfFame[i].name.at(j) < bitfont->firstChar() ||
473 hallOfFame[i].name.at(j) > bitfont->lastChar())
474 hallOfFame[i].name.at(j) = hallOfFame[i].name.at(j).upper();
475
476 HighScore = hallOfFame[0].points;
477}
478
479void Score::write()
480{
481#ifndef QWS
482 if (!highscoreFile.exists() && highscoreFile.name() == systemHighscoreFileInfo.filePath())
483 KMessageBox::information(0,
484 i18n("You're going to create the highscore-file\n"
485 "'%1'\n"
486 "for your maschine, that should be used systemwide.\n"
487 "\n"
488 "To grant access to the other users, set the appropriate rights (a+w)\n"
489 "on that file or ask your systemadministator for that favor.\n"
490 "\n"
491 "To use a different directory or filename for the highscores,"
492 "specify them in the configfile (kpacmanrc:highscoreFilePath)."
493 ).arg(systemHighscoreFileInfo.filePath()));
494
495 if (highscoreFile.name() == privateHighscoreFileInfo.filePath())
496 KMessageBox::information(0,
497 i18n("You're using a private highscore-file, that's mostly because of\n"
498 "missing write-access to the systemwide file\n"
499 "'%1' .\n"
500 "\n"
501 "Ask your systemadministrator for granting you access to that file,\n"
502 "by setting the appropriate rights (a+w) on it.\n"
503 "\n"
504 "To use a different directory or filename for the highscores,"
505 "specify them in the configfile (kpacmanrc:highscoreFilePath)."
506 ).arg(systemHighscoreFileInfo.filePath()),
507 QString::null, "PrivateHighscore");
508#endif
509 if (highscoreFile.open(IO_WriteOnly)) {
510 QDataStream s(&highscoreFile);
511 for (int i = 0; i < 10; i++)
512 s << hallOfFame[i].points << hallOfFame[i].levels << hallOfFame[i].duration <<
513 hallOfFame[i].moment << hallOfFame[i].name.latin1();
514 highscoreFile.close();
515 }
516}
517
518void Score::setPause(bool Paused)
519{
520 paused = Paused;
521
522 QRect r = bitfont->rect(i18n("PAUSED"));
523 r.moveCenter(QPoint(this->width()/2, this->height()/2));
524 repaint(r, TRUE);
525
526 // repaint 1UP or 2UP
527 repaint(FALSE);
528}
529
530void Score::end()
531{
532 if (paused) {
533 QTimer::singleShot(afterPauseMS, this, SLOT(end()));
534 return;
535 }
536
537 // repaint 1UP or 2UP
538 lastPlayer = -1;
539 repaint(FALSE);
540
541 emit forcedHallOfFame(FALSE);
542}
543
544/*
545 * Return the date in a formatted QString. The format can be changed using internationalization
546 * of the string "YY/MM/DD". Invalid QDate's where returned as "00/00/00".
547 */
548QString Score::formatDate(QDate date)
549{
550 QString s = i18n("@YY@/@MM@/@DD@");
551
552 QString dd;
553 dd.sprintf("%02d", date.isValid() ? date.year() % 100 : 0);
554 s.replace(QRegExp("@YY@"), dd);
555 dd.sprintf("%02d", date.isValid() ? date.month() : 0);
556 s.replace(QRegExp("@MM@"), dd);
557 dd.sprintf("%02d", date.isValid() ? date.day() : 0);
558 s.replace(QRegExp("@DD@"), dd);
559
560 return s;
561}
562
563QRect Score::rect(int col, float row, QString str, int align)
564{
565 QRect r = bitfont->rect(str);
566 r.moveBy(x(col), y(row));
567
568 int dx = 0;
569 int dy = 0;
570
571 if (align & AlignLeft || align & AlignRight) {
572 dx = (str.length()-1) * (bitfont->width()/2);
573 if (align & AlignRight)
574 dx *= -1;
575 }
576
577 if (align & AlignTop || align & AlignBottom) {
578 dy = bitfont->height()/2;
579 if (align & AlignBottom)
580 dy *= -1;
581 }
582
583 if (dx != 0 || dy != 0)
584 r.moveBy(dx, dy);
585
586 return r;
587}
588
589int Score::x(int col)
590{
591 return col*bitfont->width();
592}
593
594int Score::y(float row)
595{
596 return (int) (row*(bitfont->height()+bitfont->height()/4));
597}
598
599/**
600 * Ermittelt die zu benutzende "highscore"-Datei, in die auch geschrieben werden kann.
601 * Über den "highscoreFilePath"-KConfig-Eintrag, kann abweichend von der Standardlokation
602 * der Standort der "highscore"-Datei spezifiziert werden.
603 * Wenn die systemweite "highscore"-Datei nicht beschrieben werden kann, wird mit einer
604 * privaten Datei gearbeitet.
605 */
606QFileInfo Score::locateHighscoreFilePath()
607{
608#ifndef QWS
609 QFileInfo systemHighscoreDirPath;
610 QStringList systemHighscoreDirs;
611
612 // Schreibfähige "private" highscore-Datei ermitteln für den fallback.
613 privateHighscoreFileInfo.setFile(KGlobal::dirs()->saveLocation("appdata")+highscoreName);
614
615 // FilePath aus der Konfigurationsdatei benutzen
616 systemHighscoreFileInfo.setFile(cfg->readEntry("HighscoreFilePath"));
617
618 // Kein Wert aus der Konfiguration erhalten, dann die "system"-Datei suchen.
619 if (systemHighscoreFileInfo.filePath().isEmpty())
620 systemHighscoreDirs = KGlobal::dirs()->resourceDirs("appdata");
621 else
622 systemHighscoreDirs = QStringList(systemHighscoreFileInfo.filePath());
623
624 for (QStringList::Iterator i = systemHighscoreDirs.begin(); i != systemHighscoreDirs.end(); ++i) {
625
626 systemHighscoreFileInfo.setFile(*i);
627 if (systemHighscoreFileInfo.fileName().isEmpty())
628 systemHighscoreFileInfo.setFile(systemHighscoreFileInfo.dirPath()+"/"+highscoreName);
629
630 // privateHighscoreFileInfo für die "system" Suche ignorieren
631 if (systemHighscoreFileInfo.filePath() != privateHighscoreFileInfo.filePath())
632 if (!systemHighscoreFileInfo.exists()) {
633 systemHighscoreDirPath.setFile(systemHighscoreFileInfo.dirPath());
634 if (systemHighscoreDirPath.exists() && systemHighscoreDirPath.isWritable())
635 return systemHighscoreFileInfo;
636 } else
637 if (systemHighscoreFileInfo.isWritable())
638 return systemHighscoreFileInfo;
639 }
640#endif
641 return privateHighscoreFileInfo;
642}
diff --git a/noncore/games/kpacman/score.h b/noncore/games/kpacman/score.h
new file mode 100644
index 0000000..87f24b9
--- a/dev/null
+++ b/noncore/games/kpacman/score.h
@@ -0,0 +1,129 @@
1#ifndef SCORE_H
2#define SCORE_H
3
4#ifdef HAVE_CONFIG_H
5#include <config.h>
6#endif
7
8#include "portable.h"
9
10#if defined( KDE2_PORT )
11#include <kapp.h>
12#endif
13
14#include <qwidget.h>
15#include <qstring.h>
16#include <qpoint.h>
17#include <qrect.h>
18#include <qfile.h>
19
20#include <qfileinfo.h>
21#include <qdatetime.h>
22
23#include "painter.h"
24#include "bitfont.h"
25
26#define maxPlayer 1
27#define minPlayerNameLength 3
28#define highscoreName "highscore"
29
30class Score : public QWidget
31{
32 Q_OBJECT
33public:
34 Score (QWidget *parent=0, const char *name=0, int scheme=-1, int mode=-1, Bitfont *font=0);
35 ~Score();
36
37public slots:
38 void setScheme(int scheme, int mode, Bitfont *font=0);
39
40 void set(int score);
41 void set(int score, int player);
42 void setScore(int level, int player);
43 void setPause(bool paused);
44
45 void initKeys();
46
47private slots:
48 void read();
49 void write();
50 void end();
51
52signals:
53 void toggleNew();
54 void forcedHallOfFame(bool);
55
56protected:
57 void timerEvent(QTimerEvent *);
58 void paintEvent(QPaintEvent *);
59 void keyPressEvent(QKeyEvent *);
60
61 void focusInEvent(QFocusEvent *) { ; }
62 void focusOutEvent(QFocusEvent *) { ; }
63
64 void confScheme();
65 void confTiming(bool defGroup=TRUE);
66
67private:
68 Bitfont *bitfont;
69
70 QRect rect(int col, float row, QString str, int align = AlignCenter);
71 int x(int col);
72 int y(float row);
73
74 QString formatDate(QDate date);
75
76 /**
77 * Ermittelt die zu benutzende "highscore"-Datei, in die auch geschrieben werden kann.
78 * Über den "highscoreFilePath"-KConfig-Eintrag, kann abweichend von der Standardlokation
79 * der Standort der "highscore"-Datei spezifiziert werden.
80 * Wenn die systemweite "globale" Datei nicht beschrieben werden kann, wird mit einer
81 * privaten Datei gearbeitet.
82 */
83 QFileInfo locateHighscoreFilePath();
84
85 int cursorBlinkMS;
86 int hallOfFameMS;
87 int afterPauseMS;
88
89 bool paused;
90
91 uint UpKey;
92 uint DownKey;
93 uint RightKey;
94 uint LeftKey;
95
96 int lastScore;
97 int lastPlayer;
98 int HighScore;
99 int playerScore[maxPlayer];
100 QString playerName[maxPlayer];
101
102 struct {
103 int x;
104 int y;
105 QChar chr;
106 bool on;
107 } cursor;
108
109 int cursorBlinkTimer;
110 bool scrollRepeat;
111
112 struct {
113 int points;
114 int levels;
115 QTime duration;
116 QDateTime moment;
117 QString name;
118 } hallOfFame[10];
119
120 QFileInfo systemHighscoreFileInfo;
121 QFileInfo privateHighscoreFileInfo;
122
123 QFile highscoreFile;
124
125 int scheme;
126 int mode;
127};
128
129#endif // SCORE_H
diff --git a/noncore/games/kpacman/status.cpp b/noncore/games/kpacman/status.cpp
new file mode 100644
index 0000000..00d1f22
--- a/dev/null
+++ b/noncore/games/kpacman/status.cpp
@@ -0,0 +1,367 @@
1
2#include "portable.h"
3
4#if defined( KDE2_PORT )
5#include <kapp.h>
6#include <klocale.h>
7#include <kstddirs.h>
8#include <status.h>
9#include <status.moc>
10#elif defined( QPE_PORT )
11#include <qpe/qpeapplication.h>
12#include "config.h"
13#include "status.h"
14#endif
15
16#include <qpixmap.h>
17#include <qbitmap.h>
18#include <qstring.h>
19#include <qmsgbox.h>
20#include <qfileinfo.h>
21
22Status::Status( QWidget *parent, const char *name, int Scheme, int Mode ) :
23 QWidget( parent, name )
24{
25 actualLifes = 0;
26 actualLevel = 0;
27
28 lifesPix = NULL;
29 levelPix = NULL;
30
31 scheme = Scheme;
32 mode = Mode;
33 level = 0;
34
35 confScheme();
36}
37
38QList<QPixmap> *Status::loadPixmap(QWidget *parent, QString pixmapName,
39 QList<QPixmap> *pixmaps)
40{
41 if (pixmaps == NULL) {
42 pixmaps = new QList<QPixmap>;
43 pixmaps->setAutoDelete(TRUE);
44 }
45
46 if (!pixmaps->isEmpty())
47 pixmaps->clear();
48
49 QPixmap PIXMAP(pixmapName);
50 if (PIXMAP.isNull() || PIXMAP.mask() == NULL) {
51 QString msg = i18n("The pixmap could not be contructed.\n\n"
52 "The file '@PIXMAPNAME@' does not exist,\n"
53 "or is of an unknown format.");
54 msg.replace(QRegExp("@PIXMAPNAME@"), pixmapName);
55 QMessageBox::information(parent, i18n("Initialization Error"),
56 (const char *) msg);
57 return 0;
58 }
59
60 int height = PIXMAP.height();
61 int width = (height == 0) ? 0 : PIXMAP.width()/(PIXMAP.width()/height);
62
63 QBitmap BITMAP;
64 QBitmap MASK;
65
66 BITMAP = *PIXMAP.mask();
67 MASK.resize(width, height);
68
69 for (int x = 0; x < PIXMAP.width()/width; x++) {
70 QPixmap *pixmap = new QPixmap(width, height);
71 pixmaps->append(pixmap);
72 bitBlt(pixmap, 0, 0, &PIXMAP, x*width, 0, width, height, CopyROP, TRUE);
73 bitBlt(&MASK, 0, 0, &BITMAP, x*width, 0, width, height, CopyROP, TRUE);
74 pixmap->setMask(MASK);
75 }
76
77 return pixmaps;
78}
79
80void Status::paintEvent( QPaintEvent *)
81{
82 for (int x = 0; x < actualLifes && !lifesPix->isEmpty(); x++)
83 bitBlt(this, lifesPix->at(0)->width()+(lifesPix->at(0)->width()*x),
84 (height()-lifesPix->at(0)->height())/2,
85 lifesPix->at(0), 0, 0,
86 lifesPix->at(0)->width(), lifesPix->at(0)->height());
87
88 for (int x = 0; x < actualLevel && !levelPix->isEmpty(); x++) {
89 erase((width()-levelPix->at(x)->width()*2)-(levelPix->at(x)->width()*levelPos[x]),
90 (height()-levelPix->at(x)->height())/2,
91 levelPix->at(x)->width(), levelPix->at(x)->height());
92 bitBlt(this, (width()-levelPix->at(x)->width()*2)-(levelPix->at(x)->width()*levelPos[x]),
93 (height()-levelPix->at(x)->height())/2,
94 levelPix->at(x), 0, 0,
95 levelPix->at(x)->width(), levelPix->at(x)->height());
96 }
97}
98
99void Status::initPixmaps()
100{
101 if (lastLifesPixmapName != lifesPixmapName.at(level)) {
102 lifesPix = loadPixmap(this, lifesPixmapName.at(level), lifesPix);
103 lastLifesPixmapName = lifesPixmapName.at(level);
104 }
105 if (lastLevelPixmapName != levelPixmapName.at(level)) {
106 levelPix = loadPixmap(this, levelPixmapName.at(level), levelPix);
107 lastLevelPixmapName = levelPixmapName.at(level);
108 }
109}
110
111QString Status::decodeHexOctString(QString s)
112{
113 QString value;
114 QString valids;
115 int pos, xpos = 0, opos = 0;
116 int v, len, leadin;
117 const char *ptr;
118 uchar c;
119
120 while (((xpos = s.find(QRegExp("\\\\x[0-9a-fA-F]+"), xpos)) != -1) ||
121 ((opos = s.find(QRegExp("\\\\[0-7]+"), opos)) != -1)) {
122 if (xpos != -1) {
123 valids = "0123456789abcdef";
124 leadin = 2;
125 pos = xpos;
126 } else {
127 valids = "01234567";
128 leadin = 1;
129 pos = opos;
130 }
131
132 c = '\0';
133 len = 0;
134 value = s.mid(pos+leadin, 3);
135 ptr = (const char *) value;
136
137 while (*ptr != '\0' && (v = valids.find(*ptr++, 0, FALSE)) != -1) {
138 c = (c * valids.length()) + v;
139 len++;
140 }
141
142 value.fill(c, 1);
143 s.replace(pos, len+leadin, value);
144 }
145
146 return s;
147}
148
149void Status::fillArray(QArray<int> &array, QString values, int max)
150{
151 array.resize(max);
152 int last = 0;
153 bool ok;
154 QString value;
155
156 for (uint i = 0; i < array.size(); i++) {
157 if (values.find(',') < 0 && values.length() > 0) {
158 value = values;
159 values = "";
160 }
161 if (values.find(',') >= 0) {
162 value = values.left(values.find(','));
163 values.remove(0,values.find(',')+1);
164 }
165 array[i] = value.toInt(&ok);
166 if (ok)
167 last = array[i];
168 else
169 array[i] = last;
170 }
171}
172
173void Status::fillStrList(QStrList &list, QString values, int max)
174{
175 if (!list.isEmpty())
176 list.clear();
177
178 QString last = "";
179 QString value;
180
181 for (uint i = 0; i < (uint) max; i++) {
182 if (values.find(',') < 0 && values.length() > 0) {
183 value = values;
184 values = "";
185 }
186 if (values.find(',') >= 0) {
187 value = values.left(values.find(','));
188 values.remove(0,values.find(',')+1);
189 }
190 if (!value.isEmpty())
191 last = decodeHexOctString(value);
192 list.append(last);
193 }
194}
195
196void Status::fillPixmapName(QStrList &pixmapName)
197{
198 QStrList list = pixmapName;
199
200 if (!pixmapName.isEmpty())
201 pixmapName.clear();
202
203 QString pixmap;
204
205 QFileInfo fileInfo;
206
207 for (uint i = 0; i < list.count(); i++) {
208 pixmap = list.at(i);
209
210 if (pixmap.left(1) != "/" && pixmap.left(1) != "~")
211 pixmap = FIND_APP_DATA( pixmapDirectory+pixmap );
212
213 fileInfo.setFile(pixmap);
214 if (!fileInfo.isReadable() || !fileInfo.isFile())
215 pixmap = "";
216
217 pixmapName.append(pixmap);
218 }
219}
220
221void Status::confLevels(bool defGroup)
222{
223 APP_CONFIG_BEGIN( cfg );
224 if (defGroup || cfg->hasKey("Levels"))
225 maxLevel = cfg->readNumEntry("Levels", 13);
226 APP_CONFIG_END( cfg );
227}
228
229void Status::confMisc(bool defGroup)
230{
231 APP_CONFIG_BEGIN( cfg );
232 if (defGroup || cfg->hasKey("LevelPosition"))
233 fillArray(levelPos, cfg->readEntry("LevelPosition", "0,1,2,3,,4,,5,,6,,7"), maxLevel);
234
235 if (defGroup || cfg->hasKey("PixmapDirectory")) {
236 pixmapDirectory = cfg->readEntry("PixmapDirectory");
237
238 if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~")
239 pixmapDirectory.insert(0, "pics/");
240 if (pixmapDirectory.right(1) != "/")
241 pixmapDirectory.append("/");
242 }
243
244 if (defGroup || cfg->hasKey("LifesPixmapName"))
245 fillStrList(lifesPixmapName,
246 cfg->readEntry("LifesPixmapName", "lifes.xpm"), maxLevel+1);
247 if (defGroup || cfg->hasKey("LevelPixmapName"))
248 fillStrList(levelPixmapName,
249 cfg->readEntry("LevelPixmapName", "level.xpm"), maxLevel+1);
250 APP_CONFIG_END( cfg );
251}
252
253void Status::confScheme()
254{
255 APP_CONFIG_BEGIN( cfg );
256 SAVE_CONFIG_GROUP( cfg, oldgroup );
257 QString newgroup;
258
259 // if not set, read mode and scheme from the configfile
260 if (mode == -1 && scheme == -1) {
261 scheme = cfg->readNumEntry("Scheme", -1);
262 mode = cfg->readNumEntry("Mode", -1);
263
264 // if mode is not set in the defGroup-group, lookup the scheme group
265 if (scheme != -1 || mode == -1) {
266 newgroup.sprintf("Scheme %d", scheme);
267 cfg->setGroup(newgroup);
268
269 mode = cfg->readNumEntry("Mode", -1);
270 RESTORE_CONFIG_GROUP( cfg, oldgroup );
271 }
272 }
273
274 confLevels();
275
276 if (mode != -1) {
277 newgroup.sprintf("Mode %d", mode);
278 cfg->setGroup(newgroup);
279
280 confLevels(FALSE);
281 }
282
283 if (scheme != -1) {
284 newgroup.sprintf("Scheme %d", scheme);
285 cfg->setGroup(newgroup);
286
287 confLevels(FALSE);
288 }
289
290 RESTORE_CONFIG_GROUP( cfg, oldgroup );
291
292 confMisc();
293
294 if (mode != -1) {
295 newgroup.sprintf("Mode %d", mode);
296 cfg->setGroup(newgroup);
297
298 confMisc(FALSE);
299 }
300
301 if (scheme != -1) {
302 newgroup.sprintf("Scheme %d", scheme);
303 cfg->setGroup(newgroup);
304
305 confMisc(FALSE);
306 }
307
308 fillPixmapName(lifesPixmapName);
309 fillPixmapName(levelPixmapName);
310
311 initPixmaps();
312
313 setFixedHeight(minHeight());
314
315 RESTORE_CONFIG_GROUP( cfg, oldgroup );
316 APP_CONFIG_END( cfg );
317}
318
319void Status::setScheme(int Scheme, int Mode)
320{
321 mode = Mode;
322 scheme = Scheme;
323
324 confScheme();
325
326 repaint();
327}
328
329int Status::minHeight()
330{
331 if (lifesPix->isEmpty() && levelPix->isEmpty())
332 return 0;
333 if (levelPix->isEmpty())
334 return lifesPix->at(0)->height();
335 if (lifesPix->isEmpty())
336 return levelPix->at(0)->height();
337 return (lifesPix->at(0)->height() > levelPix->at(0)->height()) ?
338 lifesPix->at(0)->height() : levelPix->at(0)->height();
339}
340
341int Status::minWidth()
342{
343 if (lifesPix->isEmpty() && levelPix->isEmpty())
344 return 0;
345 if (levelPix->isEmpty())
346 return lifesPix->at(0)->width();
347 if (lifesPix->isEmpty())
348 return levelPix->at(0)->width();
349 return (lifesPix->at(0)->width() > levelPix->at(0)->width()) ?
350 lifesPix->at(0)->width() : levelPix->at(0)->width();
351}
352
353void Status::setLifes(int lifes)
354{
355 actualLifes = lifes;
356 repaint();
357}
358
359void Status::setLevel(int Level)
360{
361 level = Level;
362
363 initPixmaps();
364
365 actualLevel = (level > (int) levelPix->count()) ? (int) levelPix->count() : level;
366 repaint();
367}
diff --git a/noncore/games/kpacman/status.h b/noncore/games/kpacman/status.h
new file mode 100644
index 0000000..4f69b02
--- a/dev/null
+++ b/noncore/games/kpacman/status.h
@@ -0,0 +1,78 @@
1#ifndef STATUS_H
2#define STATUS_H
3
4#ifdef HAVE_CONFIG_H
5#include <config.h>
6#endif
7
8#include "portable.h"
9
10#if defined( KDE2_PORT )
11#include <kapp.h>
12#include <kconfig.h>
13#endif
14
15#include <qwidget.h>
16#include <qpixmap.h>
17#include <qstring.h>
18#include <qarray.h>
19#include <qlist.h>
20#include <qstrlist.h>
21#include <qregexp.h>
22
23class Status : public QWidget
24{
25 Q_OBJECT
26public:
27 Status(QWidget *parent=0, const char *name=0, int scheme=-1, int mode=-1);
28 ~Status() {};
29
30public slots:
31 void setScheme(int scheme, int mode);
32 void setLevel(int level);
33 void setLifes(int lifes);
34
35protected:
36 void paintEvent(QPaintEvent *);
37 int minHeight();
38 int minWidth();
39
40 QString decodeHexOctString(QString str);
41
42 void fillArray(QArray<int> &, QString, int);
43 void fillStrList(QStrList &, QString, int);
44 void fillPixmapName(QStrList &);
45
46 void confScheme();
47 void confLevels(bool defGroup=TRUE);
48 void confMisc(bool defGroup=TRUE);
49
50 void initPixmaps();
51
52private:
53 QArray<int> levelPos;
54 int actualLifes;
55 int actualLevel;
56
57 QString pixmapDirectory;
58
59 QStrList lifesPixmapName;
60 QStrList levelPixmapName;
61
62 QString lastLifesPixmapName;
63 QString lastLevelPixmapName;
64
65 QList<QPixmap> *loadPixmap(QWidget *parent, QString pixmapName,
66 QList<QPixmap> *pixmaps=0);
67
68 QList<QPixmap> *lifesPix;
69 QList<QPixmap> *levelPix;
70
71 int maxLevel;
72 int level;
73
74 int scheme;
75 int mode;
76};
77
78#endif // STATUS_H