diff options
Diffstat (limited to 'ksame/StoneWidget.cpp')
-rw-r--r-- | ksame/StoneWidget.cpp | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/ksame/StoneWidget.cpp b/ksame/StoneWidget.cpp new file mode 100644 index 00000000..3d4114de --- /dev/null +++ b/ksame/StoneWidget.cpp @@ -0,0 +1,345 @@ +/* + * ksame 0.4 - simple Game + * Copyright (C) 1997,1998 Marcus Kreutzberger + * + * 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 <config.h> +#include <stdio.h> +#include <stdlib.h> + +#include <qpainter.h> +#include <qpixmap.h> +#include <qbitmap.h> +#include <qimage.h> +#include <qcursor.h> + +#include <kapplication.h> +#include <kconfig.h> +#include <kiconloader.h> + +#include <time.h> +#include <kglobal.h> +#include <kstandarddirs.h> +#include <kdebug.h> +#include <assert.h> + +#include "StoneWidget.moc" + + +struct StoneSlice { + QPixmap stone; +}; + + +StoneWidget::StoneWidget( QWidget *parent, int x, int y ) + : QWidget(parent,"StoneWidget"), stonefield(x,y) +{ + setBackgroundPixmap(QPixmap(locate("wallpaper", "Time-For-Lunch-2.jpg"))); + QPixmap stonemap(locate("appdata", "stones.png")); + + assert(!stonemap.isNull()); + + slice=0; + maxslices=30; + maxcolors=4; + + sizex=x; + sizey=y; + + stone_width=stonemap.width()/(maxslices+1); + stone_height=stonemap.height()/maxcolors; + + map = new StoneSlice*[maxcolors]; + QBitmap mask; + for (int c = 0; c < maxcolors; c++) { + map[c] = new StoneSlice[maxslices]; + + for (int s = 0; s < maxslices; s++) { + map[c][s].stone.resize(stone_width, stone_height); + assert(!map[c][s].stone.isNull()); + bitBlt(&map[c][s].stone, 0, 0, + &stonemap, stone_width * s, + c*stone_height, + stone_width,stone_height,CopyROP,false); + QImage im = map[c][s].stone.convertToImage(); + mask = im.createHeuristicMask(); + map[c][s].stone.setMask(mask); + } + } + + field_height=stone_height*sizey; + field_width=stone_width*sizex; + + setMouseTracking(true); + + // QColor c(115,115,115); + // setBackgroundColor(c); + + // emit s_sizechanged(); + startTimer( 100 ); + history.setAutoDelete(true); +} + +StoneWidget::~StoneWidget() { + for (int c = 0; c < maxcolors; c++) { + delete [] map[c]; + } + delete [] map; + + setMouseTracking(false); + killTimers(); +} + +unsigned int +StoneWidget::board() { + return stonefield.getBoard(); +} + +int +StoneWidget::score() { + return stonefield.getScore(); +} + +int +StoneWidget::count(int color) { + return stonefield.count(color); +} + +int +StoneWidget::marked() { + return stonefield.getMarked(); +} + +QSize +StoneWidget::size() { + return QSize(sizex,sizey); +} + +int +StoneWidget::colors() { + return stonefield.getColors(); +} + +QSize +StoneWidget::sizeHint () const { + return QSize(field_width,field_height); +} + +void +StoneWidget::newGame(unsigned int board,int colors) { + stonefield.newGame(board,colors); + history.clear(); + modified= false; + emit s_newgame(); + emit s_colors(stonefield.getColors()); + emit s_board(stonefield.getBoard()); +} + +void +StoneWidget::reset() { + stonefield.reset(); + history.clear(); + emit s_newgame(); +} + +void +StoneWidget::unmark() { + stonefield.unmark(); + emit s_marked(0); +} + +bool StoneWidget::undoPossible() const { + if (stonefield.isGameover()) return false; + return stonefield.undoPossible(); +} + +int +StoneWidget::undo(int count) { + if (stonefield.isGameover()) return 0; + + int ret_val=stonefield.undo(count); + + QPoint p=mapFromGlobal(cursor().pos()); + int x=p.x(); + int y=p.y(); + if (x<0||y<0||x>=field_width||y>=field_height) { + emit s_score(stonefield.getMarked()); + return ret_val; + } + + int marked=stonefield.mark(x/stone_width,y/stone_height); + emit s_marked(marked); + slice=0; + emit s_score(stonefield.getScore()); + modified= (stonefield.getScore()>0); + return ret_val; +} + +bool StoneWidget::isGameover() { + return stonefield.isGameover(); +} + +bool StoneWidget::hasBonus() { + return stonefield.gotBonus(); // don't ask me why the names differ... ;-| [hlm] +} + +bool StoneWidget::isOriginalBoard() { + return !modified; +} + +void StoneWidget::readProperties(KConfig *conf) { + Q_ASSERT(conf); + + history.clear(); + + if (!conf->hasKey("Board")|| + !conf->hasKey("Colors")|| + !conf->hasKey("Stones")) { + return; + } + newGame(conf->readNumEntry("Board"),conf->readNumEntry("Colors")); + + QStrList list; + conf->readListEntry("Stones",list); + + for (const char *item=list.first();item;item=list.next()) { + int x=-1,y=-1; + if (sscanf(item,"%02X%02X",&x,&y)!=2) break; + history.append(new QPoint(x,y)); + stonefield.remove(x,y); + } +} + + +void +StoneWidget::saveProperties(KConfig *conf) { + Q_ASSERT(conf); + + QStrList list(true); + QString tmp; + + for (QPoint *item=history.first();item;item=history.next()) { + tmp.sprintf("%02X%02X",item->x(),item->y()); + list.append(tmp.ascii()); + } + + conf->writeEntry("Stones",list); + conf->writeEntry("Board",stonefield.getBoard()); + conf->writeEntry("Colors",stonefield.getColors()); +} + +void +StoneWidget::timerEvent( QTimerEvent * ) { + QPoint p=mapFromGlobal(cursor().pos()); + int x=p.x(); + int y=p.y(); + if (x<0||y<0||x>=field_width||y>=field_height) + stonefield.unmark(); + slice=(slice+1)%maxslices; + paintEvent(0); +} + +void +StoneWidget::paintEvent( QPaintEvent *e ) { + + Stone *stone=stonefield.getField(); + + for (int y=0;y<sizey;y++) { + int cy = y * stone_height; + + for (int x=0;x<sizex;x++) { + int cx = stone_width * x; + + bool redraw=stone->marked||stone->changed; + + if (!redraw&&e) { + QRect r(cx,cy,stone_width,stone_height); + redraw=r.intersects(e->rect()); + } + if (redraw) { + stone->changed=false; + if (stone->color) { + + int tslice = stone->marked?slice:0; + bitBlt(this,cx,cy, + &map[stone->color-1][tslice].stone, + 0, 0, + stone_width,stone_height,CopyROP,FALSE); + + } else { + erase(cx, cy, stone_width, stone_height); + } + } + stone++; // naechster Stein. + } + } +} + +void +StoneWidget::mousePressEvent ( QMouseEvent *e) { + + if (stonefield.isGameover()) return; + + int x=e->pos().x(); + int y=e->pos().y(); + if (x<0||y<0||x>=field_width||y>=field_height) return; + + int sx=x/stone_width; + int sy=y/stone_height; + + if (stonefield.remove(sx, sy)) { + history.append(new QPoint(sx, sy)); + + emit s_remove(sx, sy); + + stonefield.mark(sx,sy); + emit s_marked(stonefield.getMarked()); + modified= true; + + emit s_score(stonefield.getScore()); + if (stonefield.isGameover()) emit s_gameover(); + } +} + +void +StoneWidget::mouseMoveEvent ( QMouseEvent *e) +{ + if (stonefield.isGameover()) { + stonefield.unmark(); + emit s_marked(0); + return; + } + + int x=e->pos().x(); + int y=e->pos().y(); + if (x<0||y<0||x>=field_width||y>=field_height) return; + + int marked=stonefield.mark(x/stone_width,y/stone_height); + if (marked>=0) { + emit s_marked(marked); + slice=0; + } +} + + + + + + + + |