00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00077
00078
00079
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();
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
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 }
00213
00214
00215 void
00216 StoneWidget::saveProperties(Config *) {
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
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++;
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