File: objects.H

package info (click to toggle)
xjig 2.4-14.1
  • links: PTS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 892 kB
  • sloc: cpp: 10,177; makefile: 1,142; perl: 23
file content (364 lines) | stat: -rw-r--r-- 9,692 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
#ifndef _objects_h
#define _objects_h

/******************************************************************************

  The functionality of the puzzle tiles was created and tested step by step by
  implementing a linear class with each subclass adding a few special features
  to the full object.

PieceFrame    - corner, edge and pin-data of the piece including polygon-spline
      Vec2List *vl
TwinPieceFrame - intermediate class to store the current page of the tile
RotatedFrame  - position-data including
                window-position, upward-angle and rotated polygin spline
      Vec2     winpos
      Real     windir
      Vec2List *tvl
FlipFrame     - intermediate class to control the flip animation with the help
                of a transformation matrix
      Mat2		*itm
      Vec2List *ftvl
BitmapPiece   - pixmap with mask of the rotated Piece
		Pixmap   tilemask
PixmapPiece   - pixmap with Puzzle-Image of the rotated Piece
		Pixmap   tilemap
ShadowPiece   - pixmap with Puzzle-Image and ShadowFrame of the rotated Piece
		Pixmap   shadowmask
		Pixmap   shadowmap
WindowPiece   - class to control creation of local windows for each tile
		Window	swin
PieceObject   - object subclass to be stack-controlled
DBPieceObject - double buffered moves and turns

 ******************************************************************************/

#ifndef _stack_h
#	include "stack.H"
#endif
#ifndef _vec2_h
#	include "vec2.h"
#endif
#ifndef _vec2list_h
#	include "vec2list.h"
#endif
#ifndef _mat2_h
#	include "mat2.h"
#endif

// ===========================================================================

// **************
// * PieceFrame *
// **************
//
// The PieceFrame class containes the information about the boundary corners of
// an image in the original puzzle picture. Therefore the 4 corners are stored
// in that class (messured relative to the center of the object).
// Additionally the information, how the splines of the 4 pins are located,
// is stored in that class.
//
// The data is set up by Puzzle::Init
//
// All the edge information is finally combined into a point-list of a
// polygon, that surrounds the whole tile.

class PieceFrameSetup {
	public:
		PieceFrameSetup();
		virtual ~PieceFrameSetup();

		void Init( const Vec2 &tl, const Vec2 &tr, const Vec2 &br, const Vec2 &bl );
		void SetPin( int i, int l, const Real &pd )	{ left[i]=l; pin[i]=pd; }

	protected:

#define	HalfSplineLen	10
#define	MaxSplineLen	(8*HalfSplineLen+5)

	protected:
		Vec2	v[4];				// coordinates of corners (offset to center)
		char	left[4];			// flag, wether the pin is left ro right
		Real	pin[4];			// offset of pin (-1 .. 1)
		Vec2	center;			// center of piece in origin

		static double spx[HalfSplineLen];	// Spline-Position for any Pin
		static double spy[HalfSplineLen];

friend class PieceFrame;
};

// ===========================================================================

class PieceFrame{
	public:
		PieceFrame();
		virtual ~PieceFrame();

		const Vec2List &Init( const PieceFrameSetup &pfs );

		const Vec2List &GetPolyLine()		{ return *vl; }
		const Vec2 &Center()					{ return center; }

		virtual void PositionChanged();
		virtual void DirectionChanged();

	protected:
		Vec2		center;
		Vec2List	*vl;			// non-rotated polyline with pins and corners

		int same_point(int j,class PieceFrame *obj,int i) {
			Vec2	dist( ((*obj->vl)[i]+obj->center) - ((*vl)[j]+center) );
			return (fabs(dist.X())<EPS && fabs(dist.Y())<EPS);
		}
		int	join_count;

	friend class RotatedFrame;
	friend class Puzzle;
};

// ===========================================================================

class TwinPieceFrame : public PieceFrame {
	public:
		TwinPieceFrame();
		virtual ~TwinPieceFrame();

		virtual void FlipPage();

	protected:
		int	page;
};

// ===========================================================================

// ****************
// * RotatedFrame *
// ****************
//
// The PieceFrame gets extended by a window position and and upward angle,
// through which it is possible to compute a rotated list of the polygon points
//
// The public routines SetDir and SetPos can be used for moving the tile to
// a new position, in which case the virtual routines lead to an update of
// the subclasses.

class RotatedFrame : public TwinPieceFrame {
	public:
		RotatedFrame();
		virtual ~RotatedFrame();

		void Init( const PieceFrameSetup &pfs );

		void SetPos( const Vec2 &p )	{ winpos=p; PositionChanged(); }
		const Vec2 &GetPos()				{ return winpos; }
		void SetDir( const Real &d )	{
			windir=fmod(d+360.0,360.0);
			DirectionChanged();
		}
		int AdjustDir() {
			Real	help=fmod(windir+20.0,90);
			if (	help>17 && help<23
				||(join_count>minadjustcount && help<40 && help!=20.0)) {
						SetDir(windir+20-help);
						return 1;
			}
			else	return 0;
		}
		Real GetDir()						{ return windir; }
		void Redraw();

