File: mapdisplay.h

package info (click to toggle)
asc 2.6.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 82,860 kB
  • ctags: 26,395
  • sloc: cpp: 158,660; sh: 11,274; ansic: 6,878; makefile: 604; perl: 138
file content (373 lines) | stat: -rw-r--r-- 11,386 bytes parent folder | download
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
365
366
367
368
369
370
371
372
373
/***************************************************************************
                          mapdisplay.h  -  description
                             -------------------
    begin                : Wed Jan 24 2001
    copyright            : (C) 2001 by Martin Bickel
    email                : bickel@asc-hq.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef mapdisplayH
 #define mapdisplayH


#include <sigc++/sigc++.h>
#include "loki/Functor.h"

 
#include "typen.h"
#include "vehicle.h"


#include "paradialog.h"
#include "mapdisplayinterface.h"

class MapLayer;

class MapRenderer {
    
      struct Icons {
         Surface mapBackground;
         Surface notVisible;
         Surface markField;
         Surface markFieldDark;
      };
      static Icons icons;

      typedef deallocating_vector<MapLayer*> LayerRenderer;
      LayerRenderer layerRenderer;
     
      void readData();
      
    public:  
      class FieldRenderInfo {
            public:
               FieldRenderInfo( Surface& s, GameMap* actmap) : surface(s), gamemap(actmap ) {};
               Surface& surface;
               VisibilityStates visibility;
               int playerView;
               MapField* fld;
               MapCoordinate pos;
               GameMap* gamemap;
      };

    protected:
       MapRenderer();

       void paintUnitOntoField( const MapRenderer::FieldRenderInfo& fieldInfo,  int binaryUnitHeight, const SPoint& pos, Vehicle* vehicle );


      static const int surfaceBorder = 90;
            
      struct ViewPort {
         ViewPort( int x1, int y1, int x2, int y2 );
         ViewPort();
         int x1,y1,x2,y2;
      };

      // return the position of a field on the internal surface      
      int getFieldPosX( int x, int y ) { 
          if (y & 1 )   // even lines are shifted to the right
             return surfaceBorder + fielddisthalfx + x * fielddistx;
          else
             return surfaceBorder + x * fielddistx;
      };             
      
      // return the position of a field on the internal surface      
      int getFieldPosY( int x, int y ) {
          return surfaceBorder + y * fielddisty;
      };    
      
      SPoint getFieldPos( int x, int y ) {
          return SPoint( getFieldPosX(x,y), getFieldPosY(x,y));
      };
      SPoint getFieldPos2( const MapCoordinate& pos ) {
          return SPoint( getFieldPosX(pos.x,pos.y), getFieldPosY(pos.x,pos.y));
      };
      
      void paintSingleField( const MapRenderer::FieldRenderInfo& fieldInfo,  int layer, const SPoint& pos );
      void paintTerrain( Surface& surf, GameMap* actmap, int playerView, const ViewPort& viewPort, const MapCoordinate& offset );
      void paintBackground( Surface& surf, const ViewPort& viewPort );
      void paintBackgroundField( Surface& surf, SPoint pos );
      
      int bitmappedHeight2pass( int height );
      
      SigC::Signal2<void,Surface&,int> additionalItemDisplayHook;
      
      void addMapLayer( MapLayer* mapLayer ) { layerRenderer.push_back( mapLayer ); };
     
};


class MapLayer {
   bool active;
   protected:
      MapLayer() : active(true) {};
   public:
      virtual bool onLayer( int layer ) = 0;
      bool isActive() { return active; };
      virtual void setActive( bool active ) { this->active = active; };
      virtual void paintSingleField( const MapRenderer::FieldRenderInfo& fieldInfo,  int layer, const SPoint& pos ) = 0;
      virtual ~MapLayer() {};
};




class MainScreenWidget;




class MapDisplayPG: public PG_Widget, protected MapRenderer {

      typedef map<ASCString,MapLayer*> LayerMap;
      LayerMap layerMap;
      
      struct Icons {
         Surface cursor;
         Surface fieldShape;
      };
      static Icons icons;

      void readData();

      static MapDisplayPG* theMapDisplay;
      
            
      int zoom;
      Surface* surface;
      
      GameMap* lastDisplayedMap;
      void sigMapDeleted( GameMap& deletedMap );
      
      MapCoordinate offset;
     
      void setupFastBlitterCommands();
      struct Field {
         ViewPort viewPort;
         int numx, numy;
      } field;   
      

      void displayCursor( const PG_Rect& dst );
      void displayCursor();
      
      enum Dirty { Nothing, Curs, Map } dirty;
      
      Vehicle* additionalUnit;
       
      void lockOptionsChanged( int options );
      
   protected:
   
      // Paragui stuff
      void eventBlit(SDL_Surface* srf, const PG_Rect& src, const PG_Rect& dst);
      // void eventDraw(SDL_Surface* surface, const PG_Rect& rect);


      bool eventMouseButtonDown (const SDL_MouseButtonEvent *button);
      bool eventMouseMotion (const SDL_MouseMotionEvent *button);
      bool eventMouseButtonUp (const SDL_MouseButtonEvent *button);
      
      //
   
      void checkViewPosition( MapCoordinate& pos );
      
      void fillSurface( int playerView );
      void paintBackground( );


   public:
      void changeZoom( int delta) { setNewZoom( getZoom() + delta); };
      void setNewZoom( int zoom );
      int getZoom() const { return zoom; };
      SigC::Signal1<void, int> newZoom;
      
      MapCoordinate screenPos2mapPos( const SPoint& pos );
      MapCoordinate widgetPos2mapPos( const SPoint& pos );

      SPoint mapGlobalPos2internalPos ( const MapCoordinate& pos );
      SPoint mapViewPos2internalPos ( const MapCoordinate& pos );
      SPoint internal2widget( const SPoint& pos );
      SPoint widget2screen( const SPoint& pos );
      
      MapCoordinate upperLeftCorner();
      MapCoordinate lowerRightCorner();
      
      bool fieldCompletelyInViewX( const MapCoordinate& pos );
      bool fieldCompletelyInViewY( const MapCoordinate& pos );
      bool fieldCompletelyInView( const MapCoordinate& pos );
      
   private:
      SPoint upperLeftSourceBlitCorner;
   protected:

      
      void blitInternalSurface( SDL_Surface* dest, const SPoint& pnt, const PG_Rect& dstClip );

      
      static const int effectiveMovementSurfaceWidth = 4 * fielddisthalfx + fieldsizex;
      static const int effectiveMovementSurfaceHeight = 4*fieldsizey;
      
      struct MovementMask {
         Surface mask;
         SPoint  startFieldPos;
      } movementMask[sidenum];

      void displayAddons( Surface& surf, int pass);
      
      struct Movement {
         Vehicle* veh;
         SPoint from;
         SPoint to;
         int fromShadow;
         int toShadow;
         GameMap* actmap;
         Surface* mask;
         int playerView;

         PG_Rect blitViewPortInternal;
         PG_Rect blitViewPortScreen;
         SPoint maskPosition;
         SPoint targetBlitPos;

         static const int touchedFieldNum = 10;
         int actualFieldNum;
         struct {
            MapCoordinate mapPos;
            SPoint surfPos;
         } touchedFields[touchedFieldNum];

      };

      void initMovementStructure();
      Surface createMovementBufferSurface();
      void displayMovementStep( Movement& movement, int percentage );

      bool eventKeyDown(const SDL_KeyboardEvent* key)
      {
         return keyboardHandler( key );
      };

      bool keyboardHandler( const SDL_KeyboardEvent* keyEvent);
      
      bool disableKeyboardCursorMovement;
     
   public:   
      void keyboadCursorMovement( bool enable ) { disableKeyboardCursorMovement = !enable; }; 
      
      void scrollMap( int dir );
      
   private:
      void UpdateRect( const PG_Rect& rect );
      void moveCursor( int dir, int step );
      void redrawMapAtCursor ( const MapCoordinate& oldpos );

   public:

   

      MapDisplayPG ( MainScreenWidget *parent, const PG_Rect r );

      void displayUnitMovement( GameMap* actmap, Vehicle* veh, const MapCoordinate3D& from, const MapCoordinate3D& to, int duration );

      bool fieldInView(const MapCoordinate& mc );
      bool centerOnField( const MapCoordinate& mc );

      void registerAdditionalUnit ( Vehicle* veh );

      //! repaints to the internal surface, but does not blit this surface the screen
      void updateMap( bool force = false );

      //! update the internal surface and blits it to the screen
      void updateWidget();

      void addMapLayer( MapLayer* layer, const ASCString& name );
      void activateMapLayer( const ASCString& name, bool active );
      void toggleMapLayer( const ASCString& name );
      bool layerActive( const ASCString& name );
      SigC::Signal2<void, bool, const ASCString&> layerChanged;
      void getActiveLayers( vector<ASCString>& list );


   private:
      int signalPrio;
   public:
      int setSignalPriority( int priority );
      
      /** Signal that is fired when the mouse is pressed on a valid field, after the cursor evaluation has been run.
           \param MapCoordinate the Coordinate of the field that was clicked
           \param SPoint the mouse position
           \param bool true if the cursor had been repositioned
           \param int  the button that was pressed
           \param int  the priority of the signal
      */
      SigC::Signal5<bool,const MapCoordinate&, const SPoint&, bool, int, int> mouseButtonOnField;

      /** Signal that is fired when the mouse is dragged onto a new field with mouse buttons pressed.
           \param MapCoordinate the Coordinate of the field that was clicked
           \param SPoint the mouse position
           \param bool true if the cursor had been repositioned
           \param int  the priority of the signal
       */
      SigC::Signal4<bool,const MapCoordinate&, const SPoint&, bool, int> mouseDraggedToField;
      
      
      struct Cursor {
            int invisible;
            MapDisplayPG* mapDisplay; 
            Cursor( MapDisplayPG* md ) : invisible(0), mapDisplay(md) {};
            friend class MapDisplayPG;
            friend class PG_MapDisplay;
            MapCoordinate& pos();
          public:
            void goTo( const MapCoordinate& position );
            void goTo( const MapCoordinate& cursorPosition, const MapCoordinate& upperLeftScreenCorner );
            void intoView();
      } cursor; 
            
      class CursorHiding {
         public:
            CursorHiding();
            ~CursorHiding();
      };
            
      friend class CursorHiding;

      class LockDisplay {
         private:
            bool isDummy;
            void raiseLock();
         public:
            LockDisplay( bool dummy = false );
            ~LockDisplay();
      };

      friend class LockDisplay;

      
      ~MapDisplayPG ();
   private:
      int lock;
           
};

extern SigC::Signal0<void> lockMapdisplay;
extern SigC::Signal0<void> unlockMapdisplay;


typedef MapDisplayPG::LockDisplay tlockdispspfld;

extern void benchMapDisplay();


#endif