Complete.Org: Mailing Lists: Archives: freeciv-dev: October 2001:
[Freeciv-Dev] Re: PATCH: LOAD_MAP_DATA
Home

[Freeciv-Dev] Re: PATCH: LOAD_MAP_DATA

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev <freeciv-dev@xxxxxxxxxxx>
Subject: [Freeciv-Dev] Re: PATCH: LOAD_MAP_DATA
From: Jason Dorje Short <vze2zq63@xxxxxxxxxxx>
Date: Fri, 12 Oct 2001 19:30:35 -0400
Reply-to: jdorje@xxxxxxxxxxxx

Patch attached.

jason
? rc
? check_coords
? old
? topology
? core-2
? gmon.out
? gprof.regular.txt
? gprof.inline.txt
? civserver-inline
? civserver-regular
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.34
diff -u -r1.34 savegame.c
--- server/savegame.c   2001/10/12 12:58:00     1.34
+++ server/savegame.c   2001/10/12 23:28:56
@@ -50,9 +50,26 @@
 
 #include "savegame.h"
 
-
+/* This returns a hex value of the given halfbyte of the
+   decimal value.  For instance
+     DEC2HEX(0xa00, 2) == 'a' */
 #define DEC2HEX(int_value, halfbyte_wanted) \
   dec2hex[((int_value) >> ((halfbyte_wanted) * 4)) & 0xf]
+/* This returns a decimal value of the hex char, offset
+   by the given number of halfbytes.  For instance
+     HEX2DEC('a', 2) == 0xa00 */
+#define HEX2DEC(char_value, halfbyte_wanted)            \
+      (                                                 \
+        isxdigit(char_value)                            \
+          ?                                                        \
+           (((char_value)-(isdigit(char_value) ? '0' : 'a'-10)) << (4 * 
(halfbyte_wanted))) \
+          : (                                                                  
          \
+              ((char_value) != ' ')                                            
            \
+               ?                                                       \
+                 (abort(), 0)          \
+                : 0                                                           \
+            )                  \
+      )
 static const char dec2hex[] = "0123456789abcdef";
 static const char terrain_chars[] = "adfghjm prstu";
 
@@ -96,6 +113,33 @@
                      secfile_insert_str(secfile, line, secfile_name,     \
                                         plrno, y))
 
+/*
+ * This loops over the entire map to load data. It loads all the
+ * data of a line using secfile_lookup_line and then executes the
+ * set_xy_char code. The macro provides the variables x and y
+ * and ch (ch is the current character of the line). Parameters:
+ * - set_xy_char: code that sets the character for each (x, y)
+ * coordinate.
+ *  - secfile_lookup_line: code which is executed every time a line is
+ *  processed; it returns the char* for the line
+ */
+#define LOAD_MAP_DATA(secfile_lookup_line, set_xy_char) \
+{                                                       \
+  int x, y;                                             \
+  for (y = 0; y < map.ysize; y++) {                     \
+    char *line = secfile_lookup_line;                   \
+    assert(line);                                       \
+    for(x = 0; x < map.xsize; x++) {                    \
+      char ch = line[x];                                \
+      if (is_normal_map_pos(x, y)) {                    \
+       set_xy_char;                                    \
+      } else {                                          \
+       assert(ch == '#');                              \
+      }                                                 \
+    }                                                   \
+  }                                                     \
+}
+
 /* Following does not include "unirandom", used previously; add it if
  * appropriate.  (Code no longer looks at "unirandom", but should still
  * include it when appropriate for maximum savegame compatibility.)
@@ -206,8 +250,6 @@
 ***************************************************************/
 static void map_tiles_load(struct section_file *file)
 {
-  int x, y;
-
   map.is_earth=secfile_lookup_int(file, "map.is_earth");
 
   /* In some cases we read these before, but not always, and
@@ -219,18 +261,17 @@
   map_allocate();
 
   /* get the terrain type */
-  for(y=0; y<map.ysize; y++) {
-    char *terline=secfile_lookup_str(file, "map.t%03d", y);
-    for(x=0; x<map.xsize; x++) {
-      char *pch;
-      if(!(pch=strchr(terrain_chars, terline[x]))) {
-       freelog(LOG_FATAL, "unknown terrain type (map.t) in map "
-               "at position (%d,%d): %d '%c'", x, y, terline[x], terline[x]);
-       exit(1);
-      }
-      map_get_tile(x, y)->terrain=pch-terrain_chars;
-    }
-  }
+  LOAD_MAP_DATA(secfile_lookup_str(file, "map.t%03d", y),
+               {
+                 char *pch = strchr(terrain_chars, ch);
+                 if(!pch) {
+                   freelog(LOG_FATAL, "unknown terrain type (map.t) in map "
+                   "at position (%d,%d): %d '%c'", x, y, ch, ch);
+                   exit(1);
+                 }
+                 map_get_tile(x, y)->terrain = pch-terrain_chars;
+               }
+  );
 
   assign_continent_numbers();
 }
