/* * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "StoneWidget.moc" struct StoneSlice { TQPixmap stone; }; StoneWidget::StoneWidget( TQWidget *parent, int x, int y ) : TQWidget(parent,"StoneWidget"), stonefield(x,y) { setBackgroundPixmap(TQPixmap(locate("wallpaper", "Time-For-Lunch-2.jpg"))); TQPixmap 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]; TQBitmap 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(TQT_TQPAINTDEVICE(&map[c][s].stone), 0, 0, TQT_TQPAINTDEVICE(&stonemap), stone_width * s, c*stone_height, stone_width,stone_height,CopyROP,false); TQImage im = map[c][s].stone.convertToImage(); mask.convertFromImage(im.createHeuristicMask()); map[c][s].stone.setMask(mask); } } field_height=stone_height*sizey; field_width=stone_width*sizex; setMouseTracking(true); // TQColor 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); TQT_TQOBJECT(this)->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(); } TQSize StoneWidget::size() { return TQSize(sizex,sizey); } int StoneWidget::colors() { return stonefield.getColors(); } TQSize StoneWidget::sizeHint () const { return TQSize(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); TQPoint 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(TDEConfig *conf) { Q_ASSERT(conf); history.clear(); if (!conf->hasKey("Board")|| !conf->hasKey("Colors")|| !conf->hasKey("Stones")) { return; } newGame(conf->readNumEntry("Board"),conf->readNumEntry("Colors")); TQStrList 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 TQPoint(x,y)); stonefield.remove(x,y); } } void StoneWidget::saveProperties(TDEConfig *conf) { Q_ASSERT(conf); TQStrList list(true); TQString tmp; for (TQPoint *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( TQTimerEvent * ) { TQPoint 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( TQPaintEvent *e ) { Stone *stone=stonefield.getField(); for (int y=0;ymarked||stone->changed; if (!redraw&&e) { TQRect 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(TQT_TQPAINTDEVICE(this),cx,cy, TQT_TQPAINTDEVICE(&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 ( TQMouseEvent *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 TQPoint(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 ( TQMouseEvent *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; } }