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 &current );
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