<URL: http://bugs.freeciv.org/Ticket/Display.html?id=39811 >

It would have been more helpful to have a report that it was the very
first savegame that differed, because the generation differed!  Wasted an
awful lot of time testing 2.1 to completion for each iterator individually,
when I'd already tested them in trunk.  Worried about minor differences in
generation (in this case, merely the startpos)?  Oh well, fixed that, too.

Anyway, even though it was not intended for 2.1, with so much 2.1 testing,
it was committed there, too.

Committed trunk revision 13906.
Committed S2_2 revision 13907.
Committed S2_1 revision 13908, for posterity:


Index: server/generator/utilities.h
===================================================================
--- server/generator/utilities.h        (revision 13907)
+++ server/generator/utilities.h        (working copy)
@@ -33,44 +33,45 @@
 }
 
 /***************************************************************************
- iterate axe iterate on selected axe ( x if Xaxe is TRUE) over a intervale
- of -dist to dist arround the tile indexed by index0
- this iterator create 2 vars:
- index : the map index of the iterate pointed tile
- i : the position in the intervale of iteration (from -dist to dist)
- index0, dist, Xaxe are side effect safe.
+ iterate on selected axe (x if is_X_axis is TRUE) over a interval of -dist
+ to dist around the center_tile
+ _index : the position in the interval of iteration (from -dist to dist)
+ _tile : the tile pointer
  ***************************************************************************/
