You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegames/ksnake/pixServer.cpp

246 lines
7.0 KiB

/**
* Copyright Michel Filippi <mfilippi@sade.rhein-main.de>
* Robert Williams
* Andrew Chant <andrew.chant@utoronto.ca>
* André Luiz dos Santos <andre@netvision.com.br>
* Benjamin Meyer <ben+ksnake@meyerhome.net>
*
* This file is part of the ksnake package
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "pixServer.h"
#include <qimage.h>
#include <qpainter.h>
#include <qbitmap.h>
#include <kstandarddirs.h>
#include <klocale.h>
#include <kdebug.h>
#include "board.h"
#include "settings.h"
PixServer::PixServer( Board *b)
{
board = b;
initPixmaps();
initBrickPixmap();
initbackPixmaps();
initRoomPixmap();
}
void PixServer::erase(int pos)
{
if (!board->isEmpty(pos))
return;
QRect rect = board->rect(pos);
bitBlt( &cachePix, rect.x(), rect.y(), &backPix,
rect.x(), rect.y(), rect.width(), rect.height());
}
void PixServer::restore(int pos)
{
QRect rect = board->rect(pos);
bitBlt( &cachePix, rect.x(), rect.y(), &roomPix,
rect.x(), rect.y(), rect.width(), rect.height());
}
void PixServer::draw(int pos, PixMap pix, int i)
{
QPixmap p;
p.resize(BRICKSIZE, BRICKSIZE);
QRect rect = board->rect(pos);
if (! plainColor)
bitBlt( &p, 0, 0, &backPix,
rect.x(), rect.y(), rect.width(), rect.height());
else
p.fill(backgroundColor);
switch (pix) {
case SamyPix: bitBlt(&p ,0,0, &samyPix[i]);
break;
case CompuSnakePix: bitBlt(&p ,0,0, &compuSnakePix[i]);
break;
case ApplePix: bitBlt(&p ,0,0, &applePix[i]);
break;
case BallPix: bitBlt(&p ,0,0, &ballPix[i]);
break;
default:
break;
}
bitBlt(&cachePix, rect.x(), rect.y(), &p);
}
void PixServer::initPixmaps()
{
QPixmap pm = QPixmap(locate("appdata", "pics/snake1.png"));
QImage qi = pm.convertToImage();
qi=qi.smoothScale(BRICKSIZE*18,BRICKSIZE);
pm.convertFromImage(qi,QPixmap::AvoidDither);
for (int x = 0 ; x < 18; x++){
compuSnakePix[x].resize(BRICKSIZE, BRICKSIZE);
bitBlt(&compuSnakePix[x] ,0,0, &pm,x*BRICKSIZE, 0, BRICKSIZE, BRICKSIZE, Qt::CopyROP, true);
compuSnakePix[x].setMask(compuSnakePix[x].createHeuristicMask());
}
pm = QPixmap(locate("appdata", "pics/snake2.png"));
qi = pm.convertToImage();
qi=qi.smoothScale(BRICKSIZE*18,BRICKSIZE);
pm.convertFromImage(qi,QPixmap::AvoidDither);
for (int x = 0 ; x < 18; x++){
samyPix[x].resize(BRICKSIZE, BRICKSIZE);
bitBlt(&samyPix[x] ,0,0, &pm,x*BRICKSIZE, 0, BRICKSIZE, BRICKSIZE, Qt::CopyROP, true);
samyPix[x].setMask(samyPix[x].createHeuristicMask());
}
pm = QPixmap(locate("appdata", "pics/ball.png"));
qi = pm.convertToImage();
qi=qi.smoothScale(BRICKSIZE*4,BRICKSIZE);
pm.convertFromImage(qi,QPixmap::AvoidDither);
for (int x = 0 ; x < 4; x++){
ballPix[x].resize(BRICKSIZE, BRICKSIZE);
bitBlt(&ballPix[x] ,0,0, &pm,x*BRICKSIZE, 0, BRICKSIZE, BRICKSIZE, Qt::CopyROP, true);
ballPix[x].setMask(ballPix[x].createHeuristicMask());
}
pm = QPixmap(locate("appdata", "pics/apples.png"));
qi = pm.convertToImage();
qi=qi.smoothScale(BRICKSIZE*2,BRICKSIZE);
pm.convertFromImage(qi,QPixmap::AvoidDither);
for (int x = 0 ; x < 2; x++){
applePix[x].resize(BRICKSIZE, BRICKSIZE);
bitBlt(&applePix[x] ,0,0, &pm,x*BRICKSIZE, 0, BRICKSIZE, BRICKSIZE, Qt::CopyROP, true);
applePix[x].setMask(applePix[x].createHeuristicMask());
}
}
void PixServer::initbackPixmaps()
{
QString path;
plainColor = false;
if(Settings::bgcolor_enabled()){
backgroundColor = Settings::bgcolor();
plainColor = true;
} else if(Settings::bgimage_enabled()) {
// A bit of a hack.
QStringList backgroundPixmaps =
KGlobal::dirs()->findAllResources("appdata", "backgrounds/*.png");
path = backgroundPixmaps[(Settings::bgimage())];
}
QPixmap PIXMAP;
int pw, ph;
backPix.resize(MAPWIDTH, MAPHEIGHT);
if (! plainColor) {
PIXMAP = QPixmap(path);
if (!PIXMAP.isNull()) {
pw = PIXMAP.width();
ph = PIXMAP.height();
for (int x = 0; x <= MAPWIDTH; x+=pw) //Tile BG Pixmap onto backPix
for (int y = 0; y <= MAPHEIGHT; y+=ph)
bitBlt(&backPix, x, y, &PIXMAP);
}
else {
kdDebug() << "error loading background image :" << path << endl;
backgroundColor = (QColor("black"));
plainColor = true;
}
}
if ( plainColor)
backPix.fill(backgroundColor);
}
void PixServer::initBrickPixmap()
{
QPixmap pm = QPixmap(locate("appdata", "pics/brick.png"));
if (pm.isNull()) {
kdFatal() << i18n("error loading %1, aborting\n").arg("brick.png");
}
int pw = pm.width();
int ph = pm.height();
offPix.resize(MAPWIDTH, MAPHEIGHT);
for (int x = 0; x <= MAPWIDTH; x+=pw)
for (int y = 0; y <= MAPHEIGHT; y+=ph)
bitBlt(&offPix, x, y, &pm);
}
void PixServer::initRoomPixmap()
{
QPainter paint;
roomPix.resize(MAPWIDTH, MAPHEIGHT);
bitBlt(&roomPix,0,0, &backPix);
paint.begin(&roomPix);
for (unsigned int x = 0; x < board->size(); x++) {
if (board->isBrick(x))
drawBrick(&paint, x);
}
paint.end();
cachePix.resize(MAPWIDTH, MAPHEIGHT);
bitBlt(&cachePix,0,0, &roomPix);
}
void PixServer::drawBrick(QPainter *p ,int i)
{
//Note, ROOMPIC IS OUR 'TARGET'
QColor light(180,180,180);
QColor dark(100,100,100);
int topSq = board->getNext(N, i); //find 'address' of neighbouring squares
int botSq = board->getNext(S, i);
int rightSq = board->getNext(E ,i);
int leftSq = board->getNext(W, i);
QRect rect = board->rect(i); //get our square's rect
int x = rect.x();
int y = rect.y(); //Get x,y location of square???
int width, height;
int highlight = 2; //Highlighting Distance (pixels)?
width = height = rect.width();
p->fillRect(x, y, width, height, light); //By default, fill square w/ Light? no. use dark!!!!
bitBlt(&roomPix, x, y, &offPix, x, y, width, height ); //Copy the brick pattern onto the brick
if (!board->isBrick(rightSq)) p->fillRect(x + width - highlight, y, highlight, height, dark); //highlight if its an end-brick.
if (!board->isBrick(leftSq)) p->fillRect(x, y, highlight, height, light);
if (!board->isBrick(botSq)) p->fillRect(x, y + height - highlight, width, highlight, dark);
if (!board->isBrick(topSq)) p->fillRect(x, y, width, highlight, light);
}