@@ -246,28 +287,10 @@
 ***************************************************************/
 static void map_rivers_overlay_load(struct section_file *file)
 {
-  int x, y;
-
   /* get "next" 4 bits of special flags;
      extract the rivers overlay from them */
-  for(y=0; y<map.ysize; y++) {
-    char *terline=secfile_lookup_str_default(file, NULL, "map.n%03d", y);
-
-    if (terline) {
-      for(x=0; x<map.xsize; x++) {
-       char ch=terline[x];
-
-       if(isxdigit(ch)) {
-         map_get_tile(x, y)->special |=
-           ((ch-(isdigit(ch) ? '0' : 'a'-10))<<8) & S_RIVER;
-       } else if(ch!=' ') {
-         freelog(LOG_FATAL, "unknown rivers overlay flag (map.n) in map "
-                 "at position(%d,%d): %d '%c'", x, y, ch, ch);
-         exit(1);
-       }
-      }
-    }
-  }
+  LOAD_MAP_DATA(secfile_lookup_str_default(file, NULL, "map.n%03d", y),
+               map_get_tile(x, y)->special |= HEX2DEC(ch, 2) & S_RIVER);
   map.have_rivers_overlay = 1;
 }
 
@@ -276,7 +299,6 @@
 ***************************************************************/
 static void map_load(struct section_file *file)
 {
-  int x ,y;
   char *savefile_options = get_savefile_options(file);
 
   /* map_init();
@@ -293,210 +315,42 @@
     map.fixed_start_positions = 0;
   }
 
-  /* get lower 4 bits of special flags */
-  for(y=0; y<map.ysize; y++) {
-    char *terline=secfile_lookup_str(file, "map.l%03d", y);
-
-    for(x=0; x<map.xsize; x++) {
-      char ch=terline[x];
-
-      if(isxdigit(ch)) {
-       map_get_tile(x, y)->special=ch-(isdigit(ch) ? '0' : ('a'-10));
-      } else if(ch!=' ') {
-       freelog(LOG_FATAL, "unknown special flag(lower) (map.l) in map "
-           "at position(%d,%d): %d '%c'", x, y, ch, ch);
-       exit(1);
-      }
-      else
-       map_get_tile(x, y)->special=S_NO_SPECIAL;
-    }
-  }
+  /* get 4-bit segments of 16-bit "special" field. */
+  /* The old code would skip over lines that didn't exist, but
+     the LOAD_MAP_DATA macro does not currently do this.  We do
+     assert that each line exists, though. */
+  LOAD_MAP_DATA(secfile_lookup_str(file, "map.l%03d", y),
+               map_get_tile(x, y)->special = HEX2DEC(ch, 0));
+  LOAD_MAP_DATA(secfile_lookup_str(file, "map.u%03d", y),
+               map_get_tile(x, y)->special |= HEX2DEC(ch, 1));
+  LOAD_MAP_DATA(secfile_lookup_str_default(file, NULL, "map.n%03d", y),
+               map_get_tile(x, y)->special |= HEX2DEC(ch, 2));
+  LOAD_MAP_DATA(secfile_lookup_str_default(file, NULL, "map.f%03d", y),
+               map_get_tile(x, y)->special |= HEX2DEC(ch, 3));
 
-  /* get upper 4 bits of special flags */
-  for(y=0; y<map.ysize; y++) {
-    char *terline=secfile_lookup_str(file, "map.u%03d", y);
-
-    for(x=0; x<map.xsize; x++) {
-      char ch=terline[x];
-
-      if(isxdigit(ch)) {
-       map_get_tile(x, y)->special|=(ch-(isdigit(ch) ? '0' : 'a'-10))<<4;
-      } else if(ch!=' ') {
-       freelog(LOG_FATAL, "unknown special flag(upper) (map.u) in map "
-               "at position(%d,%d): %d '%c'", x, y, ch, ch);
-       exit(1);
-      }
-    }
-  }
-
-  /* get "next" 4 bits of special flags */
-  for(y=0; y<map.ysize; y++) {
-    char *terline=secfile_lookup_str_default(file, NULL, "map.n%03d", y);
-
-    if (terline) {
-      for(x=0; x<map.xsize; x++) {
-       char ch=terline[x];
-
-       if(isxdigit(ch)) {
-         map_get_tile(x, y)->special|=(ch-(isdigit(ch) ? '0' : 'a'-10))<<8;
-       } else if(ch!=' ') {
-         freelog(LOG_FATAL, "unknown special flag(next) (map.n) in map "
-                 "at position(%d,%d): %d '%c'", x, y, ch, ch);
-         exit(1);
-       }
-      }
-    }
-  }
-
-  /* get "final" 4 bits of special flags */
-  for(y=0; y<map.ysize; y++) {
-    char *terline=secfile_lookup_str_default(file, NULL, "map.f%03d", y);
-
-    if (terline) {
-      for(x=0; x<map.xsize; x++) {
-       char ch=terline[x];
-
-       if(isxdigit(ch)) {
-         map_get_tile(x, y)->special|=(ch-(isdigit(ch) ? '0' : 'a'-10))<<12;
-       } else if(ch!=' ') {
-         freelog(LOG_FATAL, "unknown special flag(final) (map.f) in map "
-                 "at position(%d,%d): %d '%c'", x, y, ch, ch);
-         exit(1);
-       }
-      }
-    }
-  }
-
   if (secfile_lookup_int_default(file, 1, "game.save_known")
       && game.load_options.load_known) {
-    /* get bits 0-3 of known flags */
-    for(y=0; y<map.ysize; y++) {
-      char *terline=secfile_lookup_str(file, "map.a%03d", y);
-      for(x=0; x<map.xsize; x++) {
-       char ch=terline[x];
-       map_get_tile(x,y)->sent=0;
-       if(isxdigit(ch)) {
-         map_get_tile(x, y)->known=ch-(isdigit(ch) ? '0' : ('a'-10));
-       } else if(ch!=' ') {
-         freelog(LOG_FATAL, "unknown known flag (map.a) in map "
-                 "at position(%d,%d): %d '%c'", x, y, ch, ch);
-         exit(1);
-       }
-       else
-         map_get_tile(x, y)->known=0;
-      }
-    }
-
-    /* get bits 4-7 of known flags */
-    for(y=0; y<map.ysize; y++) {
-      char *terline=secfile_lookup_str(file, "map.b%03d", y);
-      for(x=0; x<map.xsize; x++) {
-       char ch=terline[x];
-       if(isxdigit(ch)) {
-         map_get_tile(x, y)->known|=(ch-(isdigit(ch) ? '0' : 'a'-10))<<4;
-       } else if(ch!=' ') {
-         freelog(LOG_FATAL, "unknown known flag (map.b) in map "
-                 "at position(%d,%d): %d '%c'", x, y, ch, ch);
-         exit(1);
-       }
-      }
-    }
-
-    /* get bits 8-11 of known flags */
-    for(y=0; y<map.ysize; y++) {
-      char *terline=secfile_lookup_str(file, "map.c%03d", y);
-      for(x=0; x<map.xsize; x++) {
-       char ch=terline[x];
-       if(isxdigit(ch)) {
-         map_get_tile(x, y)->known|=(ch-(isdigit(ch) ? '0' : 'a'-10))<<8;
-       } else if(ch!=' ') {
-         freelog(LOG_FATAL, "unknown known flag (map.c) in map "
-                 "at position(%d,%d): %d '%c'", x, y, ch, ch);
-         exit(1);
-       }
-      }
-    }
 
-    /* get bits 12-15 of known flags */
-    for(y=0; y<map.ysize; y++) {
-      char *terline=secfile_lookup_str(file, "map.d%03d", y);
-      for(x=0; x<map.xsize; x++) {
-       char ch=terline[x];
-
-       if(isxdigit(ch)) {
-         map_get_tile(x, y)->known|=(ch-(isdigit(ch) ? '0' : 'a'-10))<<12;
-       } else if(ch!=' ') {
-         freelog(LOG_FATAL, "unknown known flag (map.d) in map "
-                 "at position(%d,%d): %d '%c'", x, y, ch, ch);
-         exit(1);
-       }
-      }
-    }
+    /* get 4-bit segments of the first half of the 32-bit "known" field */
+    LOAD_MAP_DATA(secfile_lookup_str(file, "map.a%03d", y),
+                 map_get_tile(x, y)->known |= HEX2DEC(ch, 0));
+    LOAD_MAP_DATA(secfile_lookup_str(file, "map.b%03d", y),
+                 map_get_tile(x, y)->known |= HEX2DEC(ch, 1));
+    LOAD_MAP_DATA(secfile_lookup_str(file, "map.c%03d", y),
+                 map_get_tile(x, y)->known |= HEX2DEC(ch, 2));
+    LOAD_MAP_DATA(secfile_lookup_str(file, "map.d%03d", y),
+                 map_get_tile(x, y)->known |= HEX2DEC(ch, 3));
 
     if (has_capability("known32fix", savefile_options)) {
-      /* get bits 16-19 of known flags */
-      for(y=0; y<map.ysize; y++) {
-       char *terline=secfile_lookup_str(file, "map.e%03d", y);
-       for(x=0; x<map.xsize; x++) {
-         char ch=terline[x];
-
-         if(isxdigit(ch)) {
-           map_get_tile(x, y)->known|=(ch-(isdigit(ch) ? '0' : 'a'-10))<<16;
-         } else if(ch!=' ') {
-           freelog(LOG_FATAL, "unknown known flag (map.e) in map "
-                   "at position(%d,%d): %d '%c'", x, y, ch, ch);
-           exit(1);
-         }
-       }
-      }
-
-      /* get bits 20-23 of known flags */
-      for(y=0; y<map.ysize; y++) {
-       char *terline=secfile_lookup_str(file, "map.g%03d", y);
-       for(x=0; x<map.xsize; x++) {
-         char ch=terline[x];
-
-         if(isxdigit(ch)) {
-           map_get_tile(x, y)->known|=(ch-(isdigit(ch) ? '0' : 'a'-10))<<20;
-         } else if(ch!=' ') {
-           freelog(LOG_FATAL, "unknown known flag (map.g) in map "
-                   "at position(%d,%d): %d '%c'", x, y, ch, ch);
-           exit(1);
-         }
-       }
-      }
-
-      /* get bits 24-27 of known flags */
-      for(y=0; y<map.ysize; y++) {
-       char *terline=secfile_lookup_str(file, "map.h%03d", y);
-       for(x=0; x<map.xsize; x++) {
-         char ch=terline[x];
-
-         if(isxdigit(ch)) {
-           map_get_tile(x, y)->known|=(ch-(isdigit(ch) ? '0' : 'a'-10))<<24;
-         } else if(ch!=' ') {
-           freelog(LOG_FATAL, "unknown known flag (map.h) in map "
-                   "at position(%d,%d): %d '%c'", x, y, ch, ch);
-           exit(1);
-         }
-       }
-      }
-
-      /* get bits 28-31 of known flags */
-      for(y=0; y<map.ysize; y++) {
-       char *terline=secfile_lookup_str(file, "map.i%03d", y);
-       for(x=0; x<map.xsize; x++) {
-         char ch=terline[x];
-
-         if(isxdigit(ch)) {
-           map_get_tile(x, y)->known|=(ch-(isdigit(ch) ? '0' : 'a'-10))<<28;
-         } else if(ch!=' ') {
-           freelog(LOG_FATAL, "unknown known flag (map.i) in map "
-                   "at position(%d,%d): %d '%c'", x, y, ch, ch);
-           exit(1);
-         }
-       }
-      }
+      /* get 4-bit segments of the second half of the 32-bit "known" field */
+      LOAD_MAP_DATA(secfile_lookup_str(file, "map.e%03d", y),
+                   map_get_tile(x, y)->known |= HEX2DEC(ch, 4));
+      LOAD_MAP_DATA(secfile_lookup_str(file, "map.g%03d", y),
+                   map_get_tile(x, y)->known |= HEX2DEC(ch, 5));
+      LOAD_MAP_DATA(secfile_lookup_str(file, "map.h%03d", y),
+                   map_get_tile(x, y)->known |= HEX2DEC(ch, 6));
+      LOAD_MAP_DATA(secfile_lookup_str(file, "map.i%03d", y),
+                   map_get_tile(x, y)->known |= HEX2DEC(ch, 7));
     }
   }
 
@@ -1219,120 +1073,39 @@
       && secfile_lookup_int_default(file, -1,"player%d.total_ncities", plrno) 
!= -1
       && secfile_lookup_int_default(file, 1, "game.save_private_map")
       && game.load_options.load_private_map) {
-    /* get the terrain type */
-    for(y=0; y<map.ysize; y++) {
-      char *terline=secfile_lookup_str(file, "player%d.map_t%03d", plrno, y);
-      for(x=0; x<map.xsize; x++) {
-       char *pch;
-       if(!(pch=strchr(terrain_chars, terline[x]))) {
-         freelog(LOG_FATAL, "unknown terrain type (map.t) in map "
-                 "at position (%d,%d): %d '%c'", x, y, terline[x], terline[x]);
-         exit(1);
-       }
-       map_get_player_tile(x, y, plr)->terrain=pch-terrain_chars;
-      }
-    }
-    
-    /* get lower 4 bits of special flags */
-    for(y=0; y<map.ysize; y++) {
-      char *terline=secfile_lookup_str(file, "player%d.map_l%03d",plrno, y);
-      
-      for(x=0; x<map.xsize; x++) {
-       char ch=terline[x];
-       
-       if(isxdigit(ch)) {
-         map_get_player_tile(x, y, plr)->special=ch-(isdigit(ch) ? '0' : 
('a'-10));
-       } else if(ch!=' ') {
-         freelog(LOG_FATAL, "unknown special flag(lower) (map.l) in map "
-                 "at position(%d,%d): %d '%c'", x, y, ch, ch);
-         exit(1);
-       }
-       else
-         map_get_player_tile(x, y, plr)->special=S_NO_SPECIAL;
-      }
-    }
-    
-    /* get upper 4 bits of special flags */
-    for(y=0; y<map.ysize; y++) {
-      char *terline=secfile_lookup_str(file, "player%d.map_u%03d", plrno, y);
-      
-      for(x=0; x<map.xsize; x++) {
-       char ch=terline[x];
-       
-       if(isxdigit(ch)) {
-         map_get_player_tile(x, y, plr)->special|=(ch-(isdigit(ch) ? '0' : 
'a'-10))<<4;
-       } else if(ch!=' ') {
-         freelog(LOG_FATAL, "unknown special flag(upper) (map.u) in map "
-                 "at position(%d,%d): %d '%c'", x, y, ch, ch);
-         exit(1);
-       }
-      }
-    }
-    
-    /* get "next" 4 bits of special flags */
-    for(y=0; y<map.ysize; y++) {
-      char *terline=secfile_lookup_str_default(file, NULL, 
"player%d.map_n%03d", plrno, y);
-      
-      if (terline) {
-       for(x=0; x<map.xsize; x++) {
-         char ch=terline[x];
-         
-         if(isxdigit(ch)) {
-           map_get_player_tile(x, y, plr)->special|=(ch-(isdigit(ch) ? '0' : 
'a'-10))<<8;
-         } else if(ch!=' ') {
-           freelog(LOG_FATAL, "unknown special flag(next) (map.n) in map "
-                   "at position(%d,%d): %d '%c'", x, y, ch, ch);
-           exit(1);
-         }
-       }
-      }
-    }
-    
-    
-    /* get lower 4 bits of updated flags */
-    for(y=0; y<map.ysize; y++) {
-      char *terline=secfile_lookup_str(file, "player%d.map_ua%03d",plrno, y);
-      
-      for(x=0; x<map.xsize; x++) {
-       char ch=terline[x];
-       map_get_player_tile(x, y, plr)->last_updated = ch-(isdigit(ch) ? '0' : 
('a'-10));
-      }
-    }
-    
-    /* get upper 4 bits of updated flags */
-    for(y=0; y<map.ysize; y++) {
-      char *terline=secfile_lookup_str(file, "player%d.map_ub%03d", plrno, y);
-      
-      for(x=0; x<map.xsize; x++) {
-       char ch=terline[x];
-       map_get_player_tile(x, y, plr)->last_updated |= (ch-(isdigit(ch) ? '0' 
: 'a'-10))<<4;
-      }
-    }
-    
-    /* get "next" 4 bits of updated flags */
-    for(y=0; y<map.ysize; y++) {
-      char *terline=secfile_lookup_str(file, "player%d.map_uc%03d", plrno, y);
-      
-      if (terline) {
-       for(x=0; x<map.xsize; x++) {
-         char ch=terline[x];
-         map_get_player_tile(x, y, plr)->last_updated |= (ch-(isdigit(ch) ? 
'0' : 'a'-10))<<8;
-       }
-      }
-    }
-    
-    /* get "last" 4 bits of updated flags */
-    for(y=0; y<map.ysize; y++) {
-      char *terline=secfile_lookup_str(file, "player%d.map_ud%03d", plrno, y);
-      
-      if (terline) {
-       for(x=0; x<map.xsize; x++) {
-         char ch=terline[x];
-         map_get_player_tile(x, y, plr)->last_updated |= (ch-(isdigit(ch) ? 
'0' : 'a'-10))<<12;
-       }
-      }
-    }
-    
+    LOAD_MAP_DATA(secfile_lookup_str(file, "player%d.map_t%03d", plrno, y),
+                 {
+                   char *pch = strchr(terrain_chars, ch);
+                   if(!pch) {
+                     freelog(LOG_FATAL, "unknown terrain type (map.t) in map "
+                       "at position (%d,%d): %d '%c'", x, y, ch, ch);
+                     exit(1);
+                   }
+                   map_get_player_tile(x, y, plr)->terrain=pch-terrain_chars;
+                 }
+    );
+    
+    /* get 4-bit segments of 12-bit "special" field. */
+    /* FIXME: the code used to skip over any lines that weren't present, but
+       the LOAD_MAP_DATA macro does not currently do this.  Is this a problem?
+       At least we assert() to make sure the line is present. */
+    LOAD_MAP_DATA(secfile_lookup_str(file, "player%d.map_l%03d",plrno, y),
+                 map_get_player_tile(x, y, plr)->special = HEX2DEC(ch, 0));
+    LOAD_MAP_DATA(secfile_lookup_str(file, "player%d.map_u%03d", plrno, y),
+                 map_get_player_tile(x, y, plr)->special |= HEX2DEC(ch, 1));
+    LOAD_MAP_DATA(secfile_lookup_str_default(file, NULL, "player%d.map_n%03d", 
plrno, y),
+                 map_get_player_tile(x, y, plr)->special |= HEX2DEC(ch, 2));
+
+    /* get 4-bit segments of 16-bit "updated" field */
+    LOAD_MAP_DATA(secfile_lookup_str(file, "player%d.map_ua%03d",plrno, y),
+                 map_get_player_tile(x, y, plr)->last_updated = HEX2DEC(ch, 
0));
+    LOAD_MAP_DATA(secfile_lookup_str(file, "player%d.map_ub%03d", plrno, y),
+                 map_get_player_tile(x, y, plr)->last_updated |= HEX2DEC(ch, 
1));
+    LOAD_MAP_DATA(secfile_lookup_str(file, "player%d.map_uc%03d", plrno, y),
+                 map_get_player_tile(x, y, plr)->last_updated |= HEX2DEC(ch, 
2));
+    LOAD_MAP_DATA(secfile_lookup_str(file, "player%d.map_ud%03d", plrno, y),
+                 map_get_player_tile(x, y, plr)->last_updated |= HEX2DEC(ch, 
3));
+
     {
       int j;
       struct dumb_city *pdcity;

[Prev in Thread] Current Thread [Next in Thread]