1 #ifndef _objects_h 2 #define _objects_h 3 4 /****************************************************************************** 5 6 The functionality of the puzzle tiles was created and tested step by step by 7 implementing a linear class with each subclass adding a few special features 8 to the full object. 9 10 PieceFrame - corner, edge and pin-data of the piece including polygon-spline 11 Vec2List *vl 12 TwinPieceFrame - intermediate class to store the current page of the tile 13 RotatedFrame - position-data including 14 window-position, upward-angle and rotated polygin spline 15 Vec2 winpos 16 Real windir 17 Vec2List *tvl 18 FlipFrame - intermediate class to control the flip animation with the help 19 of a transformation matrix 20 Mat2 *itm 21 Vec2List *ftvl 22 BitmapPiece - pixmap with mask of the rotated Piece 23 Pixmap tilemask 24 PixmapPiece - pixmap with Puzzle-Image of the rotated Piece 25 Pixmap tilemap 26 ShadowPiece - pixmap with Puzzle-Image and ShadowFrame of the rotated Piece 27 Pixmap shadowmask 28 Pixmap shadowmap 29 WindowPiece - class to control creation of local windows for each tile 30 Window swin 31 PieceObject - object subclass to be stack-controlled 32 DBPieceObject - double buffered moves and turns 33 34 ******************************************************************************/ 35 36 #ifndef _stack_h 37 # include "stack.H" 38 #endif 39 #ifndef _vec2_h 40 # include "vec2.h" 41 #endif 42 #ifndef _vec2list_h 43 # include "vec2list.h" 44 #endif 45 #ifndef _mat2_h 46 # include "mat2.h" 47 #endif 48 49 // =========================================================================== 50 51 // ************** 52 // * PieceFrame * 53 // ************** 54 // 55 // The PieceFrame class containes the information about the boundary corners of 56 // an image in the original puzzle picture. Therefore the 4 corners are stored 57 // in that class (messured relative to the center of the object). 58 // Additionally the information, how the splines of the 4 pins are located, 59 // is stored in that class. 60 // 61 // The data is set up by Puzzle::Init 62 // 63 // All the edge information is finally combined into a point-list of a 64 // polygon, that surrounds the whole tile. 65 66 class PieceFrameSetup { 67 public: 68 PieceFrameSetup(); 69 virtual ~PieceFrameSetup(); 70 71 void Init( const Vec2 &tl, const Vec2 &tr, const Vec2 &br, const Vec2 &bl ); SetPin(int i,int l,const Real & pd)72 void SetPin( int i, int l, const Real &pd ) { left[i]=l; pin[i]=pd; } 73 74 protected: 75 76 #define HalfSplineLen 10 77 #define MaxSplineLen (8*HalfSplineLen+5) 78 79 protected: 80 Vec2 v[4]; // coordinates of corners (offset to center) 81 char left[4]; // flag, wether the pin is left ro right 82 Real pin[4]; // offset of pin (-1 .. 1) 83 Vec2 center; // center of piece in origin 84 85 static double spx[HalfSplineLen]; // Spline-Position for any Pin 86 static double spy[HalfSplineLen]; 87 88 friend class PieceFrame; 89 }; 90 91 // =========================================================================== 92 93 class PieceFrame{ 94 public: 95 PieceFrame(); 96 virtual ~PieceFrame(); 97 98 const Vec2List &Init( const PieceFrameSetup &pfs ); 99 GetPolyLine()100 const Vec2List &GetPolyLine() { return *vl; } Center()101 const Vec2 &Center() { return center; } 102 103 virtual void PositionChanged(); 104 virtual void DirectionChanged(); 105 106 protected: 107 Vec2 center; 108 Vec2List *vl; // non-rotated polyline with pins and corners 109 same_point(int j,class PieceFrame * obj,int i)110 int same_point(int j,class PieceFrame *obj,int i) { 111 Vec2 dist( ((*obj->vl)[i]+obj->center) - ((*vl)[j]+center) ); 112 return (fabs(dist.X())<EPS && fabs(dist.Y())<EPS); 113 } 114 int join_count; 115 116 friend class RotatedFrame; 117 friend class Puzzle; 118 }; 119 120 // =========================================================================== 121 122 class TwinPieceFrame : public PieceFrame { 123 public: 124 TwinPieceFrame(); 125 virtual ~TwinPieceFrame(); 126 127 virtual void FlipPage(); 128 129 protected: 130 int page; 131 }; 132 133 // =========================================================================== 134 135 // **************** 136 // * RotatedFrame * 137 // **************** 138 // 139 // The PieceFrame gets extended by a window position and and upward angle, 140 // through which it is possible to compute a rotated list of the polygon points 141 // 142 // The public routines SetDir and SetPos can be used for moving the tile to 143 // a new position, in which case the virtual routines lead to an update of 144 // the subclasses. 145 146 class RotatedFrame : public TwinPieceFrame { 147 public: 148 RotatedFrame(); 149 virtual ~RotatedFrame(); 150 151 void Init( const PieceFrameSetup &pfs ); 152 SetPos(const Vec2 & p)153 void SetPos( const Vec2 &p ) { winpos=p; PositionChanged(); } GetPos()154 const Vec2 &GetPos() { return winpos; } SetDir(const Real & d)155 void SetDir( const Real &d ) { 156 windir=fmod(d+360.0,360.0); 157 DirectionChanged(); 158 } AdjustDir()159 int AdjustDir() { 160 Real help=fmod(windir+20.0,90); 161 if ( help>17 && help<23 162 ||(join_count>minadjustcount && help<40 && help!=20.0)) { 163 SetDir(windir+20-help); 164 return 1; 165 } 166 else return 0; 167 } GetDir()168 Real GetDir() { return windir; } 169 void Redraw(); 170 171 virtual void PositionChanged(); 172 virtual void DirectionChanged(); GetTPolyLine()173 Vec2List &GetTPolyLine() { return *tvl; } 174 175 int CheckForJoin( class RotatedFrame *obj ); 176 int FindStartForJoin( class PieceFrame *obj ); 177 int DoJoin( class RotatedFrame *obj, int i, int swap=0 ); 178 179 protected: 180 Vec2 winpos; // Window-Position 181 Real windir; // upward angle of tile; 182 Vec2List *tvl; // pointlist of turned points 183 184 }; 185 186 // =========================================================================== 187 188 class FlipFrame : public RotatedFrame { 189 public: 190 FlipFrame(); 191 virtual ~FlipFrame(); 192 193 Vec2List &GetTPolyLine(); 194 195 void StartFlip( const Real &angle ); 196 void SetFlip( const Real ¤t ); 197 void StopFlip(); 198 199 protected: 200 Real mangle; // flip angle 201 Vec2List *ftvl; 202 Mat2 *itm; 203 }; 204 205 // =========================================================================== 206 207 class BitmapPiece : public FlipFrame { 208 public: 209 BitmapPiece(); 210 virtual ~BitmapPiece(); 211 212 void DropBitmap(); 213 virtual void PositionChanged(); 214 virtual void DirectionChanged(); GetBitmap()215 Pixmap GetBitmap() { return tilemask; } 216 void Redraw(); 217 218 protected: 219 int winx, winy; // TopLeft in window 220 int offx, offy; // TopLeft corner-offset from center 221 int width, height; // size of bitmap 222 Pixmap tilemask; // the bitmap itself 223 224 static GC gcb; // GC to draw in Bitmaps 225 226 friend class DBPieceObject; 227 }; 228 229 // =========================================================================== 230 231 class PixmapPiece : public BitmapPiece { 232 public: 233 PixmapPiece(); 234 virtual ~PixmapPiece(); 235 236 void DropPixmap(); 237 virtual void DirectionChanged(); GetPixmap()238 Pixmap GetPixmap() { return tilemap; } 239 void Redraw(); 240 241 protected: 242 void CreateTilemap8(); 243 void CreateTilemap16(); 244 void CreateTilemap24(); 245 void CreateTilemap32(); 246 247 Pixmap tilemap; 248 static GC gcp; 249 }; 250 251 // =========================================================================== 252 253 class ShadowedPiece : public PixmapPiece { 254 public: 255 ShadowedPiece(); 256 virtual ~ShadowedPiece(); 257 258 void DropPixmap(); 259 virtual void DirectionChanged(); GetPixmap()260 Pixmap GetPixmap() { return shadowmap; } 261 void Redraw(); 262 ShadowSize()263 int ShadowSize() { return shadow_size; } 264 265 int IsInside( int x, int y ); 266 267 protected: 268 Pixmap shadowmask; 269 Pixmap shadowmap; 270 int swidth,sheight; 271 272 friend class DBPieceObject; 273 }; 274 275 // =========================================================================== 276 277 class WindowPiece : public ShadowedPiece { 278 public: 279 WindowPiece(); 280 virtual ~WindowPiece(); 281 282 virtual void PositionChanged(); 283 virtual void DirectionChanged(); 284 void Redraw(); 285 286 protected: 287 void CreateWindow(); 288 Window swin; 289 290 friend class WindowObjectStack; 291 }; 292 293 // =========================================================================== 294 295 class PieceObject : public WindowPiece, public Object { 296 public: 297 PieceObject(); 298 virtual ~PieceObject(); 299 300 virtual int Intersects(int x,int y,int width,int height); 301 virtual int IsInside(int x,int y); 302 virtual void ExposeRegion(int x,int y,int width,int height); 303 virtual void ExposeWindowRegion(Window w, int x,int y,int width,int height); 304 305 virtual void PanView( int offx, int offy ); 306 virtual void ZoomView( int midx, int midy, int chg ); 307 308 private: 309 }; 310 311 // =========================================================================== 312 313 class DBPieceObject : public PieceObject { 314 public: 315 DBPieceObject(); 316 virtual ~DBPieceObject(); 317 Move(const Vec2 & pos)318 void Move( const Vec2 &pos ) 319 { StoreExtent(); SetPos(pos); UpdateExtent(); }; MoveTurn(const Vec2 & pos,const Real & d)320 void MoveTurn( const Vec2 &pos, const Real &d ) 321 { StoreExtent(); SetPos(pos); SetDir(d); UpdateExtent(); }; Turn(const Real & d)322 void Turn( const Real &d ) 323 { StoreExtent(); SetDir(d); UpdateExtent(); }; 324 void FlipOver( const Vec2 &pos ); // animated flip 325 void TurnOver( const Real &d ); // animated turn AdjustDirection()326 void AdjustDirection() 327 { StoreExtent(); if (PieceObject::AdjustDir()) UpdateExtent(); }; 328 329 int JoinExtent( int *x1, int *y1, int *x2, int *y2 ); 330 int GetExtent( int *x1, int *y1, int *x2, int *y2 ); 331 void StoreExtent(); 332 void JoinExtent(); 333 void UpdateExtent(); 334 335 private: 336 static int x1,y1,x2,y2; 337 }; 338 339 // =========================================================================== 340 341 class MoveablePiece : public DBPieceObject { 342 public: 343 MoveablePiece(); 344 virtual ~MoveablePiece(); 345 346 virtual void DispatchPress( XButtonEvent * /*xbutton*/ ); 347 virtual void DispatchRelease( XButtonEvent * /*xbutton*/ ); 348 virtual void DispatchMotion( XMotionEvent * /*xmotion*/ ); 349 350 private: 351 static int turnflag; // -1 = left, 0 = no turn, 1 = right 352 // -2/2 = around center 353 static Time start_time; 354 static Real start_angle; 355 static Vec2 start; 356 static Vec2 poffset; 357 static Real poffset_len; 358 }; 359 360 // =========================================================================== 361 362 class Piece : public MoveablePiece { 363 }; 364 365 #endif 366