You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
808 lines
20 KiB
808 lines
20 KiB
/***************************************************************************
|
|
board_2d.cpp - description
|
|
-------------------
|
|
begin : Fri Feb 28 2003
|
|
copyright : (C) 2003 by The Knights Project
|
|
email : knights-general@lists.sourceforge.net
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* 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. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "board_2d.moc"
|
|
#include "resource.h"
|
|
#include "logic.h"
|
|
#include "knightspixcache.h"
|
|
#include <kiconeffect.h>
|
|
#include <tqpainter.h>
|
|
#include <tqtimer.h>
|
|
|
|
static int MAX_STEPS = 18;
|
|
|
|
board_2d::board_2d(TQWidget *parent, const char *name, resource *Rsrc, logic *Lgc ) : board_base(parent,name,Rsrc,Lgc)
|
|
{
|
|
updateX1 = updateY1 = 4000;
|
|
updateX2 = updateY2 = -4000;
|
|
init = TRUE;
|
|
premoveFrom = Null;
|
|
premoveTo = Null;
|
|
DragSprite = NULL;
|
|
lastMoveWasDrag = FALSE;
|
|
cache = myResource->pixCache;
|
|
int size = 8 + ( 1 * ( myResource->ThemeBorder == TRUE ) );
|
|
sprites.setAutoDelete( TRUE );
|
|
|
|
/* Setup Pixmaps */
|
|
myself.setOptimization( TQPixmap::BestOptim );
|
|
myself.resize( myResource->ThemeSize * size, myResource->ThemeSize * size);
|
|
myself.fill();
|
|
|
|
/* Setup self */
|
|
setBackgroundMode( TQt::NoBackground );
|
|
show();
|
|
}
|
|
board_2d::~board_2d()
|
|
{
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::coords
|
|
//
|
|
///////////////////////////////////////
|
|
TQPoint board_2d::coords( const int &rank, const int &file )
|
|
{
|
|
TQPoint tmp;
|
|
if( orientation == 0 )
|
|
{
|
|
tmp.setX( myResource->ThemeSize * file );
|
|
tmp.setY( myResource->ThemeSize * ( 7 - rank ) );
|
|
}
|
|
else
|
|
{
|
|
tmp.setX( myResource->ThemeSize * ( 7 - file ) );
|
|
tmp.setY( myResource->ThemeSize * rank );
|
|
}
|
|
if( myResource->ThemeBorder )
|
|
{
|
|
tmp.setX( tmp.x() + ( myResource->ThemeSize >> 1 ) );
|
|
tmp.setY( tmp.y() + ( myResource->ThemeSize >> 1 ) );
|
|
}
|
|
return tmp;
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::position
|
|
//
|
|
///////////////////////////////////////
|
|
int board_2d::position( const TQPoint &_point )
|
|
{
|
|
int file, rank;
|
|
int themeSize = myResource->ThemeSize;
|
|
TQPoint point( _point );
|
|
|
|
if( myResource->ThemeBorder )
|
|
{
|
|
point.setX( point.x() - ( themeSize >> 1 ) );
|
|
point.setY( point.y() - ( themeSize >> 1 ) );
|
|
}
|
|
if( !orientation )
|
|
{
|
|
file = point.x() / themeSize;
|
|
rank = 7 - ( point.y() / themeSize );
|
|
}
|
|
else
|
|
{
|
|
file = 7 - ( point.x() / themeSize );
|
|
rank = point.y() / themeSize;
|
|
}
|
|
return ( ( rank << 3 ) + file );
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::drawMove
|
|
//
|
|
///////////////////////////////////////
|
|
void board_2d::drawMove( const ChessMove &chessMove, const bool &reverse )
|
|
{
|
|
char fromPtr, toPtr, takenPtr(Null);
|
|
if( reverse )
|
|
{
|
|
fromPtr = ( chessMove.toRank << 3 ) + chessMove.toFile;
|
|
toPtr = ( chessMove.fromRank << 3 ) + chessMove.fromFile;
|
|
}
|
|
else
|
|
{
|
|
fromPtr = ( chessMove.fromRank << 3 ) + chessMove.fromFile;
|
|
toPtr = ( chessMove.toRank << 3 ) + chessMove.toFile;
|
|
}
|
|
|
|
/* Position where Man was taken != Target Position; ie. en passant */
|
|
if( chessMove.ManTaken != Null )
|
|
{
|
|
takenPtr = myLogic->Pointer( myLogic->chessman[ chessMove.ManTaken ].File, myLogic->chessman[ chessMove.ManTaken ].Rank );
|
|
}
|
|
|
|
/* Show Highlights */
|
|
if( myResource->OPTION_Show_Last_Move )
|
|
{
|
|
myLogic->current[ fromPtr ].Note = NOTE_MOVE;
|
|
if( chessMove.ManTaken != Null )
|
|
{
|
|
myLogic->current[ toPtr ].Note = NOTE_ATTACK;
|
|
}
|
|
else
|
|
{
|
|
myLogic->current[ toPtr ].Note = NOTE_MOVE;
|
|
}
|
|
}
|
|
|
|
/* Show Animation */
|
|
if( myResource->OPTION_Animate_Moves && !lastMoveWasDrag && isVisible() )
|
|
{
|
|
TQTimer::singleShot( 0, this, TQT_SLOT( updateSprites() ) );
|
|
sprite *spritePtr = new sprite;
|
|
spritePtr->Steps = 1;
|
|
spritePtr->Restore = FALSE;
|
|
spritePtr->POSITION_Origin = fromPtr;
|
|
spritePtr->POSITION_Destination = toPtr;
|
|
spritePtr->POSITION_TargetTaken = takenPtr;
|
|
if( !reverse )
|
|
{
|
|
spritePtr->POINT_Origin = coords( chessMove.fromRank, chessMove.fromFile );
|
|
spritePtr->POINT_Destination = coords( chessMove.toRank, chessMove.toFile );
|
|
spritePtr->PIXMAP_Sprite = getChessman( spritePtr->POSITION_Destination );
|
|
}
|
|
else
|
|
{
|
|
spritePtr->POINT_Origin = coords( chessMove.toRank, chessMove.toFile );
|
|
spritePtr->POINT_Destination = coords( chessMove.fromRank, chessMove.fromFile );
|
|
spritePtr->PIXMAP_Sprite = getChessman( spritePtr->POSITION_Origin );
|
|
}
|
|
spritePtr->POINT_Current = spritePtr->POINT_Origin;
|
|
spritePtr->PIXMAP_FlipFrame.resize( spritePtr->PIXMAP_Sprite.size() );
|
|
sprites.append( spritePtr );
|
|
}
|
|
else
|
|
{
|
|
/* Draw this position only if we're not animating */
|
|
drawPosition( toPtr );
|
|
if( takenPtr != Null )
|
|
{
|
|
drawPosition( takenPtr );
|
|
}
|
|
}
|
|
/* Draw the originating position */
|
|
drawPosition( fromPtr );
|
|
|
|
if( TQString( chessMove.SAN ).contains( "o-o", FALSE ) )
|
|
{
|
|
/* This is a castle */
|
|
ChessMove newMove;
|
|
strcpy( newMove.SAN, TQString( "no" ).latin1() );
|
|
newMove.fromRank = chessMove.fromRank;
|
|
newMove.toRank = chessMove.toRank;
|
|
newMove.ManTaken = Null;
|
|
if( TQString( chessMove.SAN ).contains( "o-o-o", FALSE ) )
|
|
{
|
|
/* Queenside */
|
|
newMove.fromFile = 0;
|
|
newMove.toFile = 3;
|
|
}
|
|
else
|
|
{
|
|
/* Kingside */
|
|
newMove.fromFile = 7;
|
|
newMove.toFile = 5;
|
|
}
|
|
drawMove( newMove, reverse );
|
|
}
|
|
lastMoveWasDrag = FALSE;
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::resizeBoard( TQT_SLOT )
|
|
//
|
|
///////////////////////////////////////
|
|
void board_2d::resizeBoard( void )
|
|
{
|
|
int size = 8 + ( 1 * ( myResource->ThemeBorder == TRUE ) );
|
|
init = FALSE;
|
|
|
|
/* Resize myself */
|
|
myself.resize( myResource->ThemeSize * size, myResource->ThemeSize * size);
|
|
myself.fill();
|
|
|
|
/* Finish up */
|
|
setFixedSize( myResource->ThemeSize * size, myResource->ThemeSize * size);
|
|
redrawAll();
|
|
|
|
int inverseSize = IMAGE_MAX - myResource->ThemeSize;
|
|
MAX_STEPS = ( ( inverseSize * inverseSize ) / IMAGE_MAX ) + 7;
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::redrawAll
|
|
//
|
|
///////////////////////////////////////
|
|
void board_2d::redrawAll( void )
|
|
{
|
|
register char tmp(0);
|
|
|
|
if( init )
|
|
return;
|
|
|
|
/* Set Qt::Orientation */
|
|
orientation = myResource->OPTION_Board_Orientation;
|
|
if( localArmy != WHITE )
|
|
orientation = !orientation;
|
|
if( flip )
|
|
orientation = !orientation;
|
|
|
|
/* Set Border */
|
|
if( myResource->ThemeBorder )
|
|
{
|
|
if( orientation )
|
|
{
|
|
TQWMatrix matrix;
|
|
matrix.rotate( 180.0 );
|
|
myself = cache->Border.xForm( matrix );
|
|
}
|
|
else
|
|
myself = cache->Border;
|
|
}
|
|
|
|
/* Redraw All Positions */
|
|
while( tmp < 64 )
|
|
drawPosition( tmp++ );
|
|
redrawLights();
|
|
|
|
/* Make sure everything is repainted */
|
|
updateX1 = updateY1 = 0;
|
|
updateX2 = updateY2 = IMAGE_MAX * 9;
|
|
|
|
commit();
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::redrawLights
|
|
//
|
|
///////////////////////////////////////
|
|
void board_2d::redrawLights( void )
|
|
{
|
|
int half, four;
|
|
TQPoint black, white;
|
|
if( myResource->ThemeBorder )
|
|
{
|
|
half = myResource->ThemeSize >> 1;
|
|
four = myResource->ThemeSize << 2;
|
|
if( !orientation )
|
|
{
|
|
black.setX( 0 );
|
|
black.setY( four );
|
|
white.setX( 0 );
|
|
white.setY( four + half );
|
|
}
|
|
else
|
|
{
|
|
black.setX( myself.width() - half );
|
|
black.setY( four + half );
|
|
white.setX( myself.width() - half );
|
|
white.setY( four );
|
|
}
|
|
if( myLogic->OnMove != WHITE )
|
|
{
|
|
myBlit( black, TQT_TQPAINTDEVICE(&cache->BorderLightOn), cache->BorderLightOn.rect() );
|
|
myBlit( white, TQT_TQPAINTDEVICE(&cache->BorderLightOff), cache->BorderLightOff.rect() );
|
|
}
|
|
else
|
|
{
|
|
myBlit( black, TQT_TQPAINTDEVICE(&cache->BorderLightOff), cache->BorderLightOff.rect() );
|
|
myBlit( white, TQT_TQPAINTDEVICE(&cache->BorderLightOn), cache->BorderLightOn.rect() );
|
|
}
|
|
}
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::drawPosition
|
|
//
|
|
///////////////////////////////////////
|
|
void board_2d::drawPosition( const int &pos )
|
|
{
|
|
int rank = pos >> 3;
|
|
int file = pos % 8;
|
|
TQPixmap buffer;
|
|
TQString cacheName = TQString::number( myResource->ThemeSize );
|
|
TQImage tempImage;
|
|
|
|
if( ( pos < 0 ) || ( pos > 63 ) ) return;
|
|
/*
|
|
Build the cache ref name
|
|
*/
|
|
if( color( rank, file ) )
|
|
cacheName += "L";
|
|
else
|
|
cacheName += "D";
|
|
if( !paused )
|
|
{
|
|
switch( myLogic->current[pos].Note )
|
|
{
|
|
case NOTE_SELECT:
|
|
case NOTE_HIGHLIGHT:
|
|
cacheName += "S";
|
|
break;
|
|
case NOTE_MOVE:
|
|
case NOTE_CASTLE:
|
|
case NOTE_PAWN_DOUBLE:
|
|
cacheName += "M";
|
|
break;
|
|
case NOTE_ATTACK:
|
|
case NOTE_ENPASSANT:
|
|
cacheName += "A";
|
|
break;
|
|
default:
|
|
cacheName += " ";
|
|
}
|
|
if( ( myLogic->current[pos].ManPtr != Null ) && ( !isSprite( pos ) ) )
|
|
{
|
|
if( myLogic->chessman[ myLogic->current[pos].ManPtr ].Army == WHITE )
|
|
cacheName += "W";
|
|
else
|
|
cacheName += "B";
|
|
switch( myLogic->chessman[myLogic->current[pos].ManPtr].Type )
|
|
{
|
|
case King:
|
|
cacheName += "K";
|
|
break;
|
|
case Queen:
|
|
cacheName += "Q";
|
|
break;
|
|
case Bishop:
|
|
cacheName += "B";
|
|
break;
|
|
case Knight:
|
|
cacheName += "N";
|
|
break;
|
|
case Rook:
|
|
cacheName += "R";
|
|
break;
|
|
case Pawn:
|
|
cacheName += "P";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if( ( pos == premoveFrom ) || ( pos == premoveTo ) )
|
|
cacheName += "t"; // The means it's transparent
|
|
}
|
|
}
|
|
else
|
|
cacheName += " ";
|
|
if( cache->find( cacheName, buffer ) )
|
|
{
|
|
/*
|
|
Cache Hit... no need to redraw
|
|
*/
|
|
if( myResource->OPTION_Show_Coord )
|
|
drawCoords( &buffer, pos );
|
|
myBlit( coords( rank, file ), TQT_TQPAINTDEVICE(&buffer), buffer.rect() );
|
|
return;
|
|
}
|
|
|
|
/*
|
|
Cache miss
|
|
Draw the pixmap
|
|
*/
|
|
if( color( rank, file ) )
|
|
buffer = cache->SquareLight;
|
|
else
|
|
buffer = cache->SquareDark;
|
|
|
|
switch( myLogic->current[pos].Note )
|
|
{
|
|
case NOTE_HIGHLIGHT: // Fall Through
|
|
case NOTE_SELECT:
|
|
bitBlt( TQT_TQPAINTDEVICE(&buffer), 0, 0, TQT_TQPAINTDEVICE(&cache->HighlightSelect), 0, 0, -1, -1, TQt::CopyROP, FALSE);
|
|
break;
|
|
case NOTE_MOVE: // Fall Through
|
|
case NOTE_CASTLE: // Fall Through
|
|
case NOTE_PAWN_DOUBLE:
|
|
bitBlt( TQT_TQPAINTDEVICE(&buffer), 0, 0, TQT_TQPAINTDEVICE(&cache->HighlightMove), 0, 0, -1, -1, TQt::CopyROP, FALSE);
|
|
break;
|
|
case NOTE_ATTACK: // Fall Through
|
|
case NOTE_ENPASSANT:
|
|
bitBlt( TQT_TQPAINTDEVICE(&buffer), 0, 0, TQT_TQPAINTDEVICE(&cache->HighlightAttack), 0, 0, -1, -1, TQt::CopyROP, FALSE);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if( !isSprite(pos) )
|
|
{
|
|
TQPixmap chessman = getChessman( pos );
|
|
bitBlt( TQT_TQPAINTDEVICE(&buffer), 0, 0, TQT_TQPAINTDEVICE(&chessman), 0, 0, -1, -1, TQt::CopyROP, FALSE);
|
|
}
|
|
/* Now add this pixmap to the cache */
|
|
cache->add( cacheName, buffer );
|
|
/* */
|
|
if( myResource->OPTION_Show_Coord )
|
|
drawCoords( &buffer, pos );
|
|
myBlit( coords( rank, file ), TQT_TQPAINTDEVICE(&buffer), buffer.rect() );
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::drawCoords
|
|
//
|
|
///////////////////////////////////////
|
|
void board_2d::drawCoords( TQPixmap *pic, const int &pos )
|
|
{
|
|
TQPainter painter;
|
|
TQString letter;
|
|
int themeSize = myResource->ThemeSize - 4;
|
|
int targetRank, targetFile;
|
|
|
|
if( orientation == 0 )
|
|
{
|
|
targetRank = 0;
|
|
targetFile = 0;
|
|
}
|
|
else
|
|
{
|
|
targetRank = 7;
|
|
targetFile = 7;
|
|
}
|
|
/* Draw Rank */
|
|
if( ( pos >> 3 ) == targetRank )
|
|
{
|
|
letter = TQString( TQString("abcdefgh").at( pos % 8 ) );
|
|
painter.begin( pic );
|
|
painter.setFont( myResource->FONT_Standard );
|
|
painter.setPen( myResource->COLOR_Notation_Shadow );
|
|
painter.drawText( 3, 3, themeSize, themeSize,
|
|
TQt::AlignRight | TQt::AlignBottom, letter );
|
|
painter.setPen( myResource->COLOR_Notation );
|
|
painter.drawText( 2, 2, themeSize, themeSize,
|
|
TQt::AlignRight | TQt::AlignBottom, letter );
|
|
painter.end();
|
|
}
|
|
/* Draw File */
|
|
if( ( pos % 8 ) == targetFile )
|
|
{
|
|
letter = TQString( TQString("12345678").at( pos >> 3 ) );
|
|
painter.begin( pic );
|
|
painter.setFont( myResource->FONT_Standard );
|
|
painter.setPen( myResource->COLOR_Black );
|
|
painter.drawText( 3, 3, themeSize, themeSize,
|
|
TQt::AlignLeft | TQt::AlignTop, letter );
|
|
painter.setPen( myResource->COLOR_White );
|
|
painter.drawText( 2, 2, themeSize, themeSize,
|
|
TQt::AlignLeft | TQt::AlignTop, letter );
|
|
painter.end();
|
|
}
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::mouseReleaseEvent
|
|
//
|
|
///////////////////////////////////////
|
|
void board_2d::mouseReleaseEvent( TQMouseEvent *event )
|
|
{
|
|
event->accept();
|
|
|
|
if( DragSprite != NULL )
|
|
{
|
|
/* Destroy any sprites being dragged */
|
|
int tmp = DragSprite->POSITION_Origin;
|
|
myBlit( DragSprite->POINT_LastUpdate,
|
|
TQT_TQPAINTDEVICE(&DragSprite->PIXMAP_FlipFrame),
|
|
DragSprite->PIXMAP_FlipFrame.rect() );
|
|
sprites.removeRef( DragSprite );
|
|
DragSprite = NULL;
|
|
drawPosition( tmp );
|
|
commit();
|
|
lastMoveWasDrag = TRUE;
|
|
}
|
|
|
|
if(event->button() == Qt::LeftButton)
|
|
{
|
|
emit leftClick( position( event->pos() ) );
|
|
}
|
|
if(event->button() == Qt::RightButton)
|
|
{
|
|
emit rightClick( position( event->pos() ) );
|
|
}
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::mousePressEvent
|
|
//
|
|
///////////////////////////////////////
|
|
void board_2d::mousePressEvent( TQMouseEvent *event )
|
|
{
|
|
pressPoint = event->pos();
|
|
event->accept();
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::mouseMoveEvent
|
|
//
|
|
///////////////////////////////////////
|
|
void board_2d::mouseMoveEvent( TQMouseEvent *event )
|
|
{
|
|
event->accept();
|
|
if( DragSprite == NULL )
|
|
{
|
|
if( event->state() & Qt::LeftButton )
|
|
{
|
|
if( abs( pressPoint.x() - event->pos().x() ) + abs( pressPoint.y() - event->pos().y() ) > 6 )
|
|
{
|
|
/* Begin Dragging a piece */
|
|
DragSprite = new sprite;
|
|
sprites.append( DragSprite );
|
|
DragSprite->POINT_Origin = pressPoint;
|
|
DragSprite->POSITION_Origin = position( pressPoint );
|
|
emit leftClick( DragSprite->POSITION_Origin ); // Tell match that we just clicked on this piece
|
|
|
|
if( myLogic->current[ DragSprite->POSITION_Origin ].Note != NOTE_SELECT )
|
|
{
|
|
/* The selection didn't take.. back out. */
|
|
sprites.removeRef( DragSprite );
|
|
DragSprite = NULL;
|
|
drawPosition( position( pressPoint ) );
|
|
commit();
|
|
return;
|
|
}
|
|
|
|
/* Get the piece image and store it in dragPix */
|
|
DragSprite->PIXMAP_Sprite = getChessman( DragSprite->POSITION_Origin );
|
|
DragSprite->PIXMAP_FlipFrame.resize( DragSprite->PIXMAP_Sprite.size() );
|
|
DragSprite->Restore = FALSE;
|
|
}
|
|
else
|
|
/* Not enough dragging */
|
|
return;
|
|
} // End ( event->state() & Qt::LeftButton )
|
|
else
|
|
return; /* No dragging. Most events should end up here */
|
|
}
|
|
|
|
int halfSize = myResource->ThemeSize >> 1;
|
|
DragSprite->POINT_Current.setX( event->x() - halfSize );
|
|
DragSprite->POINT_Current.setY( event->y() - halfSize );
|
|
commit();
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::getChessman
|
|
//
|
|
///////////////////////////////////////
|
|
TQPixmap board_2d::getChessman( const int &pos )
|
|
{
|
|
TQPixmap tmp;
|
|
register char type, army;
|
|
|
|
if( pos == premoveTo )
|
|
{
|
|
type = myLogic->chessman[myLogic->current[premoveFrom].ManPtr].Type;
|
|
army = myLogic->chessman[myLogic->current[premoveFrom].ManPtr].Army;
|
|
}
|
|
else
|
|
{
|
|
type = myLogic->chessman[myLogic->current[pos].ManPtr].Type;
|
|
army = myLogic->chessman[myLogic->current[pos].ManPtr].Army;
|
|
}
|
|
switch( type )
|
|
{
|
|
case King:
|
|
if( army == WHITE )
|
|
tmp = cache->WhiteKing;
|
|
else
|
|
tmp = cache->BlackKing;
|
|
break;
|
|
case Queen:
|
|
if( army == WHITE )
|
|
tmp = cache->WhiteQueen;
|
|
else
|
|
tmp = cache->BlackQueen;
|
|
break;
|
|
case Bishop:
|
|
if( army == WHITE )
|
|
tmp = cache->WhiteBishop;
|
|
else
|
|
tmp = cache->BlackBishop;
|
|
break;
|
|
case Knight:
|
|
if( army == WHITE )
|
|
tmp = cache->WhiteKnight;
|
|
else
|
|
tmp = cache->BlackKnight;
|
|
break;
|
|
case Rook:
|
|
if( army == WHITE )
|
|
tmp = cache->WhiteRook;
|
|
else
|
|
tmp = cache->BlackRook;
|
|
break;
|
|
case Pawn:
|
|
if( army == WHITE )
|
|
tmp = cache->WhitePawn;
|
|
else
|
|
tmp = cache->BlackPawn;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if( ( pos == premoveFrom ) || ( pos == premoveTo ) )
|
|
{
|
|
TDEIconEffect::semiTransparent( tmp );
|
|
}
|
|
return tmp;
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::setPremovePositions
|
|
//
|
|
///////////////////////////////////////
|
|
void board_2d::setPremovePositions( const int &posF, const int &posT )
|
|
{
|
|
premoveFrom = posF;
|
|
premoveTo = posT;
|
|
if( ( posF != Null ) && ( posT != Null ) )
|
|
{
|
|
myLogic->current[posF].Note = NOTE_NONE;
|
|
myLogic->current[posT].Note = NOTE_NONE;
|
|
drawPosition( posF );
|
|
drawPosition( posT );
|
|
commit();
|
|
}
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::commit
|
|
//
|
|
///////////////////////////////////////
|
|
void board_2d::commit( void )
|
|
{
|
|
drawSprites();
|
|
bitBlt( this, updateX1, updateY1, &myself, updateX1, updateY1, updateX2, updateY2, TQt::CopyROP );
|
|
updateX1 = updateY1 = 4000;
|
|
updateX2 = updateY2 = -4000;
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::paintEvent
|
|
//
|
|
///////////////////////////////////////
|
|
void board_2d::paintEvent( TQPaintEvent *event )
|
|
{
|
|
/* Paint the Widget */
|
|
bitBlt( this, event->rect().topLeft(), &myself, event->rect(), TQt::CopyROP );
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::drawSprites
|
|
//
|
|
///////////////////////////////////////
|
|
void board_2d::drawSprites( void )
|
|
{
|
|
int index;
|
|
sprite *spritePtr;
|
|
|
|
/* Remove all sprites from the pixmap */
|
|
for( index = (signed int)sprites.count() - 1; index > -1; index-- )
|
|
{
|
|
spritePtr = sprites.at(index);
|
|
if( spritePtr->Restore == FALSE )
|
|
{
|
|
spritePtr->Restore = TRUE;
|
|
}
|
|
else
|
|
{
|
|
myBlit( spritePtr->POINT_LastUpdate,
|
|
TQT_TQPAINTDEVICE(&spritePtr->PIXMAP_FlipFrame),
|
|
spritePtr->PIXMAP_FlipFrame.rect() );
|
|
}
|
|
}
|
|
/* Redraw all sprites */
|
|
for( index = 0; index < (signed int)sprites.count(); index++ )
|
|
{
|
|
spritePtr = sprites.at(index);
|
|
|
|
if( ( spritePtr == DragSprite ) || ( spritePtr->Steps < MAX_STEPS ) )
|
|
{
|
|
/* Redraw Sprite */
|
|
bitBlt( &spritePtr->PIXMAP_FlipFrame,
|
|
0,
|
|
0,
|
|
&myself,
|
|
spritePtr->POINT_Current.x(),
|
|
spritePtr->POINT_Current.y(),
|
|
spritePtr->PIXMAP_FlipFrame.width(),
|
|
spritePtr->PIXMAP_FlipFrame.height(),
|
|
TQt::CopyROP );
|
|
myBlit( spritePtr->POINT_Current,
|
|
TQT_TQPAINTDEVICE(&spritePtr->PIXMAP_Sprite),
|
|
spritePtr->PIXMAP_Sprite.rect() );
|
|
spritePtr->POINT_LastUpdate = spritePtr->POINT_Current;
|
|
}
|
|
else
|
|
{
|
|
/* Animation finished */
|
|
int origin = spritePtr->POSITION_Origin;
|
|
int destination = spritePtr->POSITION_Destination;
|
|
int target = spritePtr->POSITION_TargetTaken;
|
|
sprites.removeRef( spritePtr );
|
|
drawPosition( origin );
|
|
drawPosition( destination );
|
|
drawPosition( target );
|
|
index = -1;
|
|
}
|
|
}
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::updateSprites
|
|
//
|
|
///////////////////////////////////////
|
|
void board_2d::updateSprites( void )
|
|
{
|
|
if( myResource->OPTION_Animate_Moves )
|
|
{
|
|
for( int index = 0; index < (signed int)sprites.count(); index++ )
|
|
{
|
|
sprite *spritePtr = sprites.at( index );
|
|
if( spritePtr == DragSprite )
|
|
continue;
|
|
|
|
TQTimer::singleShot( 0, this, TQT_SLOT( updateSprites() ) );
|
|
if( spritePtr->Steps < MAX_STEPS )
|
|
{
|
|
double factor = ( 1.0 / (double)MAX_STEPS ) * (double)spritePtr->Steps;
|
|
int newX = (int)( ( spritePtr->POINT_Destination.x() - spritePtr->POINT_Origin.x() ) * factor );
|
|
int newY = (int)( ( spritePtr->POINT_Destination.y() - spritePtr->POINT_Origin.y() ) * factor );
|
|
spritePtr->POINT_Current = spritePtr->POINT_Origin + TQPoint( newX, newY );
|
|
spritePtr->Steps += sprites.count();
|
|
}
|
|
}
|
|
commit();
|
|
}
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::isSprite
|
|
//
|
|
///////////////////////////////////////
|
|
bool board_2d::isSprite( const int &pos )
|
|
{
|
|
for( unsigned int index = 0; index < sprites.count(); index++ )
|
|
{
|
|
sprite *tmpSprite = sprites.at( index );
|
|
if( tmpSprite->POSITION_Origin == pos )
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
///////////////////////////////////////
|
|
//
|
|
// board_2d::myBlit
|
|
//
|
|
///////////////////////////////////////
|
|
void board_2d::myBlit( const TQPoint &dp, const TQPaintDevice *src, const TQRect &sr )
|
|
{
|
|
bitBlt( &myself, dp.x(), dp.y(), src, sr.x(), sr.y(), sr.width(), sr.height(), TQt::CopyROP );
|
|
if( dp.x() < updateX1 )
|
|
updateX1 = dp.x();
|
|
if( dp.y() < updateY1 )
|
|
updateY1 = dp.y();
|
|
if( dp.x() + sr.width() > updateX2 )
|
|
updateX2 = dp.x() + sr.width();
|
|
if( dp.y() + sr.height() > updateX2 )
|
|
updateX2 = dp.y() + sr.height();
|
|
}
|