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