		virtual void PositionChanged();
		virtual void DirectionChanged();
		Vec2List &GetTPolyLine()		{ return *tvl; }

		int CheckForJoin( class RotatedFrame *obj );
		int FindStartForJoin( class PieceFrame *obj );
		int DoJoin( class RotatedFrame *obj, int i, int swap=0 );

	protected:
		Vec2		winpos;			// Window-Position
		Real		windir;			// upward angle of tile;
		Vec2List	*tvl;				// pointlist of turned points

};

// ===========================================================================

class FlipFrame : public RotatedFrame {
	public:
		FlipFrame();
		virtual ~FlipFrame();

		Vec2List &GetTPolyLine();

		void StartFlip( const Real &angle );
		void SetFlip( const Real &current );
		void StopFlip();

	protected:
		Real		mangle;			// flip angle
		Vec2List	*ftvl;
		Mat2		*itm;
};

// ===========================================================================

class BitmapPiece : public FlipFrame {
	public:
		BitmapPiece();
		virtual ~BitmapPiece();

		void DropBitmap();
		virtual void PositionChanged();
		virtual void DirectionChanged();
		Pixmap GetBitmap()				{ return tilemask; }
		void Redraw();

	protected:
		int		winx, winy;			// TopLeft in window
		int		offx, offy;			// TopLeft corner-offset from center
		int		width, height;		// size of bitmap
		Pixmap	tilemask;			// the bitmap itself

		static GC gcb;					// GC to draw in Bitmaps

	friend class DBPieceObject;
};

// ===========================================================================

class PixmapPiece : public BitmapPiece {
	public:
		PixmapPiece();
		virtual ~PixmapPiece();

		void DropPixmap();
		virtual void DirectionChanged();
		Pixmap GetPixmap()				{ return tilemap; }
		void Redraw();

	protected:
		void CreateTilemap8();
		void CreateTilemap16();
		void CreateTilemap32();

		Pixmap	tilemap;
		static GC	gcp;
};

// ===========================================================================

class ShadowedPiece : public PixmapPiece {
	public:
		ShadowedPiece();
		virtual ~ShadowedPiece();

		void DropPixmap();
		virtual void DirectionChanged();
		Pixmap GetPixmap()				{ return shadowmap; }
		void Redraw();

		int ShadowSize()					{ return shadow_size; }

		int IsInside( int x, int y );

	protected:
		Pixmap	shadowmask;
		Pixmap	shadowmap;
		int		swidth,sheight;

	friend class DBPieceObject;
};

// ===========================================================================

class WindowPiece : public ShadowedPiece {
	public:
		WindowPiece();
		virtual ~WindowPiece();

		virtual void PositionChanged();
		virtual void DirectionChanged();
		void Redraw();

	protected:
		void CreateWindow();
		Window	swin;

	friend class WindowObjectStack;
};

// ===========================================================================

class PieceObject : public WindowPiece, public Object {
	public:
		PieceObject();
		virtual ~PieceObject();

		virtual int Intersects(int x,int y,int width,int height);
		virtual int IsInside(int x,int y);
		virtual void ExposeRegion(int x,int y,int width,int height);
		virtual void ExposeWindowRegion(Window w, int x,int y,int width,int height);

		virtual void PanView( int offx, int offy );
		virtual void ZoomView( int midx, int midy, int chg );

	private:
};

// ===========================================================================

class DBPieceObject : public PieceObject {
	public:
		DBPieceObject();
		virtual ~DBPieceObject();

		void Move( const Vec2 &pos )
			{ StoreExtent(); SetPos(pos);  UpdateExtent(); };
		void MoveTurn( const Vec2 &pos, const Real &d )
			{ StoreExtent(); SetPos(pos); SetDir(d); UpdateExtent(); };
		void Turn( const Real &d )
			{ StoreExtent(); SetDir(d); UpdateExtent(); };
		void FlipOver( const Vec2 &pos );		// animated flip
		void TurnOver( const Real &d );			// animated turn
		void AdjustDirection()
			{ StoreExtent(); if (PieceObject::AdjustDir()) UpdateExtent(); };

		int JoinExtent( int *x1, int *y1, int *x2, int *y2 );
		int GetExtent( int *x1, int *y1, int *x2, int *y2 );
		void StoreExtent();
		void JoinExtent();
		void UpdateExtent();

	private:
		static int x1,y1,x2,y2;
};

// ===========================================================================

class MoveablePiece : public DBPieceObject {
	public:
		MoveablePiece();
		virtual ~MoveablePiece();

		virtual void DispatchPress( XButtonEvent * /*xbutton*/ );
		virtual void DispatchRelease( XButtonEvent * /*xbutton*/ );
		virtual void DispatchMotion( XMotionEvent * /*xmotion*/ );

	private:
		static int	turnflag;			//   -1 = left, 0 = no turn, 1 = right
												// -2/2 = around center
		static Time	start_time;
		static Real	start_angle;
		static Vec2	start;
		static Vec2 poffset;
		static Real poffset_len;
};

// ===========================================================================

class Piece : public MoveablePiece {
};

#endif