Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

StoneWidget.cpp

Go to the documentation of this file.
00001 /*
00002  *   ksame 0.4 - simple Game
00003  *   Copyright (C) 1997,1998  Marcus Kreutzberger
00004  *
00005  *   This program is free software; you can redistribute it and/or modify
00006  *   it under the terms of the GNU General Public License as published by
00007  *   the Free Software Foundation; either version 2 of the License, or
00008  *   (at your option) any later version.
00009  *
00010  *   This program is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *   GNU General Public License for more details.
00014  *
00015  *   You should have received a copy of the GNU General Public License
00016  *   along with this program; if not, write to the Free Software
00017  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018  *
00019  */
00020 
00021 #include <opie2/oresource.h>
00022 
00023 #include <qbitmap.h>
00024 
00025 #include <time.h>
00026 #include <assert.h>
00027 
00028 #include "StoneWidget.h"
00029 
00030 
00031 
00032 struct StoneSlice {
00033     QPixmap stone;
00034 };
00035 
00036 
00037 StoneWidget::StoneWidget( QWidget *parent, int x, int y )
00038     : QWidget(parent,"StoneWidget"), stonefield(x,y)
00039 {
00040     QPixmap stonemap = Opie::Core::OResource::loadPixmap( "zsame/stones" );
00041     assert(!stonemap.isNull());
00042 
00043     slice=0;
00044     maxslices=30;
00045     maxcolors=4;
00046 
00047     sizex=x;
00048     sizey=y;
00049 
00050     stone_width=stonemap.width()/(maxslices+1);
00051     stone_height=stonemap.height()/maxcolors;
00052 
00053     map = new StoneSlice*[maxcolors];
00054     QBitmap mask;
00055     for (int c = 0; c < maxcolors; c++) {
00056         map[c] = new StoneSlice[maxslices];
00057 
00058         for (int s = 0; s < maxslices; s++) {
00059             map[c][s].stone.resize(stone_width, stone_height);
00060             assert(!map[c][s].stone.isNull());
00061             bitBlt(&map[c][s].stone, 0, 0,
00062                    &stonemap, stone_width * s,
00063                    c*stone_height,
00064                    stone_width,stone_height,CopyROP,false);
00065             QImage im = map[c][s].stone.convertToImage();
00066             mask = im.createHeuristicMask();
00067             map[c][s].stone.setMask(mask);
00068         }
00069     }
00070 
00071     field_height=stone_height*sizey;
00072     field_width=stone_width*sizex;
00073 
00074     setMouseTracking(true);
00075 
00076     // QColor c(115,115,115);
00077     // setBackgroundColor(c);
00078 
00079     // emit s_sizechanged();
00080     startTimer( 100 );
00081     history.setAutoDelete(true);
00082 }
00083 
00084 StoneWidget::~StoneWidget() {
00085     for (int c = 0; c < maxcolors; c++) {
00086         delete [] map[c];
00087     }
00088     delete [] map;
00089 
00090     setMouseTracking(false);
00091     killTimers();
00092 }
00093 
00094 unsigned int
00095 StoneWidget::board() {
00096     return stonefield.getBoard();
00097 }
00098 
00099 int
00100 StoneWidget::score() {
00101     return stonefield.getScore();
00102 }
00103 
00104 int
00105 StoneWidget::marked() {
00106         return stonefield.getMarked();
00107 }
00108 
00109 QSize
00110 StoneWidget::size() {
00111     return QSize(sizex,sizey);
00112 }
00113 
00114 int
00115 StoneWidget::colors() {
00116     return stonefield.getColors();
00117 }
00118 
00119 QSize
00120 StoneWidget::sizeHint () const {
00121     return QSize(field_width,field_height);
00122 }
00123 
00124 void
00125 StoneWidget::newGame(unsigned int board,int colors) {
00126     stonefield.newGame(board,colors);
00127     history.clear();
00128     modified= false;
00129     emit s_newgame();
00130     emit s_colors(stonefield.getColors());
00131     emit s_board(stonefield.getBoard());
00132 }
00133 
00134 void
00135 StoneWidget::reset() {
00136     stonefield.reset();
00137     history.clear();
00138     emit s_newgame();
00139 }
00140 
00141 void
00142 StoneWidget::unmark() {
00143     stonefield.unmark();
00144     emit s_marked(0);
00145 }
00146 
00147 bool StoneWidget::undoPossible() const {
00148     if (stonefield.isGameover()) return false;
00149     return stonefield.undoPossible();
00150 }
00151 
00152 int
00153 StoneWidget::undo(int count) {
00154     if (stonefield.isGameover()) return 0;
00155 
00156     int ret_val=stonefield.undo(count);
00157 
00158     QPoint p=mapFromGlobal(cursor().pos());
00159     int x=p.x();
00160     int y=p.y();
00161     if (x<0||y<0||x>=field_width||y>=field_height) {
00162         emit s_score(stonefield.getMarked());
00163         return ret_val;
00164     }
00165 
00166     int marked=stonefield.mark(x/stone_width,y/stone_height);
00167     emit s_marked(marked);
00168     slice=0;
00169     emit s_score(stonefield.getScore());
00170     modified= (stonefield.getScore()>0);
00171     return ret_val;
00172 }
00173 
00174 bool StoneWidget::isGameover() {
00175     return stonefield.isGameover();
00176 }
00177 
00178 bool StoneWidget::hasBonus() {
00179         return stonefield.gotBonus(); // don't ask me why the names differ... ;-| [hlm]
00180 }
00181 
00182 void StoneWidget::clearBonus() {
00183     stonefield.clearBonus();
00184 }
00185 
00186 bool StoneWidget::isOriginalBoard() {
00187         return !modified;
00188 }
00189 
00190 void StoneWidget::readProperties(Config *) {
00191 /*    Q_ASSERT(conf);
00192 
00193     history.clear();
00194 
00195     if (!conf->hasKey("Board")||
00196         !conf->hasKey("Colors")||
00197         !conf->hasKey("Stones")) {
00198         return;
00199     }
00200     newGame(conf->readNumEntry("Board"),conf->readNumEntry("Colors"));
00201 
00202     QStrList list;
00203     conf->readListEntry("Stones",list);
00204 
00205     for (const char *item=list.first();item;item=list.next()) {
00206         int x=-1,y=-1;
00207         if (sscanf(item,"%02X%02X",&x,&y)!=2) break;
00208         history.append(new QPoint(x,y));
00209         stonefield.remove(x,y);
00210     }
00211 */
00212 }
00213 
00214 
00215 void
00216 StoneWidget::saveProperties(Config *) {
00217 /*
00218     Q_ASSERT(conf);
00219 
00220     QStrList list(true);
00221     QString tmp;
00222 
00223     for (QPoint *item=history.first();item;item=history.next()) {
00224         tmp.sprintf("%02X%02X",item->x(),item->y());
00225         list.append(tmp.ascii());
00226     }
00227 
00228     conf->writeEntry("Stones",list);
00229     conf->writeEntry("Board",stonefield.getBoard());
00230     conf->writeEntry("Colors",stonefield.getColors());
00231 */
00232 }
00233 
00234 void
00235 StoneWidget::timerEvent( QTimerEvent * ) {
00236     QPoint p=mapFromGlobal(cursor().pos());
00237     int x=p.x();
00238     int y=p.y();
00239     if (x<0||y<0||x>=field_width||y>=field_height)
00240         stonefield.unmark();
00241     slice=(slice+1)%maxslices;
00242     paintEvent(0);
00243 }
00244 
00245 void
00246 StoneWidget::paintEvent( QPaintEvent *e ) {
00247 
00248     Stone *stone=stonefield.getField();
00249 
00250     for (int y=0;y<sizey;y++) {
00251         int cy = y * stone_height;
00252 
00253         for (int x=0;x<sizex;x++) {
00254             int cx = stone_width * x;
00255 
00256             bool redraw=stone->marked||stone->changed;
00257 
00258             if (!redraw&&e) {
00259                 QRect r(cx,cy,stone_width,stone_height);
00260                 redraw=r.intersects(e->rect());
00261             }
00262             if (redraw) {
00263                 stone->changed=false;
00264                 if (stone->color) {
00265 
00266                     int tslice = stone->marked?slice:0;
00267                     bitBlt(this,cx,cy,
00268                            &map[stone->color-1][tslice].stone,
00269                            0, 0,
00270                            stone_width,stone_height,CopyROP,FALSE);
00271 
00272                 } else {
00273                     erase(cx, cy, stone_width, stone_height);
00274                 }
00275             }
00276             stone++;  // naechster Stein.
00277         }
00278     }
00279 }
00280 
00281 void
00282 StoneWidget::mousePressEvent ( QMouseEvent *e) {
00283 
00284     if (stonefield.isGameover()) return;
00285 
00286     int x=e->pos().x();
00287     int y=e->pos().y();
00288     if (x<0||y<0||x>=field_width||y>=field_height) return;
00289 
00290     int sx=x/stone_width;
00291     int sy=y/stone_height;
00292 
00293     int mar =stonefield.mark(sx, sy);
00294 
00295     if ( mar != -1 ) {
00296         myMoveEvent(e);
00297         return;
00298     }
00299 
00300 
00301     if (stonefield.remove(sx, sy)) {
00302         history.append(new QPoint(sx, sy));
00303 
00304         emit s_remove(sx, sy);
00305 
00306         stonefield.mark(sx,sy);
00307         emit s_marked(stonefield.getMarked());
00308                 modified= true;
00309 
00310         emit s_score(stonefield.getScore());
00311         if (stonefield.isGameover()) emit s_gameover();
00312     }
00313 }
00314 
00315 void
00316 StoneWidget::myMoveEvent ( QMouseEvent *e)
00317 {
00318     return;
00319 
00320     if (stonefield.isGameover()) {
00321         stonefield.unmark();
00322         emit s_marked(0);
00323         return;
00324     }
00325 
00326     int x=e->pos().x();
00327     int y=e->pos().y();
00328     if (x<0||y<0||x>=field_width||y>=field_height) return;
00329 
00330     int marked=stonefield.mark(x/stone_width,y/stone_height);
00331     if (marked>=0) {
00332         emit s_marked(marked);
00333         slice=0;
00334     }
00335 }
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343 

Generated on Sat Nov 5 16:17:28 2005 for OPIE by  doxygen 1.4.2