Complete.Org: Mailing Lists: Archives: freeciv-dev: October 2001:
[Freeciv-Dev] PATCH: load_map_data macro (PR#1012)
Home

[Freeciv-Dev] PATCH: load_map_data macro (PR#1012)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Cc: bugs@xxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] PATCH: load_map_data macro (PR#1012)
From: jdorje@xxxxxxxxxxxxxxxxxxxxx
Date: Sat, 13 Oct 2001 16:36:08 -0700 (PDT)

The attached patch implements a LOAD_MAP_POS macro.  It then makes code
replacement like replacing

  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;
    }
  }

with

  LOAD_MAP_DATA(secfile_lookup_str(file, "map.t%03d", y),
                map_get_tile(x, y)->terrain = char2terrain(ch));

There are three advantages to this new code: it leads to less
duplication, it "fixes" code so that it is topology-independent
(LOAD_MAP_POS skips over non-normal positions), and it introduces extra
error-checking that was previously done in only a few of the loops.

The disadvantage of the code is that it might introduce a bug.  See the
following comment about the macro itself:

/* Note: some of the code this is replacing used to skip over lines that
   did not exist.  I don't know whether this was for backwards-
   compatibility or just because the loops were written differently.
   This macro will fail if any line does not exist.  Hopefully this will
   never happen, but if so we at least show an informative message. */

After some thought, I don't think we'll easily be able to find out if
the line-skipping is needed for backwards-compatibility.  If so, then
that backwards-compitibility will no longer be present; but since this
code is at least a year old I think the damage should be small.  If not,
then we've saved some extra ugliness in the code.  This change should
have no effect on current savegames (unless there's another bug in the
code that causes data to not be saved correctly).

It is difficult to verify the correctness of the patch.  Unlike that
SAVE_MAP_DATA patch, we can't just save a game and make sure it's
identical.  This code looks correct to me (I'll double-check it again
soon) and has given correct results in all my tests.  Having more eyes
on it would definitely be good.

This patch leaves the map_rivers_overlay_load function intact.  The
original SAVE_MAP_DATA removed (IIRC) map_rivers_overlay_save.  Although
the load function could easily be removed in the same way, a comment in
the code indicates that the function may need to be called more than
once (although it is not currently).  So, I could go either way on this.

The patch also introduces hex2dec() and char2terrain() functions to
convert from the character value in the savefile to the decimal or
terrain integer value.  I have made these functions, since they do a
fair amount of error-checking and the branching would have been quite
ugly as a macro.  I've also put them up alongside DEC2HEX, dec2hex[],
and terrain_chars[]; this means they are above the [LOAD|SAVE]_MAP_POS
macros.  They can easily be moved elsewhere (further down with the other
functions) if desired.

jason short
? rc
? check_coords
? old
? topology
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.35
diff -u -r1.35 savegame.c
--- server/savegame.c   2001/10/12 19:48:30     1.35
+++ server/savegame.c   2001/10/13 23:35:32
@@ -50,12 +50,48 @@
 
 #include "savegame.h"
 
+static const char dec2hex[] = "0123456789abcdef";
+static const char terrain_chars[] = "adfghjm prstu";
 
+/* This returns a hex value of the given half-byte of the
+   decimal value.  See hex2dec().
+     example: DEC2HEX(0xa00, 2) == 'a' */
 #define DEC2HEX(int_value, halfbyte_wanted) \
   dec2hex[((int_value) >> ((halfbyte_wanted) * 4)) & 0xf]
-static const char dec2hex[] = "0123456789abcdef";
-static const char terrain_chars[] = "adfghjm prstu";
 
+/***************************************************************
+This returns a decimal value of the hex char, offset by the
+given number of half-bytes.  See DEC2HEX().
+  example: hex2dec('a', 2) == 0xa00
+***************************************************************/
+static int hex2dec(char ch, int offset)
+{
+  if (!isxdigit(ch)) {
+    if (ch == ' ') {
+      return 0; /* sane value */
+    } else {
+      freelog(LOG_FATAL, "unknown hex value ('%c')", ch);
+      exit(1);
+    }
+  }
+  return (ch-(isdigit(ch) ? '0' : 'a'-10)) << (offset * 4);
+}
+
+
+/***************************************************************
+Dereferences the terrain character.  See terrain_chars[].
+  example: char2terrain('a') == 0
+***************************************************************/
+static int char2terrain(char ch)
+{
+  char *pch = strchr(terrain_chars, ch);
+  if(!pch) {
+    freelog(LOG_FATAL, "unknown terrain type: '%c'", ch);
+    exit(1);
+  }
+  return pch - terrain_chars;
+}
+
 /* 
  * This loops over the entire map to save data. It collects all the
  * data of a line using get_xy_char and then executes the
@@ -96,6 +132,44 @@
                      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 a char* for the line
+ */
+/* Note: some of the code this is replacing used to skip over lines that
+   did not exist.  I don't know whether this was for backwards-
+   compatibility or just because the loops were written differently.
+   This macro will fail if any line does not exist.  Hopefully this will
+   never happen, but if so we at least show an informative message. */
+#define LOAD_MAP_DATA(secfile_lookup_line, set_xy_char)       \
+{                                                             \
+  int y;                                                      \
+  for (y = 0; y < map.ysize; y++) {                           \
+    char *line = secfile_lookup_line;                         \
+    int x;                                                    \
+    if (!line) {                                              \
+      freelog(LOG_FATAL, "Invalid map line for y=%d.  "       \
+             "This may be a bug in FreeCiv; see "            \
+             "http://www.freeciv.org/ if you think so.", y); \
+      exit(1);                                                \
+    }                                                         \
+    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 +280,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 +291,8 @@
   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),
+               map_get_tile(x, y)->terrain = char2terrain(ch));
 
   assign_continent_numbers();
 }
@@ -246,28 +308,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 +320,6 @@
 ***************************************************************/
 static void map_load(struct section_file *file)
 {
-  int x ,y;
   char *savefile_options = get_savefile_options(file);
 
   /* map_init();
@@ -292,211 +335,40 @@
     map.num_start_positions = 0;
     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 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);
-       }
-      }
-    }
-  }
+  /* get 4-bit segments of 16-bit "special" field. */
+  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));
 
   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 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));
 
-    /* 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);
-       }
-      }
-    }
-
     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 +1091,27 @@
       && 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),
+                 map_get_player_tile(x, y, plr)->terrain = char2terrain(ch));
+
+    /* get 4-bit segments of 12-bit "special" field. */
+    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]