00001
00002 #include "portable.h"
00003
00004 #if defined( KDE2_PORT )
00005 #include <kapp.h>
00006 #include <kconfig.h>
00007 #include <kstddirs.h>
00008 #elif defined( QPE_PORT )
00009 #include <qpe/qpeapplication.h>
00010 #include <qpe/config.h>
00011 #endif
00012
00013
00014 #include <qfileinfo.h>
00015
00016 #include "painter.h"
00017
00018 Painter::Painter( Board *b, QWidget *parent, int Scheme, int Mode, Bitfont *font)
00019 {
00020 w = parent;
00021 board = b;
00022
00023 pointPix = NULL;
00024 wallPix = NULL;
00025 prisonPix = NULL;
00026 energizerPix = NULL;
00027 fruitPix = NULL;
00028 pacmanPix = NULL;
00029 dyingPix = NULL;
00030 eyesPix = NULL;
00031 monsterPix = NULL;
00032 fruitScorePix = NULL;
00033 monsterScorePix = NULL;
00034
00035 lastPointPixmapName = "";
00036 lastWallPixmapName = "";
00037 lastPrisonPixmapName = "";
00038 lastEnergizerPixmapName = "";
00039 lastFruitPixmapName = "";
00040 lastPacmanPixmapName = "";
00041 lastDyingPixmapName = "";
00042 lastEyesPixmapName = "";
00043 lastMonsterPixmapName = "";
00044 lastFruitScorePixmapName = "";
00045 lastMonsterScorePixmapName = "";
00046
00047 bitfont = font;
00048
00049 scheme = Scheme;
00050 mode = Mode;
00051 level = 0;
00052
00053 confScheme();
00054 }
00055
00056 QList<QPixmap> *Painter::loadPixmap(QWidget*, QString pixmapName,
00057 QList<QPixmap> *pixmaps)
00058 {
00059 if (pixmaps == NULL) {
00060 pixmaps = new QList<QPixmap>;
00061 pixmaps->setAutoDelete(TRUE);
00062 }
00063
00064 if (!pixmaps->isEmpty())
00065 pixmaps->clear();
00066
00067 QPixmap PIXMAP(pixmapName);
00068 if (PIXMAP.isNull() || PIXMAP.mask() == NULL) {
00069 QString msg = "The pixmap could not be contructed.\n\n"
00070 "The file '@PIXMAPNAME@' does not exist,\n"
00071 "or is of an unknown format.";
00072 msg.replace(QRegExp("@PIXMAPNAME@"), pixmapName);
00073
00074 printf("%s\n", msg.data());
00075 return 0;
00076 }
00077
00078 int height = PIXMAP.height();
00079 int width = (height == 0) ? 0 : PIXMAP.width()/(PIXMAP.width()/height);
00080
00081 QBitmap BITMAP;
00082 QBitmap MASK;
00083
00084 BITMAP = *PIXMAP.mask();
00085 MASK.resize(width, height);
00086
00087 for (int x = 0; x < PIXMAP.width()/width; x++) {
00088 QPixmap *pixmap = new QPixmap(width, height);
00089 pixmaps->append(pixmap);
00090 bitBlt(pixmap, 0, 0, &PIXMAP, x*width, 0, width, height, QPixmap::CopyROP, TRUE);
00091 bitBlt(&MASK, 0, 0, &BITMAP, x*width, 0, width, height, QPixmap::CopyROP, TRUE);
00092 pixmap->setMask(MASK);
00093 }
00094
00095 return pixmaps;
00096 }
00097
00098 QList<QPixmap> *Painter::textPixmap(QStrList &str, QList<QPixmap> *pixmaps,
00099 QColor fg, QColor bg)
00100 {
00101 if (pixmaps == NULL) {
00102 pixmaps = new QList<QPixmap>;
00103 pixmaps->setAutoDelete(TRUE);
00104 }
00105
00106 if (!pixmaps->isEmpty())
00107 pixmaps->clear();
00108
00109 for (uint s = 0; s < str.count(); s++) {
00110 QPixmap *pixmap = new QPixmap(bitfont->text(str.at(s), fg, bg));
00111 pixmaps->append(pixmap);
00112 }
00113
00114 return pixmaps;
00115 }
00116
00117 QList<QPixmap> *Painter::textPixmap(QString str, QList<QPixmap> *pixmaps,
00118 QColor fg, QColor bg)
00119 {
00120 if (pixmaps == NULL) {
00121 pixmaps = new QList<QPixmap>;
00122 pixmaps->setAutoDelete(TRUE);
00123 }
00124
00125 if (!pixmaps->isEmpty())
00126 pixmaps->clear();
00127
00128 QPixmap *pixmap = new QPixmap(bitfont->text(str, fg, bg));
00129 pixmaps->append(pixmap);
00130
00131 return pixmaps;
00132 }
00133
00134
00135
00136
00137 QPoint Painter::point(int pos)
00138 {
00139 return QPoint((board->x(pos)-1)*BlockWidth, (board->y(pos)-1)*BlockHeight);
00140 }
00141
00142
00143 QRect Painter::rect(int pos, PixMap pix, uint i)
00144 {
00145 if (pos == OUT)
00146 return QRect();
00147
00148 QPixmap *PIXMAP = NULL;
00149 switch (pix) {
00150 case PacmanPix : PIXMAP = pacmanPix->
00151 at(checkRange(i, pacmanPix->count()-1));
00152 break;
00153 case DyingPix : PIXMAP = dyingPix->
00154 at(checkRange(i, dyingPix->count()-1));
00155 break;
00156 case MonsterPix : PIXMAP = monsterPix->
00157 at(checkRange(i, monsterPix->count()-1));
00158 break;
00159 case EyesPix : PIXMAP = eyesPix->
00160 at(checkRange(i, eyesPix->count()-1));
00161 break;
00162 case FruitPix : PIXMAP = fruitPix->
00163 at(checkRange(i, fruitPix->count()-1));
00164 break;
00165 case PointPix : PIXMAP = pointPix->
00166 at(checkRange(i, pointPix->count()-1));
00167 break;
00168 case EnergizerPix : PIXMAP = energizerPix->
00169 at(checkRange(i, energizerPix->count()-1));
00170 break;
00171 case FruitScorePix : PIXMAP = fruitScorePix->
00172 at(checkRange(i, fruitScorePix->count()-1));
00173 break;
00174 case MonsterScorePix : PIXMAP = monsterScorePix->
00175 at(checkRange(i,monsterScorePix->count()-1));
00176 break;
00177 default : PIXMAP = wallPix->
00178 at(checkRange(i, wallPix->count()-1));
00179 }
00180 if (PIXMAP == NULL)
00181 return QRect();
00182
00183 QRect rect = PIXMAP->rect();
00184 QPoint point = this->point(pos);
00185 rect.moveCenter(QPoint(point.x()-1, point.y()-1));
00186
00187 return rect;
00188 }
00189
00190 QRect Painter::rect(int pos, QString str, int align)
00191 {
00192 if (pos == OUT)
00193 return QRect();
00194 QPoint point = this->point(pos);
00195 QRect rect = bitfont->rect(str);
00196
00197 rect.moveCenter(QPoint(point.x()-1, point.y()-1));
00198
00199 int dx = 0;
00200 int dy = 0;
00201
00202 if (align & QLabel::AlignLeft || align & QLabel::AlignRight) {
00203 dx = (str.length()-1) * (bitfont->width()/2);
00204 if (align & QLabel::AlignRight)
00205 dx *= -1;
00206 }
00207
00208 if (align & QLabel::AlignTop || align & QLabel::AlignBottom) {
00209 dy = bitfont->height()/2;
00210 if (align & QLabel::AlignBottom)
00211 dy *= -1;
00212 }
00213
00214 if (dx != 0 || dy != 0)
00215 rect.moveBy(dx, dy);
00216
00217 return rect;
00218 }
00219
00220 QRect Painter::rect(QRect r1, QRect r2)
00221 {
00222 QRect rect;
00223 rect.setLeft(r1.left() < r2.left() ? r1.left() : r2.left());
00224 rect.setTop(r1.top() < r2.top() ? r1.top() : r2.top());
00225 rect.setRight(r1.right() > r2.right() ? r1.right() : r2.right());
00226 rect.setBottom(r1.bottom() > r2.bottom() ? r1.bottom() : r2.bottom());
00227
00228 return rect;
00229 }
00230
00231 void Painter::erase(int pos, PixMap pix, uint i)
00232 {
00233 if (pos == OUT)
00234 return;
00235 QRect rect = this->rect(pos, pix, i);
00236 bitBlt(&roomPix, rect.x(), rect.y(), &backPix,
00237 rect.x(), rect.y(), rect.width(), rect.height());
00238 }
00239
00240 int Painter::maxPixmaps(PixMap pix)
00241 {
00242 switch (pix) {
00243 case WallPix : return (int) wallPix->count();
00244 case PrisonPix : return (int) prisonPix->count();
00245 case PointPix : return (int) pointPix->count();
00246 case EnergizerPix : return (int) energizerPix->count();
00247 case FruitPix : return (int) fruitPix->count();
00248 case PacmanPix : return (int) pacmanPix->count();
00249 case DyingPix : return (int) dyingPix->count();
00250 case EyesPix : return (int) eyesPix->count();
00251 case MonsterPix : return (int) monsterPix->count();
00252 case FruitScorePix : return (int) fruitScorePix->count();
00253 case MonsterScorePix : return (int) monsterScorePix->count();
00254 default : return 0;
00255 }
00256 }
00257
00258 void Painter::draw(QPoint point, DrawWidget where, QPixmap pix)
00259 {
00260 switch (where) {
00261 case Widget : bitBlt(w, point.x(), point.y(), &pix);
00262 break;
00263 case RoomPix : bitBlt(&roomPix, point.x(), point.y(), &pix);
00264 break;
00265 case BackPix : bitBlt(&backPix, point.x(), point.y(), &pix);
00266 break;
00267 }
00268 }
00269
00270 void Painter::draw(QRect rect, DrawWidget where, QPixmap pix)
00271 {
00272 draw(QPoint(rect.x(), rect.y()), where, pix);
00273 }
00274
00275 void Painter::draw(int pos, DrawWidget where, PixMap pix, uint i)
00276 {
00277 QPixmap *PIXMAP = NULL;
00278 switch (pix) {
00279 case PacmanPix : PIXMAP = pacmanPix->
00280 at(checkRange(i, pacmanPix->count()-1));
00281 break;
00282 case DyingPix : PIXMAP = dyingPix->
00283 at(checkRange(i, dyingPix->count()-1));
00284 break;
00285 case MonsterPix : PIXMAP = monsterPix->
00286 at(checkRange(i, monsterPix->count()-1));
00287 break;
00288 case EyesPix : PIXMAP = eyesPix->
00289 at(checkRange(i, eyesPix->count()-1));
00290 break;
00291 case FruitPix : PIXMAP = fruitPix->
00292 at(checkRange(i, fruitPix->count()-1));
00293 break;
00294 case EnergizerPix : PIXMAP = energizerPix->
00295 at(checkRange(i, energizerPix->count()-1));
00296 break;
00297 case FruitScorePix : PIXMAP = fruitScorePix->
00298 at(checkRange(i, fruitScorePix->count()-1));
00299 break;
00300 case MonsterScorePix : PIXMAP = monsterScorePix->
00301 at(checkRange(i,monsterScorePix->count()-1));
00302 break;
00303 default : ;
00304 }
00305
00306 if (PIXMAP == NULL)
00307 return;
00308
00309 QRect rect = PIXMAP->rect();
00310 QPoint point = this->point(pos);
00311 rect.moveCenter(QPoint(point.x()-1, point.y()-1));
00312
00313 switch (where) {
00314 case Widget : bitBlt(w, rect.x(), rect.y(), PIXMAP);
00315 break;
00316 case RoomPix : bitBlt(&roomPix, rect.x(), rect.y(), PIXMAP);
00317 break;
00318 case BackPix : bitBlt(&backPix, rect.x(), rect.y(), PIXMAP);
00319 break;
00320 }
00321 }
00322
00323 QPixmap Painter::draw(int pos, DrawWidget where,
00324 QString str, QColor fg, QColor bg, int align)
00325 {
00326 QPixmap TEXT = bitfont->text(str, fg, bg);
00327
00328 QRect rect = this->rect(pos, str, align);
00329 QPixmap SAVE = QPixmap(rect.width(), rect.height());
00330
00331 switch (where) {
00332 case Widget : bitBlt(&SAVE, 0, 0, w, rect.x(), rect.y());
00333 bitBlt(w, rect.x(), rect.y(), &TEXT);
00334 break;
00335 case RoomPix : bitBlt(&SAVE, 0, 0, &roomPix, rect.x(), rect.y());
00336 bitBlt(&roomPix, rect.x(), rect.y(), &TEXT);
00337 break;
00338 case BackPix : bitBlt(&SAVE, 0, 0, &backPix, rect.x(), rect.y());
00339 bitBlt(&backPix, rect.x(), rect.y(), &TEXT);
00340 break;
00341 }
00342
00343 return SAVE;
00344 }
00345
00346 QRect Painter::draw(int col, int row, DrawWidget where,
00347 QString str, QColor fg, QColor bg, int align)
00348 {
00349 QPixmap TEXT = bitfont->text(str, fg, bg);
00350
00351 QRect rect = this->rect(row*BoardWidth+col, str, align);
00352 draw(rect, where, TEXT);
00353
00354 return rect;
00355 }
00356
00357 void Painter::initPixmaps()
00358 {
00359 if (lastPointPixmapName != pointPixmapName.at(level)) {
00360 pointPix = loadPixmap(w, pointPixmapName.at(level), pointPix);
00361 lastPointPixmapName = pointPixmapName.at(level);
00362 }
00363 if (lastPrisonPixmapName != prisonPixmapName.at(level)) {
00364 prisonPix = loadPixmap(w, prisonPixmapName.at(level), prisonPix);
00365 lastPrisonPixmapName = prisonPixmapName.at(level);
00366 }
00367 if (lastEnergizerPixmapName != energizerPixmapName.at(level)) {
00368 energizerPix = loadPixmap(w, energizerPixmapName.at(level), energizerPix);
00369 lastEnergizerPixmapName = energizerPixmapName.at(level);
00370 }
00371 if (lastFruitPixmapName != fruitPixmapName.at(level)) {
00372 fruitPix = loadPixmap(w, fruitPixmapName.at(level), fruitPix);
00373 lastFruitPixmapName = fruitPixmapName.at(level);
00374 }
00375 if (lastPacmanPixmapName != pacmanPixmapName.at(level)) {
00376 pacmanPix = loadPixmap(w, pacmanPixmapName.at(level), pacmanPix);
00377 lastPacmanPixmapName = pacmanPixmapName.at(level);
00378 }
00379 if (lastDyingPixmapName != dyingPixmapName.at(level)) {
00380 dyingPix = loadPixmap(w, dyingPixmapName.at(level), dyingPix);
00381 lastDyingPixmapName = dyingPixmapName.at(level);
00382 }
00383 if (lastEyesPixmapName != eyesPixmapName.at(level)) {
00384 eyesPix = loadPixmap(w, eyesPixmapName.at(level), eyesPix);
00385 lastEyesPixmapName = eyesPixmapName.at(level);
00386 }
00387 if (lastMonsterPixmapName != monsterPixmapName.at(level)) {
00388 monsterPix = loadPixmap(w, monsterPixmapName.at(level), monsterPix);
00389 lastMonsterPixmapName = monsterPixmapName.at(level);
00390 }
00391
00392 if (lastFruitScorePixmapName != fruitScorePixmapName.at(level) ||
00393 (const char *) *fruitScorePixmapName.at(level) == '\0') {
00394 if ((const char *) *fruitScorePixmapName.at(level) == '\0') {
00395 fruitScorePix = textPixmap(fruitScoreString, fruitScorePix, PINK);
00396 } else {
00397 fruitScorePix = loadPixmap(w, fruitScorePixmapName.at(level),
00398 fruitScorePix);
00399 lastFruitScorePixmapName = fruitScorePixmapName.at(level);
00400 }
00401 }
00402
00403 if (lastMonsterScorePixmapName != monsterScorePixmapName.at(level) ||
00404 (const char *) *monsterScorePixmapName.at(level) == '\0') {
00405 if ((const char *) *monsterScorePixmapName.at(level) == '\0') {
00406 monsterScorePix = textPixmap(monsterScoreString, monsterScorePix, CYAN);
00407 } else {
00408 monsterScorePix = loadPixmap(w, monsterScorePixmapName.at(level),
00409 monsterScorePix);
00410 lastMonsterScorePixmapName = monsterScorePixmapName.at(level);
00411 }
00412 }
00413
00414 if (lastWallPixmapName != wallPixmapName.at(level)) {
00415 wallPix = loadPixmap(w, wallPixmapName.at(level), wallPix);
00416 if (wallPix->isEmpty()) {
00417 BlockWidth = 0;
00418 BlockHeight = 0;
00419 } else {
00420 BlockWidth = wallPix->at(0)->width();
00421 BlockHeight = wallPix->at(0)->height();
00422 }
00423 lastWallPixmapName = wallPixmapName.at(level);
00424 }
00425 }
00426
00427 void Painter::initbackPixmaps()
00428 {
00429 backgroundColor = BLACK;
00430
00431 backPix.resize((BoardWidth-3)*BlockWidth, (BoardHeight-3)*BlockHeight );
00432 backPix.fill(backgroundColor);
00433 }
00434
00435 void Painter::initRoomPixmap()
00436 {
00437 roomPix.resize((BoardWidth-3)*BlockWidth, (BoardHeight-3)*BlockHeight );
00438 bitBlt(&roomPix,0,0, &backPix);
00439
00440 for (unsigned int x = 0; x < board->size(); x++) {
00441 if (board->isBrick(x))
00442 drawBrick(x);
00443 if (board->isPrison(x) || board->isGate(x))
00444 drawPrison(x);
00445 if (board->isPoint(x))
00446 drawPoint(x);
00447 }
00448 }
00449
00450 void Painter::drawBrick(int pos)
00451 {
00452 int border = 0;
00453 if (board->isBrick(board->move(pos, N ))) border |= (1 << 0);
00454 if (board->isBrick(board->move(pos, NE))) border |= (1 << 1);
00455 if (board->isBrick(board->move(pos, E ))) border |= (1 << 2);
00456 if (board->isBrick(board->move(pos, SE))) border |= (1 << 3);
00457 if (board->isBrick(board->move(pos, S ))) border |= (1 << 4);
00458 if (board->isBrick(board->move(pos, SW))) border |= (1 << 5);
00459 if (board->isBrick(board->move(pos, W ))) border |= (1 << 6);
00460 if (board->isBrick(board->move(pos, NW))) border |= (1 << 7);
00461
00462 if (board->isOut(board->move(pos, N ))) border |= (1 << 8);
00463 if (board->isOut(board->move(pos, NE))) border |= (1 << 9);
00464 if (board->isOut(board->move(pos, E ))) border |= (1 << 10);
00465 if (board->isOut(board->move(pos, SE))) border |= (1 << 11);
00466 if (board->isOut(board->move(pos, S ))) border |= (1 << 12);
00467 if (board->isOut(board->move(pos, SW))) border |= (1 << 13);
00468 if (board->isOut(board->move(pos, W ))) border |= (1 << 14);
00469 if (board->isOut(board->move(pos, NW))) border |= (1 << 15);
00470
00471 switch (border & 0xFF) {
00472 case 31 : border = 0; break;
00473 case 159 : border = 0; break;
00474 case 63 : border = 0; break;
00475 case 191 : border = 0; break;
00476 case 241 : border = 1; break;
00477 case 249 : border = 1; break;
00478 case 243 : border = 1; break;
00479 case 251 : border = 1; break;
00480 case 124 : border = 2; break;
00481 case 252 : border = 2; break;
00482 case 126 : border = 2; break;
00483 case 199 : border = 3; break;
00484 case 231 : border = 3; break;
00485 case 207 : border = 3; break;
00486 case 28 : if ((border >> 8) > 0)
00487 border = 24;
00488 else
00489 border = 4;
00490 break;
00491 case 112 : if ((border >> 8) > 0)
00492 border = 27;
00493 else
00494 border = 5;
00495 break;
00496 case 7 : if ((border >> 8) > 0)
00497 border = 25;
00498 else
00499 border = 6;
00500 break;
00501 case 193 : if ((border >> 8) > 0)
00502 border = 26;
00503 else
00504 border = 7;
00505 break;
00506 case 247 : if ((border & (1 << 11)) > 0)
00507 border = 23;
00508 else
00509 border = 8;
00510 break;
00511 case 119 : if ((border & (1 << 15)) > 0)
00512 border = 8;
00513 if ((border & (1 << 11)) > 0)
00514 border = 11;
00515 break;
00516 case 223 : if ((border & (1 << 13)) > 0)
00517 border = 20;
00518 else
00519 border = 9;
00520 break;
00521 case 221 : if ((border & (1 << 13)) > 0)
00522 border = 10;
00523 if ((border & (1 << 9)) > 0)
00524 border = 9;
00525 break;
00526 case 253 : if ((border & (1 << 9)) > 0)
00527 border = 21;
00528 else
00529 border = 10;
00530 break;
00531 case 127 : if ((border & (1 << 15)) > 0)
00532 border = 22;
00533 else
00534 border = 11;
00535 break;
00536 case 30 : border = 12; break;
00537 case 240 : border = 13; break;
00538 case 15 : border = 14; break;
00539 case 225 : border = 15; break;
00540 case 135 : border = 16; break;
00541 case 195 : border = 17; break;
00542 case 60 : border = 18; break;
00543 case 120 : border = 19; break;
00544 case 255 : border = 28; break;
00545 default : border = -1;
00546 }
00547 if (border != -1 && border < (int) wallPix->count()) {
00548 QRect rect = this->rect(pos, WallPix);
00549 bitBlt(&roomPix, rect.x(), rect.y(), wallPix->at((uint) border));
00550 }
00551 }
00552
00553 void Painter::drawPrison(int pos)
00554 {
00555 int border = 0;
00556 if (board->isPrison(board->move(pos, N ))) border |= (1 << 0);
00557 if (board->isPrison(board->move(pos, NE))) border |= (1 << 1);
00558 if (board->isPrison(board->move(pos, E ))) border |= (1 << 2);
00559 if (board->isPrison(board->move(pos, SE))) border |= (1 << 3);
00560 if (board->isPrison(board->move(pos, S ))) border |= (1 << 4);
00561 if (board->isPrison(board->move(pos, SW))) border |= (1 << 5);
00562 if (board->isPrison(board->move(pos, W ))) border |= (1 << 6);
00563 if (board->isPrison(board->move(pos, NW))) border |= (1 << 7);
00564
00565 if (board->isGate(board->move(pos, N ))) border |= (1 << 8);
00566 if (board->isGate(board->move(pos, NE))) border |= (1 << 9);
00567 if (board->isGate(board->move(pos, E ))) border |= (1 << 10);
00568 if (board->isGate(board->move(pos, SE))) border |= (1 << 11);
00569 if (board->isGate(board->move(pos, S ))) border |= (1 << 12);
00570 if (board->isGate(board->move(pos, SW))) border |= (1 << 13);
00571 if (board->isGate(board->move(pos, W ))) border |= (1 << 14);
00572 if (board->isGate(board->move(pos, NW))) border |= (1 << 15);
00573
00574 switch (border & 0xFF) {
00575 case 31 : border = 0; break;
00576 case 159 : border = 0; break;
00577 case 63 : border = 0; break;
00578 case 241 : border = 1; break;
00579 case 249 : border = 1; break;
00580 case 243 : border = 1; break;
00581 case 124 : border = 2; break;
00582 case 252 : border = 2; break;
00583 case 126 : border = 2; break;
00584 case 199 : border = 3; break;
00585 case 231 : border = 3; break;
00586 case 207 : border = 3; break;
00587 case 28 : if ((border >> 8) != 0)
00588 border = 12;
00589 else
00590 border = 4;
00591 break;
00592 case 112 : if ((border >> 8) != 0)
00593 border = 13;
00594 else
00595 border = 5;
00596 break;
00597 case 7 : if ((border >> 8) != 0)
00598 border = 14;
00599 else
00600 border = 6;
00601 break;
00602 case 193 : if ((border >> 8) != 0)
00603 border = 15;
00604 else
00605 border = 7;
00606 break;
00607 case 247 : border = 8; break;
00608 case 223 : border = 9; break;
00609 case 253 : border = 10; break;
00610 case 127 : border = 11; break;
00611 default : border = -1;
00612 }
00613 if (board->isGate(pos)) {
00614 if (board->isGate(board->move(pos, N)))
00615 border = 17;
00616 else
00617 border = 16;
00618 }
00619
00620 if (border != -1 && border < (int) prisonPix->count()) {
00621 QRect rect = this->rect(pos, PrisonPix);
00622 bitBlt(&roomPix, rect.x(), rect.y(), prisonPix->at((uint) border));
00623 }
00624 }
00625
00626 void Painter::drawPoint(int pos)
00627 {
00628 if (!pointPix->isEmpty()) {
00629 QRect rect = this->rect(pos, PointPix);
00630 bitBlt(&roomPix, rect.x(), rect.y(), pointPix->at(0));
00631 }
00632 }
00633
00634 QString Painter::decodeHexOctString(QString s)
00635 {
00636 QString value;
00637 QString valids;
00638 int pos, xpos = 0, opos = 0;
00639 int v, len, leadin;
00640 const char *ptr;
00641 uchar c;
00642
00643 while (((xpos = s.find(QRegExp("\\\\x[0-9a-fA-F]+"), xpos)) != -1) ||
00644 ((opos = s.find(QRegExp("\\\\[0-7]+"), opos)) != -1)) {
00645 if (xpos != -1) {
00646 valids = "0123456789abcdef";
00647 leadin = 2;
00648 pos = xpos;
00649 } else {
00650 valids = "01234567";
00651 leadin = 1;
00652 pos = opos;
00653 }
00654
00655 c = '\0';
00656 len = 0;
00657 value = s.mid(pos+leadin, 3);
00658 ptr = (const char *) value;
00659
00660 while (*ptr != '\0' && (v = valids.find(*ptr++, 0, FALSE)) != -1) {
00661 c = (c * valids.length()) + v;
00662 len++;
00663 }
00664
00665 value.fill(c, 1);
00666 s.replace(pos, len+leadin, value);
00667 }
00668
00669 return s;
00670 }
00671
00672 void Painter::fillScoreString(QStrList &list, QArray<int> &values)
00673 {
00674 if( !list.isEmpty())
00675 list.clear();
00676
00677 QString s;
00678
00679 for (uint i = 0; i < values.size(); i++) {
00680
00681 if (values[i] < 10 || values[i] > 10000)
00682 s = "?";
00683 else if (values[i] == 1600)
00684 s = "\x1a\x1b";
00685 else if (values[i] < 100) {
00686 s = "\x0e";
00687 s.insert(0, char (values[i] / 10 + 0x10));
00688 } else if (values[i] < 1000) {
00689 s = "\x0f";
00690 s.insert(0, char (values[i] / 100 + 0x10));
00691 } else {
00692 s = "\x0f\x10";
00693 s.insert(0, char (values[i] / 1000 + 0x10));
00694 }
00695
00696 list.append(s.data());
00697 }
00698 }
00699
00700 void Painter::fillArray(QArray<int> &array, QString values, int max)
00701 {
00702 array.resize(max);
00703 int last = 0;
00704 bool ok;
00705 QString value;
00706
00707 for (uint i = 0; i < array.size(); i++) {
00708 if (values.find(',') < 0 && values.length() > 0) {
00709 value = values;
00710 values = "";
00711 }
00712 if (values.find(',') >= 0) {
00713 value = values.left(values.find(','));
00714 values.remove(0,values.find(',')+1);
00715 }
00716 array[i] = value.toInt(&ok);
00717 if (ok)
00718 last = array[i];
00719 else
00720 array[i] = last;
00721 }
00722 }
00723
00724 void Painter::fillStrList(QStrList &list, QString values, int max)
00725 {
00726 if (!list.isEmpty())
00727 list.clear();
00728
00729 QString last = "";
00730 QString value;
00731
00732 for (uint i = 0; i < (uint) max; i++) {
00733 if (values.find(',') < 0 && values.length() > 0) {
00734 value = values;
00735 values = "";
00736 }
00737 if (values.find(',') >= 0) {
00738 value = values.left(values.find(','));
00739 values.remove(0,values.find(',')+1);
00740 }
00741 if (!value.isEmpty())
00742 last = decodeHexOctString(value);
00743 list.append(last);
00744 }
00745 }
00746
00747 void Painter::fillPixmapName(QStrList &pixmapName)
00748 {
00749 QStrList list = pixmapName;
00750
00751 if (!pixmapName.isEmpty())
00752 pixmapName.clear();
00753
00754 QString pixmap;
00755
00756 QFileInfo fileInfo;
00757
00758 for (uint i = 0; i < list.count(); i++) {
00759 pixmap = list.at(i);
00760
00761 if (pixmap.left(1) != "/" && pixmap.left(1) != "~")
00762 pixmap = FIND_APP_DATA( pixmapDirectory+pixmap );
00763
00764 fileInfo.setFile(pixmap);
00765 if (!fileInfo.isReadable() || !fileInfo.isFile())
00766 pixmap = "";
00767
00768 pixmapName.append(pixmap);
00769 }
00770 }
00771
00772 void Painter::confLevels(bool defGroup)
00773 {
00774 APP_CONFIG_BEGIN( cfg );
00775 if (defGroup || cfg->hasKey("Levels"))
00776 maxLevel = cfg->readNumEntry("Levels", 13);
00777 APP_CONFIG_END( cfg );
00778 }
00779
00780 void Painter::confMisc(bool defGroup)
00781 {
00782 APP_CONFIG_BEGIN( cfg );
00783 if (defGroup || cfg->hasKey("PixmapDirectory")) {
00784 pixmapDirectory = cfg->readEntry("PixmapDirectory");
00785
00786 if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~")
00787 pixmapDirectory.insert(0, "pics/");
00788 if (pixmapDirectory.right(1) != "/")
00789 pixmapDirectory.append("/");
00790 }
00791
00792 if (defGroup || cfg->hasKey("PointPixmapName"))
00793 fillStrList(pointPixmapName,
00794 cfg->readEntry("PointPixmapName", "point.xpm"), maxLevel+1);
00795 if (defGroup || cfg->hasKey("WallPixmapName"))
00796 fillStrList(wallPixmapName,
00797 cfg->readEntry("WallPixmapName", "wall.xpm"), maxLevel+1);
00798 if (defGroup || cfg->hasKey("PrisonPixmapName"))
00799 fillStrList(prisonPixmapName,
00800 cfg->readEntry("PrisonPixmapName", "prison.xpm"), maxLevel+1);
00801 if (defGroup || cfg->hasKey("EnergizerPixmapName"))
00802 fillStrList(energizerPixmapName,
00803 cfg->readEntry("EnergizerPixmapName", "switch.xpm"),maxLevel+1);
00804 if (defGroup || cfg->hasKey("FruitPixmapName"))
00805 fillStrList(fruitPixmapName,
00806 cfg->readEntry("FruitPixmapName", "fruit.xpm"), maxLevel+1);
00807 if (defGroup || cfg->hasKey("PacmanPixmapName"))
00808 fillStrList(pacmanPixmapName,
00809 cfg->readEntry("PacmanPixmapName", "pacman.xpm"), maxLevel+1);
00810 if (defGroup || cfg->hasKey("DyingPixmapName"))
00811 fillStrList(dyingPixmapName,
00812 cfg->readEntry("DyingPixmapName", "dying.xpm"), maxLevel+1);
00813 if (defGroup || cfg->hasKey("EyesPixmapName"))
00814 fillStrList(eyesPixmapName,
00815 cfg->readEntry("EyesPixmapName", "eyes.xpm"), maxLevel+1);
00816 if (defGroup || cfg->hasKey("MonsterPixmapName"))
00817 fillStrList(monsterPixmapName,
00818 cfg->readEntry("MonsterPixmapName", "monster.xpm"), maxLevel+1);
00819
00820 if (defGroup || cfg->hasKey("FruitScorePixmapName"))
00821 fillStrList(fruitScorePixmapName,
00822 cfg->readEntry("FruitScorePixmapName"), maxLevel+1);
00823 if (defGroup || cfg->hasKey("MonsterScorePixmapName"))
00824 fillStrList(monsterScorePixmapName,
00825 cfg->readEntry("MonsterScorePixmapName"), maxLevel+1);
00826 APP_CONFIG_END( cfg );
00827 }
00828
00829 void Painter::confScoring(bool defGroup)
00830 {
00831 APP_CONFIG_BEGIN( cfg );
00832 if (defGroup || cfg->hasKey("FruitScore"))
00833 fillArray(fruitScore,
00834 cfg->readEntry("FruitScore",
00835 "100,300,500,,700,,1000,,2000,,3000,,5000"),
00836 maxLevel+1);
00837 if (defGroup || cfg->hasKey("MonsterScore"))
00838 fillArray(monsterScore,
00839 cfg->readEntry("MonsterScore", "200,400,800,1600"), 4);
00840
00841 if (defGroup || cfg->hasKey("FruitScoreString"))
00842 fillStrList(fruitScoreString,
00843 cfg->readEntry("FruitScoreString"), maxLevel+1);
00844 if (defGroup || cfg->hasKey("MonsterScoreString"))
00845 fillStrList(monsterScoreString,
00846 cfg->readEntry("MonsterScoreString"), 4);
00847 APP_CONFIG_END( cfg );
00848 }
00849
00850 void Painter::confScheme()
00851 {
00852 APP_CONFIG_BEGIN( cfg );
00853 SAVE_CONFIG_GROUP( cfg, oldgroup );
00854 QString newgroup;
00855
00856
00857 if (mode == -1 && scheme == -1) {
00858 scheme = cfg->readNumEntry("Scheme", -1);
00859 mode = cfg->readNumEntry("Mode", -1);
00860
00861
00862 if (scheme != -1 || mode == -1) {
00863 newgroup.sprintf("Scheme %d", scheme);
00864 cfg->setGroup(newgroup);
00865
00866 mode = cfg->readNumEntry("Mode", -1);
00867 RESTORE_CONFIG_GROUP( cfg, oldgroup );
00868 }
00869 }
00870
00871 confLevels();
00872
00873 if (mode != -1) {
00874 newgroup.sprintf("Mode %d", mode);
00875 cfg->setGroup(newgroup);
00876
00877 confLevels(FALSE);
00878 }
00879
00880 if (scheme != -1) {
00881 newgroup.sprintf("Scheme %d", scheme);
00882 cfg->setGroup(newgroup);
00883
00884 confLevels(FALSE);
00885 }
00886
00887 RESTORE_CONFIG_GROUP( cfg, oldgroup );
00888
00889 confMisc();
00890 confScoring();
00891
00892 if (mode != -1) {
00893 newgroup.sprintf("Mode %d", mode);
00894 cfg->setGroup(newgroup);
00895
00896 confMisc(FALSE);
00897 confScoring(FALSE);
00898 }
00899
00900 if (scheme != -1) {
00901 newgroup.sprintf("Scheme %d", scheme);
00902 cfg->setGroup(newgroup);
00903
00904 confMisc(FALSE);
00905 confScoring(FALSE);
00906 }
00907
00908 if ((const char *) *fruitScoreString.at(0) == '\0')
00909 fillScoreString(fruitScoreString, fruitScore);
00910 if ((const char *) *monsterScoreString.at(0) == '\0')
00911 fillScoreString(monsterScoreString, monsterScore);
00912
00913 fillPixmapName(pointPixmapName);
00914 fillPixmapName(wallPixmapName);
00915 fillPixmapName(prisonPixmapName);
00916 fillPixmapName(energizerPixmapName);
00917 fillPixmapName(fruitPixmapName);
00918 fillPixmapName(pacmanPixmapName);
00919 fillPixmapName(dyingPixmapName);
00920 fillPixmapName(eyesPixmapName);
00921 fillPixmapName(monsterPixmapName);
00922 fillPixmapName(fruitScorePixmapName);
00923 fillPixmapName(monsterScorePixmapName);
00924
00925 initPixmaps();
00926 initbackPixmaps();
00927 initRoomPixmap();
00928
00929 RESTORE_CONFIG_GROUP( cfg, oldgroup );
00930 APP_CONFIG_END( cfg );
00931 }
00932
00933 void Painter::setScheme(int Scheme, int Mode, Bitfont *font)
00934 {
00935 bitfont = font;
00936
00937 mode = Mode;
00938 scheme = Scheme;
00939
00940 confScheme();
00941 }
00942
00943 void Painter::setLevel(int Level)
00944 {
00945 level = Level;
00946
00947 initPixmaps();
00948 initbackPixmaps();
00949 initRoomPixmap();
00950 }
00951
00952 int Painter::checkRange(int value, int max, int min)
00953 {
00954 if (value < min) {
00955 printf("Painter::checkRange (value = %d, max = %d, min = %d)\n",
00956 value, max, min);
00957 return min;
00958 } else if (value > max) {
00959 printf("Painter::checkRange (value = %d, max = %d, min = %d)\n",
00960 value, max, min);
00961 return max;
00962 } else
00963 return value;
00964 }