1 #ifndef _xmover_h
2 #define _xmover_h
3 
4 
5 // tiny caching class so that multiply classes that need the
6 // same help-pixmaps can share them
7 
8 #define	PCACHE_MAX	10
9 #define	ENHANCED_LBPIX_ID	1
10 
11 class PixmapCache {
12 	public:
13 		PixmapCache();
14 		~PixmapCache();
15 
16 		void Unlock(Display *dpy, Pixmap pix);
17 		Pixmap Lock( int id_in, int size_in );
18 		void InsertAndLock( Display *dpy, Pixmap pix, int id_in, int size_in );
19 
20 	static PixmapCache pcache;
21 
22 	private:
23 		int		count;
24 		Pixmap	pmap[PCACHE_MAX];
25 		int		size[PCACHE_MAX];
26 		int		id[PCACHE_MAX];
27 		int		lockcount[PCACHE_MAX];
28 };
29 
30 #define	MOVER_MODE	2
31 
32 class BallMover {
33 	public:
34 		BallMover( const Real &r );
35 		virtual ~BallMover();
36 
GetActRadius()37 		Real GetActRadius()		{ return d/w2n/2; }
38 
39 		virtual void Init();
40 		virtual void DrawBallAt( int x, int y, int col_x );
41 		virtual void MoveBallOnScreen( int oldx, int oldy, int newx, int newy, int col_x );
42 		virtual Pixmap	GetShadowMap( int x, int y );
43 
44 #ifdef STATISTICS
45 		static unsigned long	moves;
46 #endif
47 
48 	protected:
49 		int	r;				// Radius (in Pixeln)
50 		int	d;				// Durchmesser (gleich 2mal Radius)
51 
52 		double	max_rad;	// maximaler Radius, damit Pixel zur Kugel geh�rt
53 		double	max_rad2;// Quadrat des maximalen Radius
54 		Pixmap	bpix;		// Bitmap der Balldarstellung
55 		int		d_help;	// Gr��e der Hintergrund-Pixmap (mind. (2*d-1))
56 		Pixmap	help;		// Hintergrund-Pixmap
57 
58 
59 friend class BallState;
60 };
61 
62 
63 class DiscMover : public BallMover {
64 	public:
65 		DiscMover( const Real &r );
66 		virtual ~DiscMover();
67 
68 		virtual void Init();
69 		virtual Pixmap	GetShadowMap( int x, int y );
70 
71 	protected:
72 		Pixmap	lpix;	// Bitmap des Highlights
73 };
74 
75 
76 class ShadedBallMover : public BallMover {
77 	public:
78 		ShadedBallMover( const Real &r );
79 		virtual ~ShadedBallMover();
80 
81 		virtual void Init();
82 
83 		void CreateLightWindow();
84 		virtual Pixmap	GetShadowMap( int x, int y );
WC2Index(int x,int y,int * xp,int * yp)85 		void WC2Index( int x, int y, int *xp, int *yp ) {
86 			*xp = x/distx;
87    		if (*xp<0)         *xp=0;
88    		if (*xp>=lpixs_x)  *xp=lpixs_x-1;
89 			*yp = y/disty;
90    		if (*yp<0)         *yp=0;
91    		if (*yp>=lpixs_y)  *yp=lpixs_y-1;
92 		}
93 
94 	protected:
95 		Pixmap	*lpix;	// Bitmap-Feld der Highlights
96 
97 		int	distx, disty;			// Rastergr��e f�r Bereich der Highlights
98 		int	lpixs_x, lpixs_y, lpixs_all;		// Zahl der Highlights
99 };
100 
101 #if (0)
102 //
103 // ------------------------------------------------------------------------
104 //                      mult=6
105 	Szenario:  rpixs_l=18  => vecs_l=108
106 
107 	Polarkoordinaten     0    10    20    30                 ^
108 								|     |     |     |          ltoRad | | Radtol
109 																	  btoRad | | Radtob
110 	Vektor-Ids           0     6     12    18                  v
111 						|.....|.....|.....|.....|.....|           <----St2AngVec
112 																					/-St2AngPix
113 	Pixmaps-Ids       |  0  |  1  |  2  |  3  |              <-/
114 
115 	Polarkoordinaten	  170   180   190	             170   180   190
116 								|     |     |		 +mult2    |     |     |
117 	Vektor-Ids     	  102   108   114           102   108   114
118 						|.....|.....|.....|.....|  =>   |.....|.....|.....|
119 	Pixmaps-Ids       |  17 |  0  |  1  |          |  17 |  0  |  1  |
120 //
121 // ------------------------------------------------------------------------
122 //
123 #endif
124 
125 typedef unsigned int RingState;
126 
127 
128 class HalfBallMover : public ShadedBallMover {
129 	public:
130 		HalfBallMover( const Real &r, int mode_in=1 );
131 		virtual ~HalfBallMover();
132 		static HalfBallMover *Create( const Real &r, int mode_in=1 );
133 
134 		virtual void Init();
135 
136 		void CreateRingWindow();
137 		void ShowDebugRing( RingState st, int col_x );
138 		void CreateTurnWindow();
139 
lToRad(int l)140 		Real	lToRad( int l )		{return (l-mult2)*M_PI*2.0/sym/(double)vecs_l;}
bToRad(int b)141 		Real	bToRad( int b )		{return (b-mult2)*M_PI/(double)vecs_b;}
lToDeg(int l)142 		Real	lToDeg( int l )		{return (l-mult2)*360.0/sym/(double)vecs_l;}
bToDeg(int b)143 		Real	bToDeg( int b )		{return (b-mult2)*180.0/(double)vecs_b;}
RadTol(const Real & l)144 		int	RadTol( const Real &l )	{return (rtoi(l*(double)vecs_l/M_PI/2.0*sym)+mult2)%(vecs_l*(int)sym);}
RadTob(const Real & b)145 		int	RadTob( const Real &b )	{return (rtoi(b*(double)vecs_b/M_PI)+mult2)%vecs_b;}
DegTol(const Real & l)146 		int	DegTol( const Real &l )	{return (rtoi(l*(double)vecs_l/360.0*sym)+mult2)%(vecs_l*(int)sym);}
DegTob(const Real & b)147 		int	DegTob( const Real &b )	{return (rtoi(b*(double)vecs_b/180.0)+mult2)%vecs_b;}
148 
149 #if (0)
lVecToDeg(const Real & l)150 		Real	lVecToDeg( const Real &l )	{	return l*360.0/sym/rpixs_l/mult;	}
bVecToDeg(const Real & b)151 		Real	bVecToDeg( const Real &b )	{	return b*180.0/rpixs_b/mult;	}
152 
GetStateForDeg(Real l,Real b)153 		RingState GetStateForDeg( Real l, Real b ) {
154 		void StateToAngleDeg( RingState st, Real *l, Real *b ) {
155 			*l = (st/rpixs_b)*360.0/rpixs_l;
156 			*b = (st%rpixs_b)*180.0/rpixs_b;
157 		}
158 #endif
159 
160 		RingState AngVec2St( int l, int b ) { return (l*vecs_b+b)%vecs_all;	}
161 		RingState AngVec2StBnd( int l, int b ) {
162 				if ( sym>1.0 && l>=vecs_l ) { l-=vecs_l; b=(vecs_b-b+mult)%vecs_b; }
163 				return AngVec2St( l, b );
164 		}
165 
166 		RingState AngPix2St( int l, int b ) { return AngVec2St(l*mult+mult2,b*mult+mult2); }
167 		RingState AngRad2St( const Real &l, const Real &b ) {
168 				return AngVec2StBnd(RadTol(l),RadTob(b));
169 		}
170 
171 		void St2AngVec( RingState st, int *l, int *b ) {
172 			*l = ((int)st)/vecs_b;
173 			*b = ((int)st)%vecs_b;
174 		}
175 		void St2AngPix( RingState st, int *l, int *b ) {
176 			St2AngVec(st,l,b);
177 		/*	*l += mult2; */	*l /= mult;
178 		/*	*b += mult2; */	*b /= mult;
179 		}
180 		int PixIndex( int l, int b )	{				/* l,b in PixSystem */
181 			return (l*rpixs_b+b)%rpixs_all;
182 		}
183 		int PixIndex( RingState st ) {
184 			int	l,b;
185 			St2AngPix( st, &l, &b );
186 			return l*rpixs_b+b;
187 		}
188 
189 		RingState Turn( RingState ost, int dx, int dy );
190 
191 
192 		virtual void RollBallAt( int x, int y, RingState st, int col_x );
193 		virtual void RollBallOnScreen( int oldx, int oldy, RingState ost,
194 									  int newx, int newy, RingState *nst, int col_x );
195 
196 
197 	protected:
198 		Pixmap		*rpix;		// Bitmap-Feld der Ringe
199 
200 		RingState	*right;		// Felder zur Verkettung der RingState's
201 		RingState	*left;
202 		RingState	*up;
203 		RingState	*down;
204 
205 		Real	sym;		// bei Symetrie nicht alle muessen nicht fuer alle
206 							// Winkel die Kugeln berechnet werden.
207 		int	mult;		// Zahl der gespeicherten Zwischenschritte
208 		int	mult2;	// Zwischenschritte / 2
209 		int	vecs_l, vecs_b, vecs_all;		// Zahl der Hilfs-Vektoren
210 		int	rpixs_l, rpixs_b, rpixs_all;	// Zahl der Ring-Pixmaps
211 
212 		int	mode;		// Halbkugel / Vollkugel mit Punkt
213 
214 		static const int o;		// Offset im Trace-Fenster
215 		Window		tw;			// Trace-Fenster
216 		Pixmap		nbpix;
217 
218 friend class HalfBallState;
219 #ifdef DEBUG
220 	friend class TestField;
221 #endif
222 };
223 
224 
225 class LoEnhancedHalfBallMover : public HalfBallMover {
226 	public:
227 		LoEnhancedHalfBallMover( const Real &r, int mode_in=1 );
228 		virtual ~LoEnhancedHalfBallMover();
229 
230 		virtual void Init();
231 
232 		virtual void RollBallAt( int x, int y, RingState st, int col_x );
233 		virtual void RollBallOnScreen( int oldx, int oldy, RingState ost,
234 									  int newx, int newy, RingState *nst, int col_x );
235 
236 	protected:
237 		Pixmap	lbpix;
238 		int		lb_dist;		// sizeof of helpmaps (mind. 3*d-2 = (d-1)+d+(d-1)
239 		int		boffset;		// offset of real contents (d-1)
240 };
241 
242 class HiEnhancedHalfBallMover : public LoEnhancedHalfBallMover {
243 	public:
244 		HiEnhancedHalfBallMover( const Real &r, int mode_in=1 );
245 		virtual ~HiEnhancedHalfBallMover();
246 
247 		virtual void RollBallOnScreen( int oldx, int oldy, RingState ost,
248 									  int newx, int newy, RingState *nst, int col_x );
249 };
250 
251 #endif
252