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/ksokoban/ImageData.cpp

214 lines
6.0 KiB

/*
* ksokoban - a Sokoban game for KDE
* Copyright (C) 1998 Anders Widell <awl@hem.passagen.se>
*
* 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 program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "ImageData.h"
#include <assert.h>
#include <qpainter.h>
#include <qpixmap.h>
#include <qimage.h>
#include <qcolor.h>
ImageData::ImageData() : indexSize_(0), size_(0), halfSize_(0) {
random.setSeed(0);
}
ImageData::~ImageData() {
}
void
ImageData::expandIndex(int size) {
size++;
assert(size < 2500);
upperLargeIndex_.resize(size);
lowerLargeIndex_.resize(size);
leftSmallIndex_.resize(size);
rightSmallIndex_.resize(size);
for (int i=indexSize_; i<size; i++) {
upperLargeIndex_[i] = random.getLong(LARGE_STONES);
lowerLargeIndex_[i] = random.getLong(LARGE_STONES);
leftSmallIndex_[i] = random.getLong(SMALL_STONES);
rightSmallIndex_[i] = random.getLong(SMALL_STONES);
}
indexSize_ = size;
}
const QPixmap &
ImageData::upperLarge(int index) {
assert(index >= 0);
if (indexSize_ <= index) expandIndex(index);
return largeStone_xpm_[(unsigned char)upperLargeIndex_[index]];
}
const QPixmap &
ImageData::lowerLarge(int index) {
assert(index >= 0);
if (indexSize_ <= index) expandIndex(index);
return largeStone_xpm_[(unsigned char)lowerLargeIndex_[index]];
}
const QPixmap &
ImageData::leftSmall(int index) {
assert(index >= 0);
if (indexSize_ <= index) expandIndex(index);
return smallStone_xpm_[(unsigned char)leftSmallIndex_[index]];
}
const QPixmap &
ImageData::rightSmall(int index) {
assert(index >= 0);
if (indexSize_ <= index) expandIndex(index);
return smallStone_xpm_[(unsigned char)rightSmallIndex_[index]];
}
int
ImageData::resize(int size) {
assert(size > 0);
size &= ~1u;
if (size == size_) return size;
size_ = size;
halfSize_ = size/2;
for (int i=0; i<SMALL_STONES; i++) {
image2pixmap(images_[i].smoothScale(halfSize_, halfSize_), smallStone_xpm_[i]);
// smallStone_xpm_[i].convertFromImage(images_[i].smoothScale(halfSize_, halfSize_), QPixmap::ColorOnly|QPixmap::DiffuseDither|QPixmap::DiffuseAlphaDither|QPixmap::AvoidDither);
}
for (int i=0; i<LARGE_STONES; i++) {
image2pixmap(images_[SMALL_STONES+i].smoothScale(size_, halfSize_), largeStone_xpm_[i]);
// largeStone_xpm_[i].convertFromImage(images_[SMALL_STONES+i].smoothScale(size_, halfSize_) , QPixmap::ColorOnly|QPixmap::DiffuseDither|QPixmap::DiffuseAlphaDither|QPixmap::AvoidDither);
}
objectImg_ = images_[SMALL_STONES+LARGE_STONES].smoothScale(size_, size_);
// Use copy() because if the size is not changed, smoothScale is not
// really a copy
// Use {[Geometry] height=753 width=781} to test
if (objectImg_.width() == size_) objectImg_ = objectImg_.copy();
image2pixmap(objectImg_, otherPixmaps_[0], false);
brighten(objectImg_);
image2pixmap(objectImg_, brightObject_, false);
QImage img = images_[SMALL_STONES+LARGE_STONES+1].smoothScale(size_, size_);
if (img.width() == size_) img = img.copy();
image2pixmap(img, otherPixmaps_[1], false);
brighten(img);
image2pixmap(img, brightTreasure_, false);
for (int i=2; i<OTHER_IMAGES; i++) {
image2pixmap(images_[SMALL_STONES+LARGE_STONES+i].smoothScale(size_, size_), otherPixmaps_[i]);
// otherPixmaps_[i].convertFromImage(images_[SMALL_STONES+LARGE_STONES+i].smoothScale(size_, size_), QPixmap::ColorOnly|QPixmap::OrderedDither|QPixmap::OrderedAlphaDither|QPixmap::AvoidDither);
}
return size_;
}
// Don't use DiffuseDither for the objects on the "floor" since
// it gives spurious dots on the floor around them
void
ImageData::image2pixmap(QImage img, QPixmap& xpm, bool diffuse) {
xpm.convertFromImage(img,
(diffuse ?
(QPixmap::DiffuseDither|QPixmap::DiffuseAlphaDither) :
(QPixmap::OrderedDither|QPixmap::OrderedAlphaDither))|
QPixmap::ColorOnly|QPixmap::AvoidDither);
}
void
ImageData::brighten(QImage& img) {
assert(img.depth() == 32);
for (int y=0; y<img.height(); y++) {
for (int x=0; x<img.width(); x++) {
QRgb rgb = img.pixel(x, y);
int r = qRed(rgb);
int g = qGreen(rgb);
int b = qBlue(rgb);
if (r > g && r > b) {
// only modify redish pixels
QColor col(r, g, b);
QColor lcol = col.light(130);
img.setPixel(x, y, lcol.rgb());
}
}
}
}
void
ImageData::wall(QPainter &p, int x, int y, int index, bool left, bool right) {
if (left) p.drawPixmap(x, y, upperLarge(index-1), halfSize_);
else p.drawPixmap(x, y, leftSmall(index));
if (right) p.drawPixmap(x+halfSize_, y, upperLarge(index), 0, 0, halfSize_);
else p.drawPixmap(x+halfSize_, y, rightSmall(index));
p.drawPixmap(x, y+halfSize_, lowerLarge(index));
}
void
ImageData::floor(QPainter &p, int x, int y) {
p.eraseRect(x, y, size_, size_);
}
void
ImageData::goal(QPainter &p, int x, int y) {
p.drawPixmap(x, y, otherPixmaps_[2]);
}
void
ImageData::man(QPainter &p, int x, int y) {
p.drawPixmap(x, y, otherPixmaps_[3]);
}
void
ImageData::object(QPainter &p, int x, int y) {
p.drawPixmap(x, y, otherPixmaps_[0]);
}
void
ImageData::saveman(QPainter &p, int x, int y) {
p.drawPixmap(x, y, otherPixmaps_[4]);
}
void
ImageData::treasure(QPainter &p, int x, int y) {
p.drawPixmap(x, y, otherPixmaps_[1]);
}
void
ImageData::brightObject(QPainter &p, int x, int y) {
p.drawPixmap(x, y, brightObject_);
}
void
ImageData::brightTreasure(QPainter &p, int x, int y) {
p.drawPixmap(x, y, brightTreasure_);
}