summaryrefslogtreecommitdiffstats
path: root/ksame/StoneWidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ksame/StoneWidget.cpp')
-rw-r--r--ksame/StoneWidget.cpp345
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;
+ }
+}
+
+
+
+
+
+
+
+