Advanced Strategic Command
mapdisplay.cpp
Go to the documentation of this file.
1 
6 /***************************************************************************
7  mapdisplay.cpp - description
8  -------------------
9  begin : Wed Jan 24 2001
10  copyright : (C) 2001 by Martin Bickel
11  email : bickel@asc-hq.org
12  ***************************************************************************/
13 
14 /***************************************************************************
15  * *
16  * This program is free software; you can redistribute it and/or modify *
17  * it under the terms of the GNU General Public License as published by *
18  * the Free Software Foundation; either version 2 of the License, or *
19  * (at your option) any later version. *
20  * *
21  ***************************************************************************/
22 
23 // #define debugmapdisplay
24 
25 
26 #include <cmath>
27 #include <limits>
28 #include <sstream>
29 
30 #include "pgeventsupplier.h"
31 
32 #include "global.h"
33 #include "typen.h"
34 #include "mapdisplay.h"
35 #include "vehicletype.h"
36 #include "buildingtype.h"
37 #include "spfst.h"
38 #include "dialog.h"
39 #include "loaders.h"
40 #include "gameoptions.h"
41 #include "loadbi3.h"
42 #include "mapalgorithms.h"
43 #include "graphicset.h"
44 #include "graphics/blitter.h"
45 #include "graphics/drawing.h"
46 #include "loadpcx.h"
47 #include "iconrepository.h"
48 #include "mainscreenwidget.h"
49 #include "sdl/sound.h"
50 #include "spfst-legacy.h"
51 
52 #ifndef karteneditor
53  #include "dialogs/attackpanel.h"
54 #endif
55 
56 
57 #ifdef debugmapdisplay
58 #include <iostream>
59 #endif
60 
61 
62 MapRenderer::Icons MapRenderer::icons;
63 
64 bool tempsvisible = true;
65 
66 
67 sigc::signal<void> lockMapdisplay;
68 sigc::signal<void> unlockMapdisplay;
69 
70 
71 class ContainerInfoLayer : public MapLayer {
72  Surface& marker;
73  bool hasCargo( const ContainerBase* c ) {
74  for ( ContainerBase::Cargo::const_iterator i = c->getCargo().begin(); i != c->getCargo().end(); ++i )
75  if ( *i )
76  return true;
77  return false;
78  };
79 
80  bool hasOwnCargo( const ContainerBase* c, int viewingPlayer ) {
81  for ( ContainerBase::Cargo::const_iterator i = c->getCargo().begin(); i != c->getCargo().end(); ++i )
82  if ( *i ) {
83  if ( (*i)->getOwner() == viewingPlayer )
84  return true;
85  else
86  if ( hasOwnCargo( *i, viewingPlayer ))
87  return true;
88  }
89  return false;
90  };
91  public:
92  ContainerInfoLayer() : marker( IconRepository::getIcon("fieldcontainermarker.png") ) {};
93 
94  bool onLayer( int layer ) { return layer == 17; };
95  void paintSingleField( const MapRenderer::FieldRenderInfo& fieldInfo, int layer, const SPoint& pos );
96 };
97 
98 void ContainerInfoLayer::paintSingleField( const MapRenderer::FieldRenderInfo& fieldInfo, int layer, const SPoint& pos )
99 {
100  if ( fieldInfo.visibility >= visible_ago) {
101  if ( fieldInfo.fld->vehicle || (fieldInfo.fld->building && fieldInfo.fld->bdt.test(cbbuildingentry) )) {
102  ContainerBase* c = fieldInfo.fld->getContainer();
103  if ( hasCargo(c) ) {
104  if ( c->getOwner() == fieldInfo.playerView )
105  fieldInfo.surface.Blit( marker, pos );
106  else
107  if ( hasOwnCargo(c, fieldInfo.playerView ))
108  fieldInfo.surface.Blit( marker, pos );
109  }
110  }
111  }
112 }
113 
114 
115 class ResourceGraphLayer : public MapLayer {
116  void paintBar( const MapRenderer::FieldRenderInfo& fieldInfo, const SPoint& pos, int row, int amount, int color ) {
117  /*
118  int length = amount / 10;
119  int maxlength = 255/10;
120  if ( amount )
121  paintFilledRectangle<4>( fieldInfo.surface, SPoint( pos.x + 10, pos.y + 2 + row*12), length, 5, ColorMerger_ColoredOverwrite<4>( color ));
122  if ( length < maxlength )
123  paintFilledRectangle<4>( fieldInfo.surface, SPoint( pos.x + 10 + length, pos.y + 2 + row*12), maxlength-length, 5, ColorMerger_ColoredOverwrite<4>( 0x888888 ));
124  */
125 
126  int length = amount * 28 / 255;
127  int maxlength = 28;
128  if ( amount )
129  paintFilledRectangle<4>( fieldInfo.surface, SPoint( pos.x + 10, pos.y + 12 + row*15), length, 8, ColorMerger_ColoredOverwrite<4>( color ));
130  if ( length < maxlength )
131  paintFilledRectangle<4>( fieldInfo.surface, SPoint( pos.x + 10 + length, pos.y + 12 + row*15), maxlength-length, 8, ColorMerger_ColoredOverwrite<4>( 0 ));
132 
133  };
134  public:
135  bool onLayer( int layer ) { return layer == 17; };
136  void paintSingleField( const MapRenderer::FieldRenderInfo& fieldInfo, int layer, const SPoint& pos );
137 };
138 
139 void ResourceGraphLayer::paintSingleField( const MapRenderer::FieldRenderInfo& fieldInfo, int layer, const SPoint& pos )
140 {
141 #ifndef karteneditor
142  if ( fieldInfo.visibility >= visible_ago) {
143  bool visible = false;
144 
145  if ( fieldInfo.playerView == -1 )
146  if ( fieldInfo.fld->resourceview )
147  visible = true;
148 
149  if ( fieldInfo.playerView >= 0 )
150  if ( fieldInfo.fld->resourceview && (fieldInfo.fld->resourceview->visible & ( 1 << fieldInfo.playerView) ) )
151  visible = true;
152 
153  if ( visible ) {
154  if ( fieldInfo.playerView>=0 && fieldInfo.gamemap->getPlayer(fieldInfo.playerView).stat == Player::supervisor ) {
155  paintBar( fieldInfo, pos, 0, fieldInfo.fld->material, Resources::materialColor );
156  paintBar( fieldInfo, pos, 1, fieldInfo.fld->fuel, Resources::fuelColor );
157  } else {
158  paintBar( fieldInfo, pos, 0, fieldInfo.fld->resourceview->materialvisible[max(fieldInfo.playerView,0)], Resources::materialColor );
159  paintBar( fieldInfo, pos, 1, fieldInfo.fld->resourceview->fuelvisible[max(fieldInfo.playerView,0)], Resources::fuelColor );
160  }
161  }
162  }
163 #else
164  paintBar( fieldInfo, pos, 0, fieldInfo.fld->material, Resources::materialColor );
165  paintBar( fieldInfo, pos, 1, fieldInfo.fld->fuel, Resources::fuelColor );
166 #endif
167 }
168 
169 
170 
171 
172 class PipeLayer : public MapLayer {
173  ObjectType* buried_pipeline;
174  ObjectType* pipeline;
175  bool isPipe( const ContainerBase* c ) {
176  for ( ContainerBase::Cargo::const_iterator i = c->getCargo().begin(); i != c->getCargo().end(); ++i )
177  if ( *i )
178  return true;
179  return false;
180  };
181 
182  bool isObjectPipeline( const ObjectType* obj )
183  {
184  if ( !obj )
185  return false;
186  return (obj->displayMethod <= 1 ) && obj->fieldModification[0].terrain_or.test( cbpipeline );
187  }
188 
189  public:
190  PipeLayer() : buried_pipeline( NULL ), pipeline ( NULL )
191  {
192  pipeline = objectTypeRepository.getObject_byID( 3 );
193  if ( !isObjectPipeline( pipeline ))
194  pipeline = NULL;
195 
196  for ( int i = 0; i < objectTypeRepository.getNum(); ++i ) {
197  ObjectType* obj = objectTypeRepository.getObject_byPos( i );
198  if (obj->displayMethod == 1 && obj->fieldModification[0].terrain_or.test( cbpipeline )) {
199  buried_pipeline = obj;
200  }
201  if (obj->displayMethod == 0 && obj->fieldModification[0].terrain_or.test( cbpipeline ) && !pipeline) {
202  pipeline = obj;
203  }
204  }
205  }
206 
207  bool onLayer( int layer ) { return layer == 17; };
208  void paintSingleField( const MapRenderer::FieldRenderInfo& fieldInfo, int layer, const SPoint& pos );
209 };
210 
211 void PipeLayer::paintSingleField( const MapRenderer::FieldRenderInfo& fieldInfo, int layer, const SPoint& pos )
212 {
213  if ( !pipeline )
214  return;
215 
216  if ( fieldInfo.visibility > visible_ago) {
217  if ( fieldInfo.fld->building ) {
218  pipeline->display( fieldInfo.surface, pos, 63, 0 );
219  } else {
220  if ( fieldInfo.fld->bdt.test( cbpipeline )) {
221  Object* o = fieldInfo.fld->checkForObject( buried_pipeline );
222  if ( o )
223  pipeline->display( fieldInfo.surface, pos, o->dir, 0 );
224  else {
225  bool objfound = false;
226  for ( MapField::ObjectContainer::iterator i = fieldInfo.fld->objects.begin(); i != fieldInfo.fld->objects.end(); ++i )
227  if ( i->typ->fieldModification[0].terrain_or.test( cbpipeline ) ) {
228  pipeline->display( fieldInfo.surface, pos, i->dir, 0 );
229  objfound = true;
230  break;
231  }
232 
233  if ( !objfound )
234  pipeline->display( fieldInfo.surface, pos, 63, 0 );
235 
236  }
237  }
238  }
239  }
240 }
241 
242 
243 
244 class ReactionFireLayer : public MapLayer {
245  Surface& image;
246 
247  public:
248  ReactionFireLayer() : image ( IconRepository::getIcon("rf-icon.png")) {} ;
249  bool onLayer( int layer ) { return layer == 17; };
250  void paintSingleField( const MapRenderer::FieldRenderInfo& fieldInfo, int layer, const SPoint& pos );
251 };
252 
253 void ReactionFireLayer::paintSingleField( const MapRenderer::FieldRenderInfo& fieldInfo, int layer, const SPoint& pos )
254 {
255  if ( fieldInfo.visibility > visible_ago) {
256  if ( fieldInfo.fld->vehicle && fieldInfo.fld->vehicle->reactionfire.getStatus() != Vehicle::ReactionFire::off && fieldInfo.fld->vehicle->getOwner() == fieldInfo.playerView ) {
258  blitter.blit( image, fieldInfo.surface, pos);
259  }
260  }
261 }
262 
263 //The Class UnitInfoLayer paint informations about the health and the fuel on the top of the unit
264 class UnitInfoLayer : public MapLayer {
265 
266  Surface& image;
267  void paintBar( const MapRenderer::FieldRenderInfo& fieldInfo, const SPoint& pos, int position, int max, int FromTop, int color, bool OverrideColor )
268  {
269  float FlLength = ((float)29 / (float)max * position);
270  int length = int(floor(FlLength));
271  // int maxlength = 29;
272  int paintcolor;
273  if (OverrideColor == true) {
274  if (length > 20)
275  paintcolor = 0x00FF04;
276  else if (length > 10)
277  paintcolor = 0xFBFF00;
278  else if (length >= 0)
279  paintcolor = 0xFF0400;
280  }
281  else paintcolor = color;
282  paintFilledRectangle<4>( fieldInfo.surface, SPoint( pos.x + 9 , pos.y + FromTop), length, 3, ColorMerger_ColoredOverwrite<4>( paintcolor ) );
283  };
284 
285 
286  public:
287  UnitInfoLayer() : image ( IconRepository::getIcon("unitinfobg.png")) {} ;
288  bool onLayer( int layer ) { return layer == 17; };
289  void paintSingleField( const MapRenderer::FieldRenderInfo& fieldInfo, int layer, const SPoint& pos );
290 };
291 
292 void UnitInfoLayer::paintSingleField( const MapRenderer::FieldRenderInfo& fieldInfo, int layer, const SPoint& pos )
293 {
294 
295  if ( fieldInfo.visibility > visible_ago) {
296  if ( fieldInfo.fld->vehicle ) {
297  if ( ( fieldInfo.fld->vehicle->getOwner() == fieldInfo.playerView ) || (fieldInfo.visibility == visible_all) || ((fieldInfo.fld->vehicle->height >= chschwimmend) && (fieldInfo.fld->vehicle->height <= chhochfliegend))) {
299  //paint the BGimage
300  blitter.blit( image, fieldInfo.surface, pos);
301  //paint the bars
302  //1. damage / health
303  paintBar( fieldInfo, pos, 100-fieldInfo.fld->vehicle->damage, 100, 1, 0, true );
304  //2. fuel
305  paintBar( fieldInfo, pos, fieldInfo.fld->vehicle->getTank().fuel, fieldInfo.fld->vehicle->getStorageCapacity().fuel, 4, 0xFFB700, false );
306  }
307  }
308  }
309 }
310 
311 //The class UnitTraining paints the traininglevel at the bottom of the unit
312 class UnitTrainingLayer : public MapLayer {
313 
314  public:
315  bool onLayer( int layer ) { return layer == 17; };
316  void paintSingleField( const MapRenderer::FieldRenderInfo& fieldInfo, int layer, const SPoint& pos );
317 };
318 
319 
320 void UnitTrainingLayer::paintSingleField( const MapRenderer::FieldRenderInfo& fieldInfo, int layer, const SPoint& pos )
321 {
322  if ( fieldInfo.visibility > visible_ago) {
323  if ( fieldInfo.fld->vehicle ) {
324  if ( ( fieldInfo.fld->vehicle->getOwner() == fieldInfo.playerView ) || (fieldInfo.visibility == visible_all) || ((fieldInfo.fld->vehicle->height >= chschwimmend) && (fieldInfo.fld->vehicle->height <= chhochfliegend))) {
325 
327  AttackFormula af ( fieldInfo.gamemap );
328  int idx = af.getIconIndex( fieldInfo.fld->vehicle->getExperience_offensive(), true );
329 
330  ASCString training = "unitlevel-" + ASCString::toString(idx+1) +".png";
331  blitter.blit( IconRepository::getIcon(training), fieldInfo.surface, pos);
332  }
333 
334  }
335  }
336 }
337 
338 class WeaponRange : public SearchFields
339 {
340  public:
341  int run ( const Vehicle* veh );
342  void testfield ( const MapCoordinate& mc )
343  {
344  gamemap->getField( mc )->setTempw(1);
345  };
346  WeaponRange ( GameMap* _gamemap ) : SearchFields ( _gamemap )
347  {}
348  ;
349 };
350 
351 int WeaponRange :: run ( const Vehicle* veh )
352 {
353  int found = 0;
354  if ( fieldvisiblenow ( getfield ( veh->xpos, veh->ypos )))
355  for ( int i = 0; i < veh->typ->weapons.count; i++ ) {
356  if ( veh->typ->weapons.weapon[i].shootable() ) {
358  startsearch();
359  found++;
360  }
361  }
362  return found;
363 }
364 
365 
366 
367 
368 
369 MapRenderer::ViewPort::ViewPort( int x1, int y1, int x2, int y2 )
370 {
371  this->x1 = x1;
372  this->y1 = y1;
373  this->x2 = x2;
374  this->y2 = y2;
375 };
376 
378 {
379 };
380 
382 {
383  readData();
384 };
385 
386 
387 void MapRenderer::readData()
388 {
389  if ( !icons.mapBackground.valid() ) {
390  icons.mapBackground = IconRepository::getIcon("mapbkgr.raw");
391  icons.notVisible = IconRepository::getIcon("hexinvis.raw");
392  icons.markField = IconRepository::getIcon("markedfield.png");
393  icons.markField.detectColorKey();
394  icons.markFieldDark = IconRepository::getIcon("markedfielddark.png");
395  }
396 }
397 
398 
399 /*
400  layer:
401  0: terrain
402  1: below everything objects
403  2: deep submerged units and building
404  3: deep submerged objects
405  4: submerged units and buildings
406  5: submerged objects
407  6: floating units and buildings
408  7: floating objects
409  8: ground units and buildings
410  9: ground objects
411  10: low flying units and buildings
412  11: low flying objects
413  12: flying units and buildings
414  13: flying objects
415  14: high flying units and buildings
416  15: high flying objects
417  16: orbiting units
418  17: orbiting objects
419  18 view obstructions
420 */
421 
423 {
424  return getFirstBit(height) * 2 + 2;
425 }
426 
427 
428 void MapRenderer::paintUnitOntoField( const MapRenderer::FieldRenderInfo& fieldInfo, int binaryUnitHeight, const SPoint& pos, Vehicle* vehicle )
429 {
430  if ( vehicle && (vehicle->height == binaryUnitHeight))
431  if ( ( vehicle->getOwner() == fieldInfo.playerView ) || (fieldInfo.visibility == visible_all) || ((vehicle->height >= chschwimmend) && (vehicle->height <= chhochfliegend)))
432  vehicle->paint( fieldInfo.surface, pos );
433 
434 }
435 
436 void MapRenderer::paintSingleField( const MapRenderer::FieldRenderInfo& fieldInfo, int layer, const SPoint& pos )
437 {
438 
439  int binaryUnitHeight = 0;
440  if ( layer > 1 )
441  if ( !(layer & 1 ))
442  binaryUnitHeight = 1 << (( layer-2)/2);
443 
444  MapField* fld = fieldInfo.fld;
445 
446  if ( layer == 0 && fieldInfo.visibility >= visible_ago )
447  fld->typ->paint ( fieldInfo.surface, pos );
448 
449 
450  if ( fieldInfo.visibility > visible_ago ) {
451 
452  /* display buildings */
453  if ( fld->building && (fld->building->typ->height & binaryUnitHeight) && fld->building->visible )
454  if ((fieldInfo.visibility == visible_all) || (fld->building->typ->height >= chschwimmend) || ( fld->building->getOwner() == fieldInfo.playerView ))
455  fld->building->paintSingleField( fieldInfo.surface, pos, fld->building->getLocalCoordinate( fieldInfo.pos ));
456 
457 
458  /* display units */
459  paintUnitOntoField( fieldInfo, binaryUnitHeight, pos, fld->vehicle );
460  paintUnitOntoField( fieldInfo, binaryUnitHeight, pos, fld->secondvehicle );
461 
462 
463  }
464 
465  // display objects
466  if ( layer & 1 )
467  for ( MapField::ObjectContainer::iterator o = fld->objects.begin(); o != fld->objects.end(); o++ ) {
468  int h = o->typ->imageHeight;
469  if ( fieldInfo.visibility > visible_ago || (o->typ->visibleago && fieldInfo.visibility >= visible_ago ))
470  if ( h >= ((layer-1)/2)*30 && h < (layer-1)/2*30+30 )
471  o->display ( fieldInfo.surface, pos, fld->getWeather() );
472  }
473 
474 
475 
476 
477  if ( fieldInfo.visibility > visible_ago ) {
478  /* display mines */
479 
480  if ( fieldInfo.visibility == visible_all )
481  if ( !fld->mines.empty() && layer == 7 ) {
482  for ( MapField::MineContainer::const_iterator i = fld->mines.begin(); i != fld->mines.end(); ++i )
483  i->paint( fieldInfo.surface, pos );
484  }
485 
486 
487 
488  /* display marked fields */
489 
490  if ( layer == 18 ) {
491  if ( fld->getaTemp() && tempsvisible )
492  fieldInfo.surface.Blit( icons.markField, pos );
493  else
494  if ( fld->getaTemp2() && tempsvisible )
495  fieldInfo.surface.Blit( icons.markFieldDark, pos );
496  }
497 
498 
499  } else {
500  if (fieldInfo.visibility == visible_ago ) {
501  if ( fld->building && (fld->building->typ->height & binaryUnitHeight) && fld->building->visible )
502  if ((fieldInfo.visibility == visible_all) || (fld->building->typ->height >= chschwimmend) || ( fld->building->getOwner() == fieldInfo.playerView ))
503  fld->building->paintSingleField( fieldInfo.surface, pos, fld->building->getLocalCoordinate( fieldInfo.pos ));
504 
505  }
506  }
507 
508 
509  // display view obstructions
510  if ( layer == 18 ) {
511  if ( fieldInfo.visibility == visible_ago) {
513  // PG_Point pnt = ClientToScreen( 0,0 );
514  blitter.blit( icons.notVisible, fieldInfo.surface, pos);
515  /*
516  // putspriteimage( r + unitrightshift , yp + unitdownshift , view.va8);
517  putshadow( r, yp, icons.view.nv8, &xlattables.a.dark2 );
518  if ( fld->a.temp && tempsvisible )
519  putspriteimage( r, yp, cursor.markfield);
520  else
521  if ( fld->a.temp2 && tempsvisible )
522  putspriteimage( r, yp, xlatpict ( &xlattables.a.dark2 , cursor.markfield));
523 
524  */
525  } else
526  if ( fieldInfo.visibility == visible_not) {
527  fieldInfo.surface.Blit( icons.notVisible, pos );
528  /*
529  if ( ( fld->a.temp || fld->a.temp2 ) && tempsvisible )
530  putspriteimage( r, yp, cursor.markfield);
531  */
532 
533  }
534 
535  }
536 
537  for ( LayerRenderer::iterator i = layerRenderer.begin(); i != layerRenderer.end(); ++i )
538  if ( (*i)->isActive() && (*i)->onLayer(layer))
539  (*i)->paintSingleField( fieldInfo , layer, pos );
540 
541 }
542 
543 
544 void MapRenderer::paintBackground( Surface& surf, const ViewPort& viewPort )
545 {
546  for (int y= viewPort.y1; y < viewPort.y2; ++y )
547  for ( int x=viewPort.x1; x < viewPort.x2; ++x )
548  paintBackgroundField( surf, getFieldPos(x,y) );
549 }
550 
552 {
553  surf.Blit( icons.mapBackground, pos );
554 }
555 
556 
557 
558 void MapRenderer::paintTerrain( Surface& surf, GameMap* actmap, int playerView, const ViewPort& viewPort, const MapCoordinate& offset )
559 {
560  FieldRenderInfo fieldRenderInfo( surf, actmap );
561  fieldRenderInfo.playerView = playerView;
562 
563  GraphicSetManager::Instance().setActive ( actmap->graphicset );
564 
565  for (int pass = 0; pass <= 18 ;pass++ ) {
566  for (int y= viewPort.y1; y < viewPort.y2; ++y )
567  for ( int x=viewPort.x1; x < viewPort.x2; ++x ) {
568  fieldRenderInfo.pos = MapCoordinate( offset.x + x, offset.y + y );
569  fieldRenderInfo.fld = actmap->getField ( fieldRenderInfo.pos );
570  SPoint pos = getFieldPos(x,y);
571  if ( fieldRenderInfo.fld ) {
572  fieldRenderInfo.visibility = fieldVisibility ( fieldRenderInfo.fld, playerView );
573  paintSingleField( fieldRenderInfo, pass, pos );
574  } else
575  if ( pass == 0 )
576  paintBackgroundField( surf, pos );
577 
578  }
579  additionalItemDisplayHook( surf, pass );
580  }
581 
582 }
583 
584 
585 
587 {/*
588  int t = ticker;
589  for ( int i = 0; i < 20; ++i )
590  repaintMap();
591 
592  int t2 = ticker;
593 
594  for ( int i = 0; i< 20; ++i)
595  theGlobalMapDisplay->Redraw();
596 
597  int t3 = ticker;
598 
599  ASCString s;
600  s.format("update map: %d \nupdate widget: %d \n%f fps", t2-t,t3-t2, 20.0 / float(t3-t) * 100 );
601  displaymessage(s, 1 );
602  */
603 }
604 
605 
606 MapDisplayPG* MapDisplayPG::theMapDisplay = NULL;
608 
609 MapDisplayPG::MapDisplayPG ( MainScreenWidget *parent, const PG_Rect r )
610  : PG_Widget ( parent, r, false ) ,
611  zoom(-1),
612  surface(NULL),
613  lastDisplayedMap(NULL),
614  offset(0,0),
615  dirty(Map),
616  additionalUnit(NULL),
617  disableKeyboardCursorMovement(false),
618  signalPrio(0),
619  cursor(this),
620  lock(0)
621 {
622  SetDirtyUpdate(true);
624 
625  readData();
626 
628 
629  setNewZoom( CGameOptions::Instance()->mapzoom );
630 
631  repaintMap.connect( sigc::mem_fun( *this, &MapDisplayPG::updateWidget ));
632 
633  PG_Application::GetApp()->sigKeyDown.connect( sigc::mem_fun( *this, &MapDisplayPG::keyboardHandler ));
634 
635  SetName( "THEMapDisplay");
636 
638  SDL_Surface* ws = GetWidgetSurface ();
639  if ( ws ) {
640  Surface s = Surface::Wrap( ws );
642  }
643 
644  MapRenderer::additionalItemDisplayHook.connect( sigc::mem_fun( *this, &MapDisplayPG::displayAddons ));
645 
646  upperLeftSourceBlitCorner = SPoint( getFieldPosX(0,0), getFieldPosY(0,0));
647 
648  theMapDisplay = this;
649  theGlobalMapDisplay = this;
651 
652  addMapLayer( new ResourceGraphLayer(), "resources" );
653  addMapLayer( new ContainerInfoLayer(), "container" );
654  addMapLayer( new PipeLayer() , "pipes" );
655  addMapLayer( new ReactionFireLayer() , "reactionfire" );
656  addMapLayer( new UnitInfoLayer() , "unitinfo" );
657  addMapLayer( new UnitTrainingLayer() , "unittraining" );
658 
659  parent->lockOptionsChanged.connect( sigc::mem_fun( *this, &MapDisplayPG::lockOptionsChanged ));
660  GameMap::sigMapDeletion.connect( sigc::mem_fun( *this, &MapDisplayPG::sigMapDeleted ));
661 }
662 
663 
664 
665 void MapDisplayPG::lockOptionsChanged( int options )
666 {
668  EnableReceiver(false);
669  else
670  EnableReceiver(true);
671 }
672 
673 void MapDisplayPG::sigMapDeleted( GameMap& deletedMap )
674 {
675  if ( &deletedMap == lastDisplayedMap ) {
676  paintBackground();
677  Update();
678  }
679 }
680 
681 
683 {
684  if ( surface ) {
685  delete surface;
686  surface = NULL;
687  }
688 }
689 
690 
691 MapDisplayPG::Icons MapDisplayPG::icons;
692 
693 
694 void MapDisplayPG::readData()
695 {
696  if ( !icons.cursor.valid() ) {
697  icons.cursor = IconRepository::getIcon( "curshex.png" );
698  icons.fieldShape = IconRepository::getIcon("hexinvis.raw");
699  }
700 }
701 
702 
703 void MapDisplayPG::setNewZoom( int zoom )
704 {
705  if ( zoom > 100 )
706  zoom = 100;
707  if ( zoom < 20 )
708  zoom = 20;
709 
710  if ( zoom == this->zoom )
711  return;
712 
713  this->zoom = zoom;
714 
715  field.numx = int( ceil(float(Width()) * 100 / zoom / fielddistx) );
716  field.numy = int( ceil(float(Height()) * 100 / zoom / fielddisty) );
717 
718  field.viewPort.x1 = -1;
719  field.viewPort.y1 = -1;
720  field.viewPort.x2 = field.numx + 1;
721  field.viewPort.y2 = field.numy + 1;
722 
723  if ( field.numy & 1 )
724  field.numy += 1;
725 
726  delete surface;
727  surface = new Surface( Surface::createSurface ( field.numx * fielddistx + 2 * surfaceBorder, (field.numy - 1) * fielddisty + fieldysize + 2 * surfaceBorder, colorDepth*8 ));
728 
729  dirty = Map;
730  if ( zoom != CGameOptions::Instance()->mapzoom ) {
733  }
734  newZoom( zoom );
735 }
736 
737 
738 void MapDisplayPG::fillSurface( int playerView )
739 {
740  checkViewPosition( offset );
741  if ( !lock ) {
742  paintTerrain( *surface, actmap, playerView, field.viewPort, offset );
743  lastDisplayedMap = actmap;
744  }
745  else
746  paintBackground();
747  dirty = Curs;
748 }
749 
751 {
752  MapRenderer::paintBackground( *surface, field.viewPort );
753  lastDisplayedMap = NULL;
754 }
755 
756 
757 
759 {
760  if ( offset.x + field.numx >= actmap->xsize +1 )
761  offset.x = max(0,actmap->xsize - field.numx +1 );
762 
763  if ( offset.y + field.numy >= actmap->ysize +4)
764  offset.y = max(0,actmap->ysize - field.numy +4);
765 
766  if ( offset.y & 1 )
767  offset.y -= 1;
768 
769  if ( offset.x < 0 )
770  offset.x = 0;
771 
772  if ( offset.y < 0 )
773  offset.y = 0;
774 }
775 
776 
777 
778 
779 template<int pixelSize>
780 class PixSel : public SourcePixelSelector_CacheZoom<pixelSize, SourcePixelSelector_DirectRectangle<pixelSize> >
781 {}
782 ;
783 
784 
785 void MapDisplayPG::updateMap(bool force )
786 {
787  if ( !actmap )
788  return;
789 
790  if ( dirty > Curs || force )
792 }
793 
795 {
796  updateMap(true);
797  Update(true);
798 }
799 
800 
801 
802 void MapDisplayPG::blitInternalSurface( SDL_Surface* dest, const SPoint& pnt, const PG_Rect& dstClip )
803 {
804  if ( zoom != 100 ) {
805  float fzoom = float(zoom) / 100.0;
807  blitter.setZoom( fzoom );
808  blitter.initSource( *surface );
809 
810  // SourcePixelSelector
811  blitter.setSrcRectangle( upperLeftSourceBlitCorner, int(float(Width()) / fzoom), int(float(Height()) / fzoom));
812 
813  PG_Rect clip= dstClip.IntersectRect( dest->clip_rect );
814  blitter.setTargetRect( clip );
815 
816  Surface s = Surface::Wrap( dest );
817  blitter.blit( *surface, s, SPoint(pnt.x, pnt.y ));
818  } else {
820  blitter.initSource( *surface );
821 
822  // SourcePixelSelector
823  blitter.setSrcRectangle( upperLeftSourceBlitCorner, Width(), Height() );
824 
825  PG_Rect clip= dstClip.IntersectRect( dest->clip_rect );
826  blitter.setTargetRect( clip );
827 
828  Surface s = Surface::Wrap( dest );
829  blitter.blit( *surface, s, SPoint(pnt.x, pnt.y ));
830  }
831 
832 }
833 
834 
835 void MapDisplayPG::displayCursor()
836 {
837  displayCursor( *this );
838 }
839 
840 void MapDisplayPG::displayCursor( const PG_Rect& dst )
841 {
842  if ( !actmap )
843  return;
844 
845  if ( dst.w <= 0 || dst.h <= 0 )
846  return;
847 
848  int x = cursor.pos().x - offset.x;
849  int y = cursor.pos().y - offset.y;
850  if( x >= field.viewPort.x1 && x < field.viewPort.x2 && y >= field.viewPort.y1 && y < field.viewPort.y2 && x >= 0 && y >= 0 && x < actmap->xsize && y < actmap->ysize ) {
851  // surface->Blit( icons.cursor, getFieldPos(x,y));
853  blitter.setZoom( float(zoom) / 100.0 );
854 
855  PG_Rect clip= dst.IntersectRect( PG_Application::GetScreen()->clip_rect );
856 
857  if ( clip.w && clip.h ) {
858  blitter.setTargetRect ( clip );
859 
860  Surface s = Surface::Wrap( PG_Application::GetScreen() );
862  blitter.blit( icons.cursor, s, pos );
863  }
864  }
865 }
866 
867 
868 void MapDisplayPG::UpdateRect( const PG_Rect& rect )
869 {
870  SPoint p = widget2screen ( SPoint( rect.x, rect.y));
871  PG_Rect sc ( p.x, p.y, rect.w, rect.h );
872  sc = sc.IntersectRect( *this );
873  eventBlit( GetWidgetSurface (), rect, sc );
874  if ( sc.w && sc.h )
875  PG_Application::UpdateRect(PG_Application::GetScreen(), sc.x, sc.y, sc.w, sc.h );
876 }
877 
878 
879 void MapDisplayPG::eventBlit(SDL_Surface* srf, const PG_Rect& src, const PG_Rect& dst)
880 {
881  if ( !GetWidgetSurface ()) {
882  if ( dirty > Nothing )
883  updateMap();
884 
885  PG_Point pnt = ClientToScreen( 0,0 );
886  blitInternalSurface( PG_Application::GetScreen(), SPoint(pnt.x,pnt.y), dst );
887  } else {
888  PG_Widget::eventBlit(srf,src,dst);
889  }
890 
891  if ( !cursor.invisible )
892  displayCursor( dst );
893 
894 
895 }
896 
897 
899 {
900  return getFieldPos( pos.x - offset.x, pos.y - offset.y );
901 }
902 
904 {
905  return getFieldPos( pos.x, pos.y );
906 }
907 
908 
910 {
911  return SPoint( int(ceil(float(pos.x - surfaceBorder) * zoom / 100.0)), int(ceil(float(pos.y - surfaceBorder) * zoom / 100.0)));
912 }
913 
915 {
916  PG_Point p = ClientToScreen ( pos.x, pos.y );
917  return SPoint ( p.x, p.y );
918 }
919 
920 
922 {
923  PG_Point pnt = ScreenToClient( pos.x, pos.y );
924  if ( pnt.x >= 0 && pnt.y >= 0 && pnt.x < Width() && pnt.y < Height() )
925  return widgetPos2mapPos ( SPoint( pnt.x, pnt.y ));
926  else
927  return MapCoordinate();
928 }
929 
931 {
932  int x = int( float(pos.x) * 100 / zoom ) + surfaceBorder;
933  int y = int( float(pos.y) * 100 / zoom ) + surfaceBorder;
934 
935  for (int yy= field.viewPort.y1; yy < field.viewPort.y2; ++yy )
936  for ( int xx=field.viewPort.x1; xx < field.viewPort.x2; ++xx ) {
937  int x1 = getFieldPosX(xx,yy);
938  int y1 = getFieldPosY(xx,yy);
939  if ( x >= x1 && x < x1+ fieldsizex && y >= y1 && y < y1+fieldsizey )
940  if ( icons.fieldShape.GetPixel(x-x1,y-y1) != 255 )
941  return MapCoordinate(xx+offset.x,yy+offset.y);
942  }
943 
944  return MapCoordinate();
945 }
946 
948 {
949  return offset;
950 }
951 
953 {
954  return MapCoordinate( offset.x + field.numx , offset.y + field.numy );
955 }
956 
957 
959 {
960  if ( !(mc.valid() && mc.x < actmap->xsize && mc.y < actmap->ysize ))
961  return false;
962 
963  MapCoordinate newpos ( mc.x - field.numx / 2, mc.y - field.numy / 2 );
964 
965  checkViewPosition( newpos );
966 
967  if ( newpos != offset ) {
968  offset = newpos;
969  dirty = Map;
970  Redraw();
971  viewChanged();
972  }
973  return true;
974 
975 }
976 
977 void MapDisplayPG::redrawMapAtCursor ( const MapCoordinate& oldpos )
978 {
979  if ( oldpos.valid() ) {
981  UpdateRect( PG_Rect( p.x, p.y, fieldsizex, fieldsizey ) );
982  }
983 
985  UpdateRect( PG_Rect( p.x, p.y, fieldsizex, fieldsizey ) );
986 }
987 
988 
990 {
991  int old = signalPrio;
992  signalPrio = priority;
993  return old;
994 }
995 
997 {
998  SDL_Event event;
999  while ( PG_Application::GetEventSupplier()->PeepEvent(&event) && (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) && (event.button.button == CGameOptions::Instance()->mouse.zoomoutbutton || event.button.button == CGameOptions::Instance()->mouse.zoominbutton ))
1000  PG_Application::GetEventSupplier()->PollEvent ( &event );
1001 }
1002 
1003 bool MapDisplayPG::eventMouseButtonDown (const SDL_MouseButtonEvent *button)
1004 {
1005  MapCoordinate mc = screenPos2mapPos( SPoint(button->x, button->y));
1006 
1007  if ( button->type == SDL_MOUSEBUTTONDOWN && button->button == CGameOptions::Instance()->mouse.zoomoutbutton ) {
1008  changeZoom( 10 );
1009 
1010  MapCoordinate newpos = screenPos2mapPos( SPoint(button->x, button->y));
1011  MapCoordinate newOffset ( offset.x - ( newpos.x - mc.x ), offset.y - ( newpos.y - mc.y ));
1012  checkViewPosition( newOffset );
1013  offset = newOffset;
1014 
1015  viewChanged();
1016  repaintMap();
1018  return true;
1019  }
1020 
1021  if ( button->type == SDL_MOUSEBUTTONDOWN && button->button == CGameOptions::Instance()->mouse.zoominbutton ) {
1022  changeZoom( -10 );
1023 
1024  MapCoordinate newpos = screenPos2mapPos( SPoint(button->x, button->y));
1025  MapCoordinate newOffset ( offset.x - ( newpos.x - mc.x ), offset.y - ( newpos.y - mc.y ));
1026  checkViewPosition( newOffset );
1027  offset = newOffset;
1028 
1029  viewChanged();
1030  repaintMap();
1032  return true;
1033  }
1034 
1035 
1036  if ( !actmap )
1037  return false;
1038 
1039  if ( !(mc.valid() && mc.x < actmap->xsize && mc.y < actmap->ysize ))
1040  return false;
1041 
1042  if ( button->type == SDL_MOUSEBUTTONDOWN && button->button == CGameOptions::Instance()->mouse.fieldmarkbutton ) {
1043  MapCoordinate oldpos = cursor.pos();
1044  bool changed = cursor.pos() != mc;
1045  cursor.pos() = mc;
1046  cursor.invisible = 0;
1047  dirty = Curs;
1048 
1049  updateFieldInfo();
1050 
1051  if ( changed )
1052  redrawMapAtCursor( oldpos );
1053 
1054  mouseButtonOnField( mc, SPoint(button->x, button->y), changed, button->button, signalPrio );
1055  return true;
1056 
1057  }
1058 
1059  if ( button->type == SDL_MOUSEBUTTONDOWN && button->button == CGameOptions::Instance()->mouse.centerbutton ) {
1060  return centerOnField( mc );
1061  }
1062 
1063  mouseButtonOnField( mc, SPoint(button->x, button->y), false, button->button, signalPrio );
1064 
1065  return false;
1066 }
1067 
1068 bool MapDisplayPG::eventMouseMotion (const SDL_MouseMotionEvent *button)
1069 {
1070  if ( !actmap )
1071  return false;
1072 
1073  MapCoordinate mc = screenPos2mapPos( SPoint(button->x, button->y));
1074  if ( !(mc.valid() && mc.x < actmap->xsize && mc.y < actmap->ysize ))
1075  return false;
1076 
1077  if ( button->type == SDL_MOUSEMOTION && (button->state == SDL_BUTTON( CGameOptions::Instance()->mouse.fieldmarkbutton) )) {
1078  bool changed = cursor.pos() != mc;
1079  if ( changed ) {
1080  MapCoordinate oldpos = cursor.pos();
1081  cursor.pos() = mc;
1082  cursor.invisible = 0;
1083  dirty = Curs;
1084 
1085  redrawMapAtCursor( oldpos );
1086  cursorMoved();
1087 
1088  mouseDraggedToField( mc, SPoint(button->x, button->y), changed, signalPrio );
1089 
1090  return true;
1091  }
1092  }
1093  return false;
1094 }
1095 
1096 
1097 bool MapDisplayPG::eventMouseButtonUp (const SDL_MouseButtonEvent *button)
1098 {
1099  return false;
1100 }
1101 
1102 
1104 {
1105  SPoint internal = mapGlobalPos2internalPos( pos);
1106  SPoint s = widget2screen( internal2widget( internal ));
1108  return s.x >= my_xpos && s2.x < my_xpos + my_width;
1109 }
1110 
1112 {
1113  SPoint internal = mapGlobalPos2internalPos( pos);
1114  SPoint s = widget2screen( internal2widget( internal ));
1116  return s.y >= my_ypos && s2.y < my_ypos + my_height;
1117 }
1118 
1120 {
1121  // for performance-reasons we don't call the above two methods
1122  SPoint internal = mapGlobalPos2internalPos( pos);
1123  SPoint s = widget2screen( internal2widget( internal ));
1125  return (s.y >= my_ypos && s2.y < my_ypos + my_height) && (s.x >= my_xpos && s2.x < my_xpos + my_width);
1126 
1127 }
1128 
1129 
1131 {
1132  if ( mc.x < offset.x || mc.y < offset.y || mc.x >= offset.x + field.numx || mc.y >= offset.y + field.numy || !fieldCompletelyInView(mc) )
1133  return false;
1134  else
1135  return true;
1136 }
1137 
1138 
1139 
1141 {
1143  s.SetColorKey( SDL_SRCCOLORKEY, 0xffffff);
1144  return s;
1145 }
1146 
1147 
1149 {
1150  if ( !movementMask[0].mask.valid() )
1151  for ( int dir = 0; dir < sidenum; ++dir ) {
1153  MapCoordinate start;
1154  if ( dir >= 2 && dir <= 4 )
1155  start = MapCoordinate( 1, 2 );
1156  else
1157  start = MapCoordinate( 1, 4 );
1158 
1159  MapCoordinate dest = getNeighbouringFieldCoordinate( start, dir );
1160 
1161  for ( int i = 0; i < sidenum; ++i)
1162  movementMask[dir].mask.Blit( icons.fieldShape, getFieldPos2( getNeighbouringFieldCoordinate( start, i )));
1163  for ( int i = 0; i < sidenum; ++i)
1164  movementMask[dir].mask.Blit( icons.fieldShape, getFieldPos2( getNeighbouringFieldCoordinate( dest, i )));
1165 
1166  SPoint pix = getFieldPos2( start );
1167  movementMask[dir].startFieldPos = pix;
1168 
1169  pix.x += fieldsizex/2;
1170  pix.y += fieldsizey/2;
1171  movementMask[dir].mask.SetColorKey( SDL_SRCCOLORKEY, movementMask[dir].mask.GetPixel( pix ) & ~movementMask[dir].mask.GetPixelFormat().Amask());
1172  }
1173 }
1174 
1175 
1176 template<int pixelsize>
1178 {
1179  typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
1180  int x,y,x1,y1;
1181  int w,h;
1182  PG_Rect innerRect;
1183  int outerwidth;
1184 
1185  const PixelType* pointer;
1186  const PixelType* startPointer;
1187  int pitch;
1188  int linelength;
1189  const Surface* surface;
1190  protected:
1191  SourcePixelSelector_DirectSubRectangle() : x(0),y(0),x1(0),y1(0),w(0),h(0),outerwidth(0),pointer(NULL), surface(NULL)
1192  {}
1193  ;
1194 
1195  int getWidth()
1196  {
1197  return min(w, surface->w() -x1 );
1198  };
1200  {
1201  return min(h, surface->h()-y1 );
1202  };
1203 
1204 
1205  void init ( const Surface& srv )
1206  {
1207  surface = &srv;
1208  startPointer = pointer = (const PixelType*)(srv.pixels());
1209  linelength = srv.pitch()/sizeof(PixelType);
1210  pitch = linelength - w -1 ;
1211  y = y1;
1212  x = x1;
1213  pointer += x1 + y1 * linelength;
1214  outerwidth = getWidth();
1215  };
1216 
1217  PixelType getPixel(int x, int y)
1218  {
1219  x += x1;
1220  y += y1;
1221  if ( x >= 0 && y >= 0 && x < surface->w() && y < surface->h() )
1222  return surface->GetPixel(SPoint(x,y));
1223  else
1224  return surface->GetPixelFormat().colorkey();
1225  };
1226 
1227 
1228  PixelType nextPixel()
1229  {
1230  ++x;
1231  return *(pointer++);
1232  };
1233 
1234 
1236  {
1237  pointer += linelength;
1238  ++y;
1239  };
1240 
1241  void skipPixels( int pixNum )
1242  {
1243  pointer += pixNum;
1244  x += pixNum;
1245  };
1246 
1248  {
1249  if ( y < innerRect.y )
1250  return outerwidth - (x - x1);
1251  else
1252  if ( y >= innerRect.y + innerRect.h )
1253  return outerwidth - (x - x1);
1254  else
1255  if ( x < innerRect.x )
1256  return innerRect.x - x;
1257  else
1258  if ( x >= innerRect.x + innerRect.w )
1259  return outerwidth - (x - x1);
1260  else
1261  return 0;
1262 
1263  };
1264 
1265  void nextLine()
1266  {
1267  pointer = startPointer + x1 + (y++) * linelength;
1268  x = x1;
1269  };
1270 
1271  public:
1272  void setSrcRectangle( SPoint pos, int width, int height )
1273  {
1274  x1 = pos.x;
1275  y1 = pos.y;
1276  w = width;
1277  h = height;
1278  };
1279  void setInnerSrcRectangle( const PG_Rect& rect )
1280  {
1281  innerRect = rect;
1282  };
1283 
1284 };
1285 
1286 template<int pixelSize>
1287 class MovePixSel : public SourcePixelSelector_CacheZoom<pixelSize, SourcePixelSelector_DirectSubRectangle<pixelSize> >
1288 {}
1289 ;
1290 
1291 
1292 void MapDisplayPG::displayMovementStep( Movement& movement, int percentage )
1293 {
1294 #ifdef debugmapdisplay
1295  surface->Fill( 0xff00ff00);
1296 #endif
1297 
1298  FieldRenderInfo fieldRenderInfo( *surface, movement.veh->getMap() );
1299  fieldRenderInfo.playerView = movement.playerView;
1300  for (int pass = 0; pass <= 18 ;pass++ ) {
1301  for ( int i = 0; i < movement.actualFieldNum; ++i ) {
1302  SPoint pos = movement.touchedFields[i].surfPos;
1303  fieldRenderInfo.pos = movement.touchedFields[i].mapPos;
1304  fieldRenderInfo.fld = movement.actmap->getField ( fieldRenderInfo.pos );
1305  if ( fieldRenderInfo.fld ) {
1306  fieldRenderInfo.visibility = fieldVisibility ( fieldRenderInfo.fld, fieldRenderInfo.playerView );
1307 
1308  paintSingleField( fieldRenderInfo, pass, pos );
1309  }
1310  }
1311 
1312  if ( pass >= 2 && pass < 18 )
1313  if ( !(pass & 1 ))
1314  if ( movement.veh->height & (1 << (( pass-2)/2))) {
1315  SPoint pos;
1316  pos.x = movement.from.x + (movement.to.x - movement.from.x) * percentage/100;
1317  pos.y = movement.from.y + (movement.to.y - movement.from.y) * percentage/100;
1318  int shadow = 0;
1319  if ( movement.fromShadow >= 0 && movement.toShadow >= 0 )
1320  shadow = movement.fromShadow + (movement.toShadow - movement.fromShadow) * percentage/100;
1321  movement.veh->paint( *surface, pos, false, shadow );
1322  }
1323  }
1324 
1325 #ifdef debugmapdisplay
1327  alphaBlitter.blit( *movement.mask, *surface, movement.maskPosition);
1328 #endif
1329 
1330  PG_Rect targetArea ( widget2screen( SPoint( 0, 0 )).x, widget2screen( SPoint( 0, 0 )).y, Width(), Height() );
1331  Surface s = Surface::Wrap( PG_Application::GetScreen() );
1332 
1333 #ifdef debugmapdisplay
1334  s.Fill( 0xff00ff );
1335 #endif
1336 
1337  if ( zoom != 100 ) {
1338  float fzoom = float(zoom) / 100.0;
1340  blitter.setZoom( fzoom );
1341  blitter.initSource( *surface );
1342 
1343  blitter.setSrcRectangle( SPoint( getFieldPosX(0,0), getFieldPosY(0,0)), int(float(Width()) / fzoom), int(float(Height()) / fzoom));
1344  blitter.setInnerSrcRectangle( movement.blitViewPortInternal );
1345 
1346  blitter.setTargetRect( targetArea );
1347  blitter.blit( *surface, s, movement.targetBlitPos );
1348  } else {
1350  blitter.initSource( *surface );
1351 
1352  blitter.setSrcRectangle( SPoint( getFieldPosX(0,0), getFieldPosY(0,0)), Width(), Height() );
1353  blitter.setInnerSrcRectangle( movement.blitViewPortInternal );
1354 
1355  blitter.setTargetRect( targetArea );
1356  blitter.blit( *surface, s, movement.targetBlitPos );
1357  }
1358 
1359 #ifdef debugmapdisplay
1360  rectangle<4>( s, SPoint(targetArea.x, targetArea.y), targetArea.w, targetArea.h, ColorMerger_ColoredOverwrite<4>( 0x00ffff ), ColorMerger_ColoredOverwrite<4>( 0x00ffff ) );
1361  rectangle<4>( s, SPoint(movement.blitViewPortScreen.x, movement.blitViewPortScreen.y), movement.blitViewPortScreen.w, movement.blitViewPortScreen.h, ColorMerger_ColoredOverwrite<4>( 0x0000ff ), ColorMerger_ColoredOverwrite<4>( 0x0000ff ) );
1362  PG_Application::UpdateRect(PG_Application::GetScreen(), 0, 0, PG_Application::GetScreen()->w, PG_Application::GetScreen()->h );
1363 #else
1364  PG_Application::UpdateRect(PG_Application::GetScreen(), movement.blitViewPortScreen.x, movement.blitViewPortScreen.y, movement.blitViewPortScreen.w, movement.blitViewPortScreen.h );
1365 #endif
1366 }
1367 
1368 
1369 
1370 
1371 
1372 bool ccompare( const MapCoordinate& a, const MapCoordinate& b )
1373 {
1374  return a.y < b.y || (a.y == b.y && a.x < b.x);
1375 }
1376 
1377 
1378 void MapDisplayPG::displayUnitMovement( GameMap* actmap, Vehicle* veh, const MapCoordinate3D& from, const MapCoordinate3D& to, int duration )
1379 {
1380  static int col = 0xff;
1381 
1382 #ifdef debugmapdisplay
1383  col += 30;
1384  if ( col > 255 )
1385  col -= 255;
1386 #endif
1387 
1388  surface->Fill( col << 8 );
1389 
1390  if ( !fieldInView( from ) && !fieldInView( to ))
1391  return;
1392 
1393  if ( from.x == to.x && from.y == to.y && from.getBitmappedHeight() <= chschwimmend && to.getBitmappedHeight() <= chschwimmend )
1394  // we don't animate a descending or ascending submarine without movement
1395  return;
1396 
1397  int startTime = ticker;
1398  int endTime = startTime + duration;
1399 
1400  // initialisation that is only executed the first time the code runs here
1402 
1403  int dir = getdirection( from, to );
1404 
1405  if ( from.x == to.x && from.y == to.y )
1406  dir = -1; // changing height vertically
1407  else
1408  veh->direction = dir;
1409 
1410  typedef vector< MapCoordinate > TouchedFields;
1411  TouchedFields touchedFields;
1412 
1413  touchedFields.push_back ( from );
1414  for ( int ii = 0; ii < sidenum; ++ii ) {
1416  if ( fieldInView( p ) )
1417  touchedFields.push_back ( p );
1418  }
1419 
1420  if ( dir != -1 ) {
1421  if ( fieldInView( to ))
1422  touchedFields.push_back ( to);
1423 
1424  for ( int ii = 0; ii < sidenum; ++ii ) {
1426  if ( fieldInView( p ) )
1427  touchedFields.push_back ( p );
1428  }
1429  }
1430 
1431 
1432  // now we have all fields that are touched during movement in a list
1433  // let's sort it
1434 
1435  sort( touchedFields.begin(), touchedFields.end(), ccompare );
1436 
1437  Movement movement;
1438  int i = 0;
1439  for ( TouchedFields::iterator j = touchedFields.begin(); j != touchedFields.end(); ++j ) {
1440  if ( i == 0 || movement.touchedFields[i-1].mapPos != *j ) {
1441  movement.touchedFields[i].mapPos = *j;
1442  movement.touchedFields[i].surfPos = mapGlobalPos2internalPos( *j );
1443  ++i;
1444  }
1445  }
1446  movement.actualFieldNum = i;
1447 
1448  movement.veh = veh;
1449  movement.from = mapGlobalPos2internalPos( from );
1450  movement.to = mapGlobalPos2internalPos( to );
1451 
1452  const int maxShadowWidth = 32;
1453  SPoint p1 = SPoint( min( movement.from.x, movement.to.x), min( movement.from.y, movement.to.y) );
1454  movement.blitViewPortInternal = PG_Rect( p1.x, p1.y, max( movement.from.x, movement.to.x) - p1.x + maxShadowWidth + fieldsizex,
1455  max( movement.from.y, movement.to.y) - p1.y + maxShadowWidth + fieldsizey );
1456 
1457  movement.blitViewPortInternal = movement.blitViewPortInternal.IntersectRect( PG_Rect( 0, 0, surface->w(), surface->h() ) );
1458  movement.targetBlitPos = widget2screen ( SPoint( 0, 0));
1459  SPoint a = widget2screen( internal2widget( SPoint( movement.blitViewPortInternal.x, movement.blitViewPortInternal.y )));
1460  SPoint b = widget2screen( internal2widget( SPoint( movement.blitViewPortInternal.x + movement.blitViewPortInternal.w, movement.blitViewPortInternal.y + movement.blitViewPortInternal.h )));
1461 
1462 
1463  movement.blitViewPortScreen = PG_Rect( a.x, a.y, b.x - a.x + 1, b.y - a.y + 1 );
1464  movement.blitViewPortScreen = movement.blitViewPortScreen.IntersectRect( PG_Rect( 0, 0, PG_Application::GetScreenWidth(), PG_Application::GetScreenHeight() ));
1465 
1466  movement.toShadow = ContainerBase::calcShadowDist( to.getNumericalHeight() );
1467  movement.fromShadow = ContainerBase::calcShadowDist( from.getNumericalHeight() );
1468 
1469  movement.actmap = actmap;
1470 
1471  if ( dir < 0 ) {
1472  movement.mask = &movementMask[0].mask;
1473  movement.maskPosition = mapGlobalPos2internalPos( from ) - movementMask[0].startFieldPos;
1474  } else {
1475  movement.mask = &movementMask[dir].mask;
1476  movement.maskPosition = mapGlobalPos2internalPos( from ) - movementMask[dir].startFieldPos;
1477  }
1478 
1479  movement.playerView = actmap->getPlayerView();
1480 
1481  int loopCounter = 0;
1482 #ifdef debugmapdisplay
1483  int loopStartTicker = ticker;
1484 #endif
1485 
1486  while ( ticker < endTime ) {
1487  displayMovementStep( movement, (ticker - startTime) * 100 / duration );
1488  ++loopCounter;
1489  }
1490 
1491  if( duration )
1492  displayMovementStep( movement, 100 );
1493 
1494 #ifdef debugmapdisplay
1495  cout << (float(loopCounter) / float(ticker - loopStartTicker) * 100) << " / " << (float(loopCounter) / float(ticker - startTime) * 100) << " fps \n";
1496 #endif
1497 }
1498 
1499 void MapDisplayPG::displayAddons( Surface& surf, int pass)
1500 {
1501  if( additionalUnit )
1502  if ( pass == bitmappedHeight2pass( additionalUnit->height ) ) {
1503  SPoint p = mapViewPos2internalPos( additionalUnit->getPosition() - offset );
1504  if ( p.x >= 0 && p.y >= 0 && p.x + fieldsizex + ContainerBase::calcShadowDist(getFirstBit(chsatellit)) < surf.w() && p.y + fieldsizey + ContainerBase::calcShadowDist(getFirstBit(chsatellit)) < surf.h() )
1505  additionalUnit->paint( surf, p, false, -1 );
1506  }
1507 
1508 }
1509 
1511 {
1512  if ( actmap )
1513  return actmap->getCursor();
1514  else {
1515  static MapCoordinate mc;
1516  return mc;
1517  }
1518 }
1519 
1521 {
1522  if ( !actmap )
1523  return;
1524 
1525  MapCoordinate oldOffset = offset;
1526 
1527  const int stepWidth = 2;
1528 
1529 
1530  if ( dir == 7 || dir == 0 || dir == 1 )
1531  offset.y -= 2 * stepWidth;
1532 
1533  if ( dir >= 1 && dir <= 3 )
1534  offset.x += stepWidth;
1535 
1536  if ( dir >= 3 && dir <= 5 )
1537  offset.y += 2 * stepWidth;
1538 
1539  if ( dir >= 5 && dir <= 7)
1540  offset.x -= stepWidth;
1541 
1542  checkViewPosition( offset );
1543 
1544  if ( offset != oldOffset ) {
1545  dirty = Map;
1546  Update();
1547  viewChanged();
1548  }
1549 }
1550 
1551 
1552 void MapDisplayPG::moveCursor( int dir, int step )
1553 {
1554  MapCoordinate pos = cursor.pos();
1555 
1556  switch ( dir ) {
1557  case 0: pos.y -= 2 * step;
1558  break;
1559  case 1: pos.y -= 1 * step;
1560  if ( !(pos.y & 1) )
1561  pos.x += 1 * step;
1562  break;
1563  case 2: if ( step & 1 ) {
1564  if ( pos.y & 1 ) {
1565  if ( pos.x < actmap->xsize-1 ) {
1566  pos.x += 1 * step;
1567  pos.y -= 1 * step;
1568  }
1569  } else
1570  pos.y += 1 * step;
1571  } else
1572  pos.x += step/2;
1573  break;
1574  case 3: pos.y += 1 * step;
1575  if ( !(pos.y & 1) )
1576  pos.x += 1 * step;
1577  break;
1578  case 4: pos.y += 2 * step;
1579  break;
1580  case 5: pos.y += 1 * step;
1581  if ( pos.y & 1 )
1582  pos.x -= 1 * step;
1583  break;
1584  case 6: if ( step & 1) {
1585  if ( pos.y & 1 ) {
1586  pos.y -= 1 * step;
1587  } else {
1588  if ( pos.x > 0 ) {
1589  pos.x -= 1 * step;
1590  pos.y += 1 * step;
1591  }
1592  }
1593  } else
1594  pos.x -= step/2;
1595  break;
1596  case 7: pos.y -= 1 * step;
1597  if ( pos.y & 1 )
1598  pos.x -= 1 * step;
1599  break;
1600  }
1601 
1602  if ( pos.x >= actmap->xsize )
1603  pos.x = actmap->xsize -1;
1604 
1605  if ( pos.x < 0 )
1606  pos.x = 0;
1607 
1608  if ( pos.y >= actmap->ysize )
1609  pos.y = actmap->ysize -1;
1610 
1611  if ( pos.y < 0 )
1612  pos.y = 0;
1613 
1614  if ( pos != cursor.pos() ) {
1615  MapCoordinate oldpos = cursor.pos();
1616  cursor.invisible = 0;
1617  dirty = Curs;
1618 
1619  cursor.pos() = pos;
1620 
1621  MapCoordinate oldOffset = offset;
1622 
1623  if ( pos.x < offset.x )
1624  offset.x = max( 0, pos.x );
1625 
1626  if ( pos.y < offset.y )
1627  offset.y = min( 0, pos.y & ~1);
1628 
1629  if ( pos.x > offset.x + field.numx - 2 || !fieldCompletelyInViewX( pos ))
1630  offset.x = pos.x - field.numx + 6;
1631 
1632  if ( pos.y > offset.y + field.numy - 2 || !fieldCompletelyInViewY( pos ))
1633  offset.y = (pos.y - field.numy + 8) & ~1;
1634 
1635  if ( offset != oldOffset )
1636  dirty = Map;
1637 
1638  checkViewPosition( offset );
1639 
1640  cursorMoved();
1641  if ( offset != oldOffset ) {
1642  Update();
1643  viewChanged();
1644  } else {
1645  redrawMapAtCursor( oldpos );
1646  /*
1647  SPoint p = internal2widget( mapGlobalPos2internalPos( oldpos ));
1648  UpdateRect( PG_Rect( p.x, p.y, fieldsizex, fieldsizey ) );
1649 
1650  p = internal2widget( mapGlobalPos2internalPos( pos ));
1651  UpdateRect( PG_Rect( p.x, p.y, fieldsizex, fieldsizey ) );
1652  */
1653  }
1654  }
1655 }
1656 
1657 
1658 bool MapDisplayPG::keyboardHandler( PG_MessageObject* o, const SDL_KeyboardEvent* keyEvent)
1659 {
1660  if ( !keyEvent || !actmap )
1661  return false;
1662 
1663  int keyStateNum;
1664  Uint8* keyStates = SDL_GetKeyState ( &keyStateNum );
1665 
1666  if ( keyEvent->type == SDL_KEYDOWN ) {
1668  if ( keyEvent->keysym.sym == SDLK_RIGHT && keyStates[SDLK_RIGHT] ) {
1669  moveCursor(2, 1);
1670  return true;
1671  }
1672  if ( keyEvent->keysym.sym == SDLK_LEFT && keyStates[SDLK_LEFT] ) {
1673  moveCursor(6, 1);
1674  return true;
1675  }
1676  if ( (keyEvent->keysym.sym == SDLK_UP && keyStates[SDLK_UP] ) || ( keyEvent->keysym.sym == SDLK_KP8 && keyStates[SDLK_KP8] )) {
1677  moveCursor(0, 1);
1678  return true;
1679  }
1680  if ( (keyEvent->keysym.sym == SDLK_DOWN && keyStates[SDLK_DOWN]) || (keyEvent->keysym.sym == SDLK_KP2 && keyStates[SDLK_KP2] )) {
1681  moveCursor(4, 1);
1682  return true;
1683  }
1684  if ( keyEvent->keysym.sym == SDLK_KP6 && keyStates[SDLK_KP6] ) {
1685  moveCursor(2, 2);
1686  return true;
1687  }
1688  if ( keyEvent->keysym.sym == SDLK_KP4 && keyStates[SDLK_KP4] ) {
1689  moveCursor(6, 2);
1690  return true;
1691  }
1692  if ( keyEvent->keysym.sym == SDLK_KP7 && keyStates[SDLK_KP7] ) {
1693  moveCursor(7, 1);
1694  return true;
1695  }
1696  if ( keyEvent->keysym.sym == SDLK_KP9 && keyStates[SDLK_KP9]) {
1697  moveCursor(1, 1);
1698  return true;
1699  }
1700  if ( keyEvent->keysym.sym == SDLK_KP1 && keyStates[SDLK_KP1]) {
1701  moveCursor(5, 1);
1702  return true;
1703  }
1704  if ( keyEvent->keysym.sym == SDLK_KP3 && keyStates[SDLK_KP3]) {
1705  moveCursor(3, 1);
1706  return true;
1707  }
1708 
1709  }
1710  }
1711  return false;
1712 }
1713 
1714 
1716 {
1717  additionalUnit = veh;
1718 }
1719 
1720 void MapDisplayPG::addMapLayer( MapLayer* layer, const ASCString& name )
1721 {
1722  MapRenderer::addMapLayer( layer );
1723  layerMap[name] = layer;
1724  layer->setActive(false);
1725 }
1726 
1727 void MapDisplayPG::activateMapLayer( const ASCString& name, bool active )
1728 {
1729  LayerMap::iterator i = layerMap.find( name );
1730  if ( i != layerMap.end() ) {
1731  i->second->setActive( active );
1732  layerChanged( active, name );
1733  }
1734 }
1735 
1737 {
1738  LayerMap::iterator i = layerMap.find( name );
1739  if ( i != layerMap.end() ) {
1740  i->second->setActive( !i->second->isActive() );
1741  layerChanged( i->second->isActive(), name );
1742  }
1743 }
1744 
1746 {
1747  LayerMap::iterator i = layerMap.find( name );
1748  if ( i != layerMap.end() )
1749  return i->second->isActive();
1750  else
1751  return false;
1752 }
1753 
1754 
1755 void MapDisplayPG::getActiveLayers( vector<ASCString>& list )
1756 {
1757  list.clear();
1758  for ( LayerMap::iterator i = layerMap.begin(); i != layerMap.end(); ++i )
1759  if ( i->second->isActive() )
1760  list.push_back( i->first );
1761 }
1762 
1763 
1764 
1765 
1767 {
1768  if ( theMapDisplay )
1769  ++theMapDisplay->cursor.invisible;
1770 }
1771 
1773 {
1774  if ( theMapDisplay ) {
1775  --theMapDisplay->cursor.invisible;
1776  if ( !theMapDisplay->cursor.invisible )
1777  theMapDisplay->displayCursor();
1778  }
1779 }
1780 
1781 
1782 void MapDisplayPG::Cursor::goTo( const MapCoordinate& cursorPosition, const MapCoordinate& upperLeftScreenCorner )
1783 {
1784  bool redraw = false;
1785 
1786  if ( upperLeftScreenCorner.valid() )
1787  if ( upperLeftScreenCorner != mapDisplay->offset ) {
1788  redraw = true;
1789  mapDisplay->offset = upperLeftScreenCorner;
1790  }
1791 
1792  MapCoordinate oldpos = pos();
1793  if ( !mapDisplay->fieldInView( cursorPosition) )
1794  mapDisplay->centerOnField(cursorPosition);
1795 
1796  pos()=cursorPosition;
1797 
1798  if ( pos() != oldpos || redraw) {
1799  invisible = 0;
1800  mapDisplay->dirty = MapDisplayPG::Curs;
1801  mapDisplay->Update();
1802  // mapDisplay->updateWidget();
1803  }
1804 }
1805 
1807 {
1808  MapCoordinate oldpos = pos();
1809  if ( !mapDisplay->fieldInView( position) )
1810  mapDisplay->centerOnField(position);
1811  pos()=position;
1812 
1813  if ( pos() != oldpos ) {
1814  invisible = 0;
1815  mapDisplay->dirty = MapDisplayPG::Curs;
1816  mapDisplay->Update();
1817  // mapDisplay->updateWidget();
1818  }
1819 
1820 }
1821 
1822 
1823 
1824 
1825 
1827 
1828 
1829 
1830 void MapDisplayPG::LockDisplay::raiseLock()
1831 {
1832  if ( theMapDisplay ) {
1833  ++theMapDisplay->lock;
1834  theMapDisplay->dirty = Map;
1835  theMapDisplay->Update();
1836  }
1837  lockMapdisplay();
1838 
1839 }
1840 
1841 
1842 MapDisplayPG::LockDisplay::LockDisplay( bool dummy ) : isDummy( dummy )
1843 {
1844  if ( !dummy )
1845  raiseLock();
1846 }
1847 
1849 {
1850  if ( !isDummy ) {
1851  if ( theMapDisplay ) {
1852  --theMapDisplay->lock;
1853  if ( !theMapDisplay->lock ) {
1854  theMapDisplay->dirty = Map;
1855  theMapDisplay->Update();
1856  }
1857  }
1858  if ( !theMapDisplay->lock )
1859  unlockMapdisplay();
1860  }
1861 }
1862 
1863 
1864 
TerrainType::Weather * typ
the terraintype of the field
Definition: mapfield.h:38
Uint8 materialvisible[8]
Definition: mapfield.h:110
SPoint mapGlobalPos2internalPos(const MapCoordinate &pos)
Definition: mapdisplay.cpp:898
int fuel
Definition: typen.h:101
int displayMethod
some objects require special displaying methods, for example shading the terrain they are build on ...
Definition: objecttype.h:175
void paintSingleField(const MapRenderer::FieldRenderInfo &fieldInfo, int layer, const SPoint &pos)
Definition: mapdisplay.cpp:436
void paintBackground(Surface &surf, const ViewPort &viewPort)
Definition: mapdisplay.cpp:544
void displayMovementStep(Movement &movement, int percentage)
ItemRepositoryLoader< ObjectType > objectTypeRepository("objecttype")
Interface for loading and writing of PCX images.
Player & getPlayer(PlayerID p)
Definition: gamemap.h:257
MapCoordinate & getCursor()
Definition: gamemap.cpp:933
int xsize
the size of the map
Definition: gamemap.h:201
void getActiveLayers(vector< ASCString > &list)
int getFieldPosY(int x, int y)
Definition: mapdisplay.h:85
virtual void setActive(bool active)
Definition: mapdisplay.h:117
int centerbutton
the button to select a field and open the menu there
Definition: gameoptions.h:146
bool fieldInView(const MapCoordinate &mc)
map accessing and usage routines used by ASC and the mapeditor
const BuildingType * typ
Definition: buildings.h:48
#define chschwimmend
Definition: typen.h:412
int damage
Damage. 0 is no damage, when damage reaches 100 the container is destroyed.
the core formula, which weighs the different factory that go into the calculation ...
Definition: attack.h:42
Vehicle * vehicle
Definition: mapfield.h:89
void toggleMapLayer(const ASCString &name)
bool valid() const
Definition: typen.h:221
void paintTerrain(Surface &surf, GameMap *actmap, int playerView, const ViewPort &viewPort, const MapCoordinate &offset)
Definition: mapdisplay.cpp:558
void paintSingleField(const MapRenderer::FieldRenderInfo &fieldInfo, int layer, const SPoint &pos)
Definition: mapdisplay.cpp:211
void blit(const Surface &src, Surface &dst, SPoint dstPos)
Definition: blitter.h:349
void paintSingleField(Surface &s, SPoint imgpos, BuildingType::LocalCoordinate pos) const
Definition: buildings.cpp:198
MapCoordinate lowerRightCorner()
Definition: mapdisplay.cpp:952
bool fieldCompletelyInViewY(const MapCoordinate &pos)
void paintBackground()
Definition: mapdisplay.cpp:750
Surface createMovementBufferSurface()
sigc::signal< void > dataLoaderTicker
Loading Battle Isle 3 maps. The central BI3 map loading class is a straight conversion of Joerg Richt...
int getFirstBit(int zahl)
Count the number of zero bits on the LSB side of "zahl".
Definition: misc.cpp:45
Uint8 material
Definition: mapfield.h:54
UnitWeapon weapons
The weapons.
Definition: vehicletype.h:248
bool keyboardHandler(PG_MessageObject *o, const SDL_KeyboardEvent *keyEvent)
static const int materialColor
Definition: typen.h:140
Resources getStorageCapacity() const
returns the local storage capacity for the given resource, which depends on the resource mode of the ...
MapCoordinate & pos()
bool shootable(void) const
int fieldmarkbutton
the button to select a field without opening the menu
Definition: gameoptions.h:130
PG_Rect blitViewPortInternal
Definition: mapdisplay.h:238
int getOwner() const
returns the number of the player this vehicle/building belongs to
int lockdisplaymap
WeaponRange(GameMap *_gamemap)
Definition: mapdisplay.cpp:346
#define fieldysize
Definition: typen.h:432
bool disableKeyboardCursorMovement
Definition: mapdisplay.h:263
SPoint getFieldPos2(const MapCoordinate &pos)
Definition: mapdisplay.h:92
sigc::signal< void, bool, const ASCString & > layerChanged
Definition: mapdisplay.h:298
sigc::signal< bool, const MapCoordinate &, const SPoint &, bool, int > mouseDraggedToField
Signal that is fired when the mouse is dragged onto a new field with mouse buttons pressed...
Definition: mapdisplay.h:322
int getNumericalHeight() const
Definition: typen.h:242
static const int surfaceBorder
Definition: mapdisplay.h:68
static const int effectiveMovementSurfaceWidth
Definition: mapdisplay.h:218
BuildingType::LocalCoordinate getLocalCoordinate(const MapCoordinate &field) const
converts a global coordinate into a local coordinate.
Definition: buildings.cpp:423
int run(const Vehicle *veh)
Definition: mapdisplay.cpp:351
MapCoordinate3D getPosition() const
returns the units position
Definition: vehicle.cpp:1552
static Surface createSurface(int width, int height, SDLmm::Color color=255)
Definition: surface.cpp:387
sigc::signal< void > repaintMap
}@
Definition: spfst.cpp:45
static const int effectiveMovementSurfaceHeight
Definition: mapdisplay.h:219
A system that provides a set of images for vehicles, buildings, etc.
void fillSurface(int playerView)
Definition: mapdisplay.cpp:738
SPoint getFieldPos(int x, int y)
Definition: mapdisplay.h:89
void updateMap(bool force=false)
repaints to the internal surface, but does not blit this surface the screen
Definition: mapdisplay.cpp:785
void display(Surface &surface, const SPoint &pos) const
displays the objecttype at x/y on the screen
Definition: objecttype.cpp:289
#define chhochfliegend
Definition: typen.h:416
SingleWeapon weapon[16]
Definition: vehicletype.h:170
ContainerBase * getContainer()
returns a pointer to the ContainerBase of the field or NULL if there is none
Definition: mapfield.cpp:331
Global platform dependant definitions. This file just branches to the platform specific files in thei...
void registerAdditionalUnit(Vehicle *veh)
Resources getTank() const
returns the resources that the unit is carrying
Definition: vehicle.cpp:378
a single field of the map
Definition: mapfield.h:26
static int calcShadowDist(int binaryHeight)
struct MapDisplayPG::Cursor cursor
int getIconIndex(int experience, bool offensive)
Definition: attack.cpp:156
void setNewZoom(int zoom)
Definition: mapdisplay.cpp:703
void updateWidget()
update the internal surface and blits it to the screen
Definition: mapdisplay.cpp:794
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
void paintSingleField(const MapRenderer::FieldRenderInfo &fieldInfo, int layer, const SPoint &pos)
Definition: mapdisplay.cpp:320
bool layerActive(const ASCString &name)
sigc::signal< void, Surface &, int > additionalItemDisplayHook
Definition: mapdisplay.h:103
int height
the current level of height ( BITMAPPED ! )
Definition: vehicle.h:118
int getWeather()
the weather that is on this field
Definition: mapfield.cpp:370
int getPlayerView() const
the player which is currently viewing the map.
Definition: gamemap.cpp:1007
void displayUnitMovement(GameMap *actmap, Vehicle *veh, const MapCoordinate3D &from, const MapCoordinate3D &to, int duration)
MapField * getfield(int x, int y)
returns the field at the given coordinates
Definition: spfst.cpp:199
const int sidenum
the number of sides that a field has; is now fixed at 6;
Definition: typen.h:438
bool onLayer(int layer)
Definition: mapdisplay.cpp:288
#define fieldsizey
Definition: typen.h:441
void addMapLayer(MapLayer *mapLayer)
Definition: mapdisplay.h:105
int bitmappedHeight2pass(int height)
Definition: mapdisplay.cpp:422
bool fieldvisiblenow(const MapField *pe, Vehicle *veh, int player)
{@
Definition: spfst.cpp:399
void paintSingleField(const MapRenderer::FieldRenderInfo &fieldInfo, int layer, const SPoint &pos)
Definition: mapdisplay.cpp:292
static ASCString toString(int i)
converts the parameter to a String
Definition: ascstring.cpp:193
class Vehicle::ReactionFire reactionfire
#define maxmalq
Constants that specify the layout of ASC.
Definition: typen.h:429
struct MapDisplayPG::MovementMask movementMask[sidenum]
void testfield(const MapCoordinate &mc)
Definition: mapdisplay.cpp:342
void paintSingleField(const MapRenderer::FieldRenderInfo &fieldInfo, int layer, const SPoint &pos)
Definition: mapdisplay.cpp:98
void setChanged(bool flag=true)
Definition: gameoptions.h:272
int mindistance
the minimal distance the weapon can shoot
Definition: vehicletype.h:114
void filterQueuedZoomEvents()
Definition: mapdisplay.cpp:996
int graphicset
the ID of the graphic set
Definition: gamemap.h:424
bool onLayer(int layer)
Definition: mapdisplay.cpp:249
bool tempsvisible
Definition: mapdisplay.cpp:64
bool fieldCompletelyInViewX(const MapCoordinate &pos)
enum Player::PlayerStatus stat
sigc::signal< void > lockMapdisplay
Definition: mapdisplay.cpp:67
void initsearch(const MapCoordinate &startPosition, int _firstDistance, int _lastDistance)
void paintUnitOntoField(const MapRenderer::FieldRenderInfo &fieldInfo, int binaryUnitHeight, const SPoint &pos, Vehicle *vehicle)
Definition: mapdisplay.cpp:428
Uint8 fuel
mineral resources on this field.
Definition: mapfield.h:54
An object that can be placed on fields. Roads, pipelines and ditches are examples of objects...
Definition: objecttype.h:30
Coordinate on the twodimensional map.
Definition: typen.h:202
MapCoordinate mapPos
Definition: mapdisplay.h:246
int setSignalPriority(int priority)
Definition: mapdisplay.cpp:989
LockDisplay(bool dummy=false)
void initSource(const Surface &src)
Definition: blitter.h:343
int getFieldPosX(int x, int y)
Definition: mapdisplay.h:77
static sigc::signal< void, GameMap & > sigMapDeletion
Definition: gamemap.h:501
searches fields in hexagonal "circles" around a field and calls testfield for each field ...
Definition: mapalgorithms.h:28
Uint8 getaTemp()
Definition: mapfield.cpp:52
void paint(Surface &s, SPoint pos, int shadowDist=-1) const
displays the unit at position spos on s
Definition: vehicle.cpp:1681
void benchMapDisplay()
Definition: mapdisplay.cpp:586
struct MapDisplayPG::Movement::@18 touchedFields[touchedFieldNum]
The interface for the buildingtype class.
sigc::signal< void > unlockMapdisplay
Definition: mapdisplay.cpp:68
int dir
Definition: objects.h:51
virtual void startsearch(void)
int maxdistance
the maximum distance the weapon can shoot
Definition: vehicletype.h:111
struct ObjectType::FieldModification fieldModification[cwettertypennum]
SPoint mapViewPos2internalPos(const MapCoordinate &pos)
Definition: mapdisplay.cpp:903
void scrollMap(int dir)
sigc::signal< void > updateFieldInfo
Definition: spfst.cpp:47
void checkViewPosition(MapCoordinate &pos)
Definition: mapdisplay.cpp:758
MapCoordinate upperLeftCorner()
Definition: mapdisplay.cpp:947
#define fieldsizex
Definition: typen.h:440
void setSrcRectangle(SPoint pos, int width, int height)
VisibilityStates visibility
Definition: mapdisplay.h:55
void paint(Surface &s, SPoint pos)
displays the image on the screen coordinates x1/y1
SDLmm::SPoint SPoint
Definition: surface.h:27
VisibilityStates fieldVisibility(const MapField *pe)
}@
Definition: spfst.cpp:440
static CGameOptions * Instance()
returns the only Instance
Definition: gameoptions.cpp:38
bool eventMouseButtonDown(const SDL_MouseButtonEvent *button)
#define chsatellit
Definition: typen.h:417
struct CGameOptions::Mouse mouse
void addMapLayer(MapLayer *layer, const ASCString &name)
int ysize
Definition: gamemap.h:201
sigc::signal< void > viewChanged
the view of the player onto the map changed, for example because he scrolled the map ...
Definition: spfst.cpp:51
TerrainBits bdt
the terraintype properties. They determine which units can move over the field. This variable is reca...
Definition: mapfield.h:161
void paintBackgroundField(Surface &surf, SPoint pos)
Definition: mapdisplay.cpp:551
MineContainer mines
Definition: mapfield.h:117
#define fielddistx
Definition: typen.h:433
void blitInternalSurface(SDL_Surface *dest, const SPoint &pnt, const PG_Rect &dstClip)
Definition: mapdisplay.cpp:802
int height
the levels of height which this unit can enter
void assignDefaultPalette()
assigns the default ASC palette to the surface (only for 8 Bit surfaces)
Definition: surface.cpp:429
int mapzoom
the zoom of the map display in ASC
Definition: gameoptions.h:75
void eventBlit(SDL_Surface *srf, const PG_Rect &src, const PG_Rect &dst)
Definition: mapdisplay.cpp:879
void activateMapLayer(const ASCString &name, bool active)
Interface for all the dialog boxes used by the game and the mapeditor.
sigc::signal< bool, const MapCoordinate &, const SPoint &, bool, int, int > mouseButtonOnField
Signal that is fired when the mouse is pressed on a valid field, after the cursor evaluation has been...
Definition: mapdisplay.h:314
MapCoordinate screenPos2mapPos(const SPoint &pos)
Definition: mapdisplay.cpp:921
int xpos
the position on the map
Definition: vehicle.h:124
int getBitmappedHeight() const
Definition: typen.h:241
MapCoordinate widgetPos2mapPos(const SPoint &pos)
Definition: mapdisplay.cpp:930
procedure for loading and writing savegames, maps etc.
const VehicleType * typ
Definition: vehicle.h:83
static Surface & getIcon(const ASCString &name)
Uint8 direction
the direction in which the unit is facing
Definition: vehicle.h:121
bool fieldCompletelyInView(const MapCoordinate &pos)
static const int fuelColor
Definition: typen.h:141
Coordinate on the map including height.
Definition: typen.h:238
Building * building
Definition: mapfield.h:102
void goTo(const MapCoordinate &position)
MapDisplayPG * theGlobalMapDisplay
Definition: mapdisplay.cpp:607
void changeZoom(int delta)
Definition: mapdisplay.h:190
void setTempw(Uint16 tempw)
Definition: mapfield.cpp:63
Vehicle * secondvehicle
two units and the same field are only allowed temporary during movement
Definition: mapfield.h:92
sigc::signal< void > cursorMoved
Definition: spfst.cpp:48
bool onLayer(int layer)
Definition: mapdisplay.cpp:94
GameMap * actmap
Definition: spfst.cpp:64
GameMap * getMap() const
static Surface Wrap(SDL_Surface *surface)
Definition: surface.h:76
The parent class of Vehicle and Building; The name Container originates from Battle Isle...
Definition: containerbase.h:40
bool onLayer(int layer)
Definition: mapdisplay.cpp:315
void displayAddons(Surface &surf, int pass)
const T & max(const T &a, const T &b, const T &c)
Definition: misc.h:97
bool eventMouseButtonUp(const SDL_MouseButtonEvent *button)
void initMovementStructure()
const T & min(const T &a, const T &b, const T &c)
Definition: misc.h:80
void paintSingleField(const MapRenderer::FieldRenderInfo &fieldInfo, int layer, const SPoint &pos)
Definition: mapdisplay.cpp:139
an instance of an object type (ObjectType) on the map
Definition: objects.h:46
Status getStatus() const
for each player that can still be attacked one bit is set
Definition: vehicle.h:155
Definition: sg.cpp:412
int zoomoutbutton
the button to display the vehicle information
Definition: gameoptions.h:157
bool ccompare(const MapCoordinate &a, const MapCoordinate &b)
bool eventMouseMotion(const SDL_MouseMotionEvent *button)
const Cargo & getCargo() const
sigc::signal< void, int > newZoom
Definition: mapdisplay.h:192
Object * checkForObject(const ObjectType *o)
checks if there are objects from the given type on the field and returns them
Definition: mapfield.cpp:648
int ypos
Definition: vehicle.h:124
bool visible
is the building visible? Building can be made invisible, but this feature should be used only in some...
Definition: buildings.h:63
int getdirection(const MapCoordinate &start, const MapCoordinate &dest)
void setInnerSrcRectangle(const PG_Rect &rect)
GameMap * gamemap
Definition: mapalgorithms.h:30
void paintSingleField(const MapRenderer::FieldRenderInfo &fieldInfo, int layer, const SPoint &pos)
Definition: mapdisplay.cpp:253
bool centerOnField(const MapCoordinate &mc)
Definition: mapdisplay.cpp:958
bool onLayer(int layer)
Definition: mapdisplay.cpp:207
sigc::signal< void, int > lockOptionsChanged
bool onLayer(int layer)
Definition: mapdisplay.cpp:135
#define minmalq
Definition: typen.h:430
Resourceview * resourceview
the mineral resources that were seen by a player on this field; since the actual amount may have decr...
Definition: mapfield.h:114
#define fielddisty
Definition: typen.h:434
MapCoordinate3D getNeighbouringFieldCoordinate(const MapCoordinate3D &pos, int direc)
returns the coordinate of the field that is adjecent to the given field in the direction of direc ...
ObjectContainer objects
Definition: mapfield.h:124
Uint8 getaTemp2()
Definition: mapfield.cpp:59
const int colorDepth
Definition: basegfx.h:46
The map. THE central structure of ASC, which holds everything not globally available together...
Definition: gamemap.h:182
volatile int ticker
Definition: events.cpp:234
SPoint widget2screen(const SPoint &pos)
Definition: mapdisplay.cpp:914
MapField * getField(int x, int y)
Definition: gamemap.h:465
MapDisplayPG(MainScreenWidget *parent, const PG_Rect r)
Definition: mapdisplay.cpp:609
SPoint internal2widget(const SPoint &pos)
Definition: mapdisplay.cpp:909
int getExperience_offensive() const
Definition: vehicle.cpp:253