-#define iterate_axe(iter_tile, i, center_tile, dist, Xaxe)             \
-  {                                                                    \
-    const int ___dist = (dist);                                                
\
-    const struct tile *_center_tile = (center_tile);                   \
-    const bool ___Xaxe = (Xaxe);                                       \
-    int i, ___x, ___y;                                                 \
-    struct tile *iter_tile;                                            \
+#define axis_iterate(center_tile, _tile, _index, dist, is_X_axis)      \
+{                                                                      \
+  int _tile##_x, _tile##_y;                                            \
+  struct tile *_tile;                                                  \
+  const struct tile *_tile##_center = (center_tile);                   \
+  const bool _index##_axis = (is_X_axis);                              \
+  const int _index##_d = (dist);                                       \
+  int _index = -(_index##_d);                                          \
                                                                        \
-    for (i = -___dist; i <= ___dist; i++) {                            \
-      ___x = _center_tile->nat_x + (___Xaxe ? i : 0);                  \
-      ___y = _center_tile->nat_y + (___Xaxe ? 0 : i);                  \
-      iter_tile = native_pos_to_tile(___x, ___y);                      \
-      if (!iter_tile) {                                                        
\
-       continue;                                                       \
-      }
+  for (; _index <= _index##_d; _index++) {                             \
+    _tile##_x = _tile##_center->nat_x + (_index##_axis ? _index : 0);  \
+    _tile##_y = _tile##_center->nat_y + (_index##_axis ? 0 : _index);  \
+    _tile = native_pos_to_tile(_tile##_x, _tile##_y);                  \
+    if (NULL != _tile) {
 
-#define iterate_axe_end \
-    } \
+#define axis_iterate_end                                               \
+    }                                                                  \
+  }                                                                    \
 } 
-#define whole_map_iterate_filtered(ptile, pdata, pfilter)                   \
-{                                                                          \
-  bool (*_filter)(const struct tile *ptile, const void *data) = (pfilter);  \
-  const void *_data = (pdata);                                             \
-                                                                           \
-  whole_map_iterate(ptile) {                                                \
-    if (_filter && !(_filter)(ptile, _data)) {                             \
-      continue;                                                             \
-    }
 
-#define whole_map_iterate_filtered_end                                     \
-  } whole_map_iterate_end                                                  \
+/***************************************************************************
+ pdata or pfilter can be NULL!
+***************************************************************************/
+#define whole_map_iterate_filtered(_tile, pdata, pfilter)              \
+{                                                                      \
+  bool (*_tile##_filter)(const struct tile *vtile, const void *vdata) = 
(pfilter);\
+  const void *_tile##_data = (pdata);                                  \
+                                                                       \
+  whole_map_iterate(_tile) {                                           \
+    if (NULL == _tile##_filter || (_tile##_filter)(_tile, _tile##_data)) {
+
+#define whole_map_iterate_filtered_end                                 \
+    }                                                                  \
+  } whole_map_iterate_end;                                             \
 }
 
 bool is_normal_nat_pos(int x, int y);
Index: server/generator/utilities.c
===================================================================
--- server/generator/utilities.c        (revision 13907)
+++ server/generator/utilities.c        (working copy)
@@ -184,10 +184,10 @@
     whole_map_iterate(ptile) {
       int  N = 0, D = 0;
 
-      iterate_axe(tile1, i, ptile, 2, axe) {
+      axis_iterate(ptile, pnear, i, 2, axe) {
        D += weight[i + 2];
-       N += weight[i + 2] * source_map[tile1->index];
-      } iterate_axe_end;
+       N += weight[i + 2] * source_map[pnear->index];
+      } axis_iterate_end;
       if(zeroes_at_edges) {
        D = total_weight;
       }
Index: common/terrain.c
===================================================================
--- common/terrain.c    (revision 13907)
+++ common/terrain.c    (working copy)
@@ -292,23 +292,23 @@
   This iterator behaves like adjc_iterate or cardinal_adjc_iterate depending
   on the value of card_only.
 ****************************************************************************/
-#define variable_adjc_iterate(center_tile, itr_tile, card_only)                
    \
-{                                                                          \
-  enum direction8 *_dirlist;                                               \
-  int _total;                                                              \
-                                                                           \
-  if (card_only) {                                                         \
-    _dirlist = map.cardinal_dirs;                                          \
-    _total = map.num_cardinal_dirs;                                        \
-  } else {                                                                 \
-    _dirlist = map.valid_dirs;                                             \
-    _total = map.num_valid_dirs;                                           \
-  }                                                                        \
-                                                                           \
-  adjc_dirlist_iterate(center_tile, itr_tile, _dir, _dirlist, _total) {
+#define variable_adjc_iterate(center_tile, _tile, card_only)           \
+{                                                                      \
+  enum direction8 *_tile##_list;                                       \
+  int _tile##_count;                                                   \
+                                                                       \
+  if (card_only) {                                                     \
+    _tile##_list = map.cardinal_dirs;                                  \
+    _tile##_count = map.num_cardinal_dirs;                             \
+  } else {                                                             \
+    _tile##_list = map.valid_dirs;                                     \
+    _tile##_count = map.num_valid_dirs;                                        
\
+  }                                                                    \
+  adjc_dirlist_iterate(center_tile, _tile, _tile##_dir,                        
\
+                      _tile##_list, _tile##_count) {
 
-#define variable_adjc_iterate_end                                          \
-  } adjc_dirlist_iterate_end;                                              \
+#define variable_adjc_iterate_end                                      \
+  } adjc_dirlist_iterate_end;                                          \
 }
 
 
Index: common/unitlist.h
===================================================================
--- common/unitlist.h   (revision 13907)
+++ common/unitlist.h   (working copy)
@@ -27,25 +27,30 @@
     TYPED_LIST_ITERATE(struct unit, unitlist, punit)
 #define unit_list_iterate_end  LIST_ITERATE_END
 
-#define unit_list_iterate_safe(unitlist, punit)                                
    \
-{                                                                          \
-  int _size = unit_list_size(unitlist);                                        
    \
-                                                                           \
-  if (_size > 0) {                                                         \
-    int _ids[_size], _i = 0;                                               \
-                                                                           \
-    unit_list_iterate(unitlist, punit) {                                   \
-      _ids[_i++] = punit->id;                                              \
-    } unit_list_iterate_end;                                               \
-    for (_i = 0; _i < _size; _i++) {                                       \
-      struct unit *punit = find_unit_by_id(_ids[_i]);                      \
-                                                                           \
-      if (punit) {
+#define unit_list_iterate_safe(unitlist, _unit)                                
\
+{                                                                      \
+  int _unit##_size = unit_list_size(unitlist);                         \
+                                                                       \
+  if (_unit##_size > 0) {                                              \
+    int _unit##_numbers[_unit##_size];                                 \
+    int _unit##_index = 0;                                             \
+                                                                       \
+    unit_list_iterate(unitlist, _unit) {                               \
+      _unit##_numbers[_unit##_index++] = _unit->id;                    \
+    } unit_list_iterate_end;                                           \
+                                                                       \
+    for (_unit##_index = 0;                                            \
+        _unit##_index < _unit##_size;                                  \
+        _unit##_index++) {                                             \
+      struct unit *_unit =                                             \
+       find_unit_by_id(_unit##_numbers[_unit##_index]);                \
+                                                                       \
+      if (NULL != _unit) {
 
-#define unit_list_iterate_safe_end                                         \
-      }                                                                        
    \
-    }                                                                      \
-  }                                                                        \
+#define unit_list_iterate_safe_end                                     \
+      }                                                                        
\
+    }                                                                  \
+  }                                                                    \
 }
 
 struct unit *unit_list_find(const struct unit_list *punitlist, int unit_id);
Index: ai/aiunit.h
===================================================================
--- ai/aiunit.h (revision 13907)
+++ ai/aiunit.h (working copy)
@@ -94,18 +94,14 @@
 
 void update_simple_ai_types(void);
 
-#define simple_ai_unit_type_iterate(m_i)                                    \
-{                                                                           \
-  int m_c;                                                                  \
-  for (m_c = 0;; m_c++) {                                                   \
-    struct unit_type * m_i = simple_ai_types[m_c];                         \
-                                                                           \
-    if (!m_i) {                                                                
    \
-      break;                                                                \
-    }
+#define simple_ai_unit_type_iterate(_ut)                               \
+{                                                                      \
+  struct unit_type *_ut;                                               \
+  int _ut##_index = 0;                                                 \
+  while (NULL != (_ut = simple_ai_types[_ut##_index++])) {
 
-#define simple_ai_unit_type_iterate_end                                     \
- }                                                                          \
+#define simple_ai_unit_type_iterate_end                                        
\
+  }                                                                    \
 }
 
 #endif  /* FC__AIUNIT_H */
Index: ai/aicity.c
===================================================================
--- ai/aicity.c (revision 13907)
+++ ai/aicity.c (working copy)
@@ -61,18 +61,21 @@
 
 /* Iterate over cities within a certain range around a given city
  * (city_here) that exist within a given city list. */
-#define city_range_iterate(city_here, list, range, city)            \
-{                                                                   \
-  Continent_id continent = tile_get_continent(city_here->tile);            \
-  city_list_iterate(list, city) {                                   \
-    if ((range == REQ_RANGE_CITY && city == city_here)              \
-        || (range == REQ_RANGE_LOCAL && city == city_here)          \
-        || (range == REQ_RANGE_CONTINENT                            \
-            && tile_get_continent(city->tile) == continent)        \
-        || (range == REQ_RANGE_PLAYER)) {
-#define city_range_iterate_end \
-  } } city_list_iterate_end; }
+#define city_range_iterate(city_here, list, range, city)               \
+{                                                                      \
+  city_list_iterate(list, city) {                                      \
+    if (range == REQ_RANGE_PLAYER                                      \
+     || ((range == REQ_RANGE_CITY || range == REQ_RANGE_LOCAL)         \
+      && city == city_here)                                            \
+     || (range == REQ_RANGE_CONTINENT                                  \
+      && tile_get_continent(city->tile) ==                             \
+        tile_get_continent(city_here->tile))) {
 
+#define city_range_iterate_end                                         \
+    }                                                                  \
+  } city_list_iterate_end;                                             \
+}
+
 #define CITY_EMERGENCY(pcity)                        \
  (pcity->surplus[O_SHIELD] < 0 || city_unhappy(pcity)   \
   || pcity->food_stock + pcity->surplus[O_FOOD] < 0)
Index: client/agents/cma_core.c
===================================================================
--- client/agents/cma_core.c    (revision 13907)
+++ client/agents/cma_core.c    (working copy)
@@ -78,13 +78,13 @@
   int apply_result_ignored, apply_result_applied, refresh_forced;
 } stats;
 
-#define my_city_map_iterate(pcity, cx, cy) {                           \
-  city_map_checked_iterate(pcity->tile, cx, cy, _ptile) { \
+#define my_city_map_iterate(pcity, cx, cy) {                           \
+  city_map_checked_iterate(pcity->tile, cx, cy, cx##cy##_ptile) {      \
     if (!is_free_worked_tile(cx, cy)) {
 
-#define my_city_map_iterate_end \
-    }                                \
-  } city_map_checked_iterate_end;    \
+#define my_city_map_iterate_end                                                
\
+    }                                                                  \
+  } city_map_checked_iterate_end;                                      \
 }
 
 
Index: client/citydlg_common.c
===================================================================
--- client/citydlg_common.c     (revision 13907)
+++ client/citydlg_common.c     (working copy)
@@ -142,29 +142,28 @@
 
 /* Iterate over all known tiles in the city.  This iteration follows the
  * painter's algorithm and can be used for drawing. */
-#define citydlg_iterate(pcity, ptile, pedge, pcorner, canvas_x, canvas_y)   \
-{                                                                          \
-  int _my_gui_x0, _my_gui_y0;                                              \
-  struct city *_pcity = (pcity);                                           \
-  const int _my_width = get_citydlg_canvas_width();                        \
-  const int _my_height = get_citydlg_canvas_height();                      \
-                                                                           \
-  map_to_gui_vector(tileset, &_my_gui_x0, &_my_gui_y0,                     \
-                   _pcity->tile->x, _pcity->tile->y);                      \
-  _my_gui_x0 -= (_my_width - tileset_tile_width(tileset)) / 2;             \
-  _my_gui_y0 -= (_my_height - tileset_tile_height(tileset)) / 2;           \
-  freelog(LOG_DEBUG, "citydlg: %d,%d + %dx%d",                             \
-         _my_gui_x0, _my_gui_y0, _my_width, _my_height);                   \
-                                                                           \
-  gui_rect_iterate(_my_gui_x0, _my_gui_y0, _my_width, _my_height,          \
-                  ptile, pedge, pcorner, _gui_x, _gui_y) {                 \
-    const int canvas_x = _gui_x - _my_gui_x0;                              \
-    const int canvas_y = _gui_y - _my_gui_y0;                              \
+#define citydlg_iterate(pcity, ptile, pedge, pcorner, _x, _y)          \
+{                                                                      \
+  int _x##_0, _y##_0;                                                  \
+  const int _x##_w = get_citydlg_canvas_width();                       \
+  const int _y##_h = get_citydlg_canvas_height();                      \
+                                                                       \
+  map_to_gui_vector(tileset, &_x##_0, &_y##_0,                         \
+                   (pcity)->tile->x, (pcity)->tile->y);                \
+  _x##_0 -= (_x##_w - tileset_tile_width(tileset)) / 2;                        
\
+  _y##_0 -= (_y##_h - tileset_tile_height(tileset)) / 2;               \
+  freelog(LOG_DEBUG, "citydlg: %d,%d + %dx%d",                         \
+         _x##_0, _y##_0, _x##_w, _y##_h);                              \
+                                                                       \
+  gui_rect_iterate(_x##_0, _y##_0, _x##_w, _y##_h,                     \
+                  ptile, pedge, pcorner, _x##_g, _y##_g) {             \
+    const int _x = _x##_g - _x##_0;                                    \
+    const int _y = _y##_g - _y##_0;                                    \
     {
 
-#define citydlg_iterate_end                                                \
-    }                                                                       \
-  } gui_rect_iterate_end;                                                  \
+#define citydlg_iterate_end                                            \
+    }                                                                  \
+  } gui_rect_iterate_end;                                              \
 }
 
 /****************************************************************************
Index: client/mapview_common.h
===================================================================
--- client/mapview_common.h     (revision 13907)
+++ client/mapview_common.h     (working copy)
@@ -58,157 +58,158 @@
  * The order of iteration is guaranteed to satisfy the painter's algorithm.
  * The iteration covers not only tiles but tile edges and corners.
  *
- * gui_x0, gui_y0: gives the GUI origin of the rectangle.
- * width, height: gives the GUI width and height of the rectangle.  These
- * values may be negative.
+ * GRI_x0, GRI_y0: gives the GUI origin of the rectangle.
  *
- * ptile, pedge, pcorner: gives the tile, edge, or corner that is being
- * iterated over.  These are declared inside the macro.  Usually only
- * one of them will be non-NULL at a time.  These values may be passed in
- * directly to fill_sprite_array.
+ * GRI_width, GRI_height: gives the GUI width and height of the rectangle.
+ * These values may be negative.
  *
- * canvas_x, canvas_y: the canvas position of the current element.  Each
- * element is assumed to be tileset_tile_width(tileset) * 
tileset_tile_height(tileset) in
- * size.  If an element is larger the caller needs to use a larger rectangle
- * of iteration.
+ * _t, _e, _c: the tile, edge, or corner that is being iterated, declared
+ * inside the macro.  Usually, only one of them will be non-NULL at a time.
+ * These values may be passed directly to fill_sprite_array().
  *
+ * _x, _y: the canvas position of the current element, declared inside
+ * the macro.  Each element is assumed to be tileset_tile_width(tileset) *
+ * tileset_tile_height(tileset) in size.  If an element is larger, the 
+ * caller needs to use a larger rectangle of iteration.
+ *
  * The grid of iteration is rather complicated.  For a picture of it see
  * http://bugs.freeciv.org/Ticket/Attachment/89565/56824/newgrid.png
  * or the other text in PR#12085.
  */
-#define gui_rect_iterate(GRI_gui_x0, GRI_gui_y0, width, height,                
    \
-                        ptile, pedge, pcorner, gui_x, gui_y)               \
-{                                                                          \
-  int _gui_x0 = (GRI_gui_x0), _gui_y0 = (GRI_gui_y0);                      \
-  int _width = (width), _height = (height);                                \
-                                                                           \
-  if (_width < 0) {                                                        \
-    _gui_x0 += _width;                                                     \
-    _width = -_width;                                                      \
-  }                                                                        \
-  if (_height < 0) {                                                       \
-    _gui_y0 += _height;                                                        
    \
-    _height = -_height;                                                        
    \
-  }                                                                        \
-  if (_width > 0 && _height > 0) {                                         \
-    const int _ratio = (tileset_is_isometric(tileset) ? 2 : 1);                
    \
-    const int _r = _ratio * 2;                                             \
-    const int _Wr = tileset_tile_width(tileset);                               
            \
-    const int _Hr = tileset_tile_height(tileset);                              
            \
-    /* Don't divide by _r yet, to avoid integer rounding errors. */        \
-    const int GRI_x0 = DIVIDE(_gui_x0 * _r, _Wr) - _ratio / 2;         \
-    const int GRI_y0 = DIVIDE(_gui_y0 * _r, _Hr) - _ratio / 2;         \
-    const int GRI_x1 = DIVIDE((_gui_x0 + _width) * _r + _Wr - 1,           \
-                             _Wr) + _ratio;                                \
-    const int GRI_y1 = DIVIDE((_gui_y0 + _height) * _r + _Hr - 1,          \
-                             _Hr) + _ratio;                                \
-    const int _count = (GRI_x1 - GRI_x0) * (GRI_y1 - GRI_y0);              \
-    int GRI_itr, GRI_x_itr, GRI_y_itr, GRI_sum, GRI_diff;                  \
-                                                                           \
-    freelog(LOG_DEBUG, "Iterating over %d-%d x %d-%d rectangle.",          \
-           GRI_x1, GRI_x0, GRI_y1, GRI_y0);                                \
-    for (GRI_itr = 0; GRI_itr < _count; GRI_itr++) {                       \
-      struct tile *ptile = NULL;                                           \
-      struct tile_edge *pedge = NULL;                                      \
-      struct tile_corner *pcorner = NULL;                                  \
-      struct tile_edge GRI_edge;                                           \
-      struct tile_corner GRI_corner;                                       \
-      int gui_x, gui_y;                                                        
    \
-                                                                           \
-      GRI_x_itr = GRI_x0 + (GRI_itr % (GRI_x1 - GRI_x0));                  \
-      GRI_y_itr = GRI_y0 + (GRI_itr / (GRI_x1 - GRI_x0));                  \
-      GRI_sum = GRI_x_itr + GRI_y_itr;                                     \
-      GRI_diff = GRI_y_itr - GRI_x_itr;                                        
    \
-      if (tileset_is_isometric(tileset)) {                                 \
-       if ((GRI_x_itr + GRI_y_itr) % 2 != 0) {                             \
-         continue;                                                         \
-       }                                                                   \
-       if (GRI_x_itr % 2 == 0 && GRI_y_itr % 2 == 0) {                     \
-         if ((GRI_x_itr + GRI_y_itr) % 4 == 0) {                           \
-           /* Tile */                                                      \
-           ptile = map_pos_to_tile(GRI_sum / 4 - 1, GRI_diff / 4);         \
-         } else {                                                          \
-           /* Corner */                                                    \
-           pcorner = &GRI_corner;                                          \
-           pcorner->tile[0] = map_pos_to_tile((GRI_sum - 6) / 4,           \
-                                              (GRI_diff - 2) / 4);         \
-           pcorner->tile[1] = map_pos_to_tile((GRI_sum - 2) / 4,           \
-                                              (GRI_diff - 2) / 4);         \
-           pcorner->tile[2] = map_pos_to_tile((GRI_sum - 2) / 4,           \
-                                              (GRI_diff + 2) / 4);         \
-           pcorner->tile[3] = map_pos_to_tile((GRI_sum - 6) / 4,           \
-                                              (GRI_diff + 2) / 4);         \
-           if (tileset_hex_width(tileset) > 0) {                           \
-             pedge = &GRI_edge;                                            \
-             pedge->type = EDGE_UD;                                        \
-             pedge->tile[0] = pcorner->tile[0];                            \
-             pedge->tile[1] = pcorner->tile[2];                            \
-           } else if (tileset_hex_height(tileset) > 0) {                   \
-             pedge = &GRI_edge;                                            \
-             pedge->type = EDGE_LR;                                        \
-             pedge->tile[0] = pcorner->tile[1];                            \
-             pedge->tile[1] = pcorner->tile[3];                            \
-           }                                                               \
-         }                                                                 \
-       } else {                                                            \
-         /* Edge. */                                                       \
-         pedge = &GRI_edge;                                                \
-         if (GRI_sum % 4 == 0) {                                           \
-           pedge->type = EDGE_NS;                                          \
-           pedge->tile[0] = map_pos_to_tile((GRI_sum - 4) / 4, /* N */     \
-                                            (GRI_diff - 2) / 4);           \
-           pedge->tile[1] = map_pos_to_tile((GRI_sum - 4) / 4, /* S */     \
-                                            (GRI_diff + 2) / 4);           \
-         } else {                                                          \
-           pedge->type = EDGE_WE;                                          \
-           pedge->tile[0] = map_pos_to_tile((GRI_sum - 6) / 4,             \
-                                            GRI_diff / 4); /* W */         \
-           pedge->tile[1] = map_pos_to_tile((GRI_sum - 2) / 4,             \
-                                            GRI_diff / 4); /* E */         \
-         }                                                                 \
-       }                                                                   \
-      } else {                                                             \
-       if (GRI_sum % 2 == 0) {                                             \
-         if (GRI_x_itr % 2 == 0) {                                         \
-           /* Corner. */                                                   \
-           pcorner = &GRI_corner;                                          \
-           pcorner->tile[0] = map_pos_to_tile(GRI_x_itr / 2 - 1,           \
-                                              GRI_y_itr / 2 - 1); /* NW */ \
-           pcorner->tile[1] = map_pos_to_tile(GRI_x_itr / 2,               \
-                                              GRI_y_itr / 2 - 1); /* NE */ \
-           pcorner->tile[2] = map_pos_to_tile(GRI_x_itr / 2,               \
-                                              GRI_y_itr / 2); /* SE */     \
-           pcorner->tile[3] = map_pos_to_tile(GRI_x_itr / 2 - 1,           \
-                                              GRI_y_itr / 2); /* SW */     \
-         } else {                                                          \
-           /* Tile. */                                                     \
-           ptile = map_pos_to_tile((GRI_x_itr - 1) / 2,                    \
-                                   (GRI_y_itr - 1) / 2);                   \
-         }                                                                 \
-       } else {                                                            \
-         /* Edge. */                                                       \
-         pedge = &GRI_edge;                                                \
-         if (GRI_y_itr % 2 == 0) {                                         \
-           pedge->type = EDGE_NS;                                          \
-           pedge->tile[0] = map_pos_to_tile((GRI_x_itr - 1) / 2, /* N */   \
-                                            GRI_y_itr / 2 - 1);            \
-           pedge->tile[1] = map_pos_to_tile((GRI_x_itr - 1) / 2, /* S */   \
-                                            GRI_y_itr / 2);                \
-         } else {                                                          \
-           pedge->type = EDGE_WE;                                          \
-           pedge->tile[0] = map_pos_to_tile(GRI_x_itr / 2 - 1, /* W */     \
-                                            (GRI_y_itr - 1) / 2);          \
-           pedge->tile[1] = map_pos_to_tile(GRI_x_itr / 2, /* E */         \
-                                            (GRI_y_itr - 1) / 2);          \
-         }                                                                 \
-       }                                                                   \
-      }                                                                        
    \
-      gui_x = GRI_x_itr * _Wr / _r - tileset_tile_width(tileset) / 2;          
    \
-      gui_y = GRI_y_itr * _Hr / _r - tileset_tile_height(tileset) / 2;
+#define gui_rect_iterate(GRI_x0, GRI_y0, GRI_width, GRI_height,                
\
+                        _t, _e, _c, _x, _y)                            \
+{                                                                      \
+  int _x##_0 = (GRI_x0), _y##_0 = (GRI_y0);                            \
+  int _x##_w = (GRI_width), _y##_h = (GRI_height);                     \
+                                                                       \
+  if (_x##_w < 0) {                                                    \
+    _x##_0 += _x##_w;                                                  \
+    _x##_w = -_x##_w;                                                  \
+  }                                                                    \
+  if (_y##_h < 0) {                                                    \
+    _y##_0 += _y##_h;                                                  \
+    _y##_h = -_y##_h;                                                  \
+  }                                                                    \
+  if (_x##_w > 0 && _y##_h > 0) {                                      \
+    struct tile_edge _t##_e;                                           \
+    struct tile_corner _t##_c;                                         \
+    int _t##_xi, _t##_yi, _t##_si, _t##_di;                            \
+    int _x, _y;                                                                
\
+    const int _t##_r1 = (tileset_is_isometric(tileset) ? 2 : 1);       \
+    const int _t##_r2 = _t##_r1 * 2; /* double the ratio */            \
+    const int _t##_w = tileset_tile_width(tileset);                    \
+    const int _t##_h = tileset_tile_height(tileset);                   \
+    /* Don't divide by _r2 yet, to avoid integer rounding errors. */   \
+    const int _t##_x0 = DIVIDE(_x##_0 * _t##_r2, _t##_w) - _t##_r1 / 2;        
\
+    const int _t##_y0 = DIVIDE(_y##_0 * _t##_r2, _t##_h) - _t##_r1 / 2;        
\
+    const int _t##_x1 = DIVIDE((_x##_0 + _x##_w) * _t##_r2 + _t##_w - 1,\
+                              _t##_w) + _t##_r1;                       \
+    const int _t##_y1 = DIVIDE((_y##_0 + _y##_h) * _t##_r2 + _t##_h - 1,\
+                              _t##_h) + _t##_r1;                       \
+    const int _t##_count = (_t##_x1 - _t##_x0) * (_t##_y1 - _t##_y0);  \
+    int _t##_index = 0;                                                        
\
+                                                                       \
+    freelog(LOG_DEBUG, "Iterating over %d-%d x %d-%d rectangle.",      \
+           _t##_x1, _t##_x0, _t##_y1, _t##_y0);                        \
+    for (; _t##_index < _t##_count; _t##_index++) {                    \
+      struct tile *_t = NULL;                                          \
+      struct tile_edge *_e = NULL;                                     \
+      struct tile_corner *_c = NULL;                                   \
+                                                                       \
+      _t##_xi = _t##_x0 + (_t##_index % (_t##_x1 - _t##_x0));          \
+      _t##_yi = _t##_y0 + (_t##_index / (_t##_x1 - _t##_x0));          \
+      _t##_si = _t##_xi + _t##_yi;                                     \
+      _t##_di = _t##_yi - _t##_xi;                                     \
+      if (2 == _t##_r1 /*tileset_is_isometric(tileset)*/) {            \
+       if ((_t##_xi + _t##_yi) % 2 != 0) {                             \
+         continue;                                                     \
+       }                                                               \
+       if (_t##_xi % 2 == 0 && _t##_yi % 2 == 0) {                     \
+         if ((_t##_xi + _t##_yi) % 4 == 0) {                           \
+           /* Tile */                                                  \
+           _t = map_pos_to_tile(_t##_si / 4 - 1, _t##_di / 4);         \
+         } else {                                                      \
+           /* Corner */                                                \
+           _c = &_t##_c;                                               \
+           _c->tile[0] = map_pos_to_tile((_t##_si - 6) / 4,            \
+                                         (_t##_di - 2) / 4);           \
+           _c->tile[1] = map_pos_to_tile((_t##_si - 2) / 4,            \
+                                         (_t##_di - 2) / 4);           \
+           _c->tile[2] = map_pos_to_tile((_t##_si - 2) / 4,            \
+                                         (_t##_di + 2) / 4);           \
+           _c->tile[3] = map_pos_to_tile((_t##_si - 6) / 4,            \
+                                         (_t##_di + 2) / 4);           \
+           if (tileset_hex_width(tileset) > 0) {                       \
+             _e = &_t##_e;                                             \
+             _e->type = EDGE_UD;                                       \
+             _e->tile[0] = _c->tile[0];                                \
+             _e->tile[1] = _c->tile[2];                                \
+           } else if (tileset_hex_height(tileset) > 0) {               \
+             _e = &_t##_e;                                             \
+             _e->type = EDGE_LR;                                       \
+             _e->tile[0] = _c->tile[1];                                \
+             _e->tile[1] = _c->tile[3];                                \
+           }                                                           \
+         }                                                             \
+       } else {                                                        \
+         /* Edge. */                                                   \
+         _e = &_t##_e;                                                 \
+         if (_t##_si % 4 == 0) {                                       \
+           _e->type = EDGE_NS;                                         \
+           _e->tile[0] = map_pos_to_tile((_t##_si - 4) / 4,            \
+                                         (_t##_di - 2) / 4);   /*N*/   \
+           _e->tile[1] = map_pos_to_tile((_t##_si - 4) / 4,            \
+                                         (_t##_di + 2) / 4);   /*S*/   \
+         } else {                                                      \
+           _e->type = EDGE_WE;                                         \
+           _e->tile[0] = map_pos_to_tile((_t##_si - 6) / 4,            \
+                                         _t##_di / 4);         /*W*/   \
+           _e->tile[1] = map_pos_to_tile((_t##_si - 2) / 4,            \
+                                         _t##_di / 4);         /*E*/   \
+         }                                                             \
+       }                                                               \
+      } else {                                                         \
+       if (_t##_si % 2 == 0) {                                         \
+         if (_t##_xi % 2 == 0) {                                       \
+           /* Corner. */                                               \
+           _c = &_t##_c;                                               \
+           _c->tile[0] = map_pos_to_tile(_t##_xi / 2 - 1,              \
+                                         _t##_yi / 2 - 1);     /*NW*/  \
+           _c->tile[1] = map_pos_to_tile(_t##_xi / 2,                  \
+                                         _t##_yi / 2 - 1);     /*NE*/  \
+           _c->tile[2] = map_pos_to_tile(_t##_xi / 2,                  \
+                                         _t##_yi / 2);         /*SE*/  \
+           _c->tile[3] = map_pos_to_tile(_t##_xi / 2 - 1,              \
+                                         _t##_yi / 2);         /*SW*/  \
+         } else {                                                      \
+           /* Tile. */                                                 \
+           _t = map_pos_to_tile((_t##_xi - 1) / 2,                     \
+                                (_t##_yi - 1) / 2);                    \
+         }                                                             \
+       } else {                                                        \
+         /* Edge. */                                                   \
+         _e = &_t##_e;                                                 \
+         if (_t##_yi % 2 == 0) {                                       \
+           _e->type = EDGE_NS;                                         \
+           _e->tile[0] = map_pos_to_tile((_t##_xi - 1) / 2,            \
+                                         _t##_yi / 2 - 1);     /*N*/   \
+           _e->tile[1] = map_pos_to_tile((_t##_xi - 1) / 2,            \
+                                         _t##_yi / 2);         /*S*/   \
+         } else {                                                      \
+           _e->type = EDGE_WE;                                         \
+           _e->tile[0] = map_pos_to_tile(_t##_xi / 2 - 1,              \
+                                         (_t##_yi - 1) / 2);   /*W*/   \
+           _e->tile[1] = map_pos_to_tile(_t##_xi / 2,                  \
+                                         (_t##_yi - 1) / 2);   /*E*/   \
+         }                                                             \
+       }                                                               \
+      }                                                                        
\
+      _x = _t##_xi * _t##_w / _t##_r2 - _t##_w / 2;                    \
+      _y = _t##_yi * _t##_h / _t##_r2 - _t##_h / 2;
 
-#define gui_rect_iterate_end                                               \
-    }                                                                      \
-  }                                                                        \
+#define gui_rect_iterate_end                                           \
+    }                                                                  \
+  }                                                                    \
 }
 
 void refresh_tile_mapcanvas(struct tile *ptile,
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to