Difference for x11/xutil.c from version 1.16.2.1 to 1.1


version 1.16.2.1 version 1.1
Line 1
 
Line 1
 char *rcsid_x11_xutil_c =  
     "$Id: xutil.c,v 1.16.2.1 2005/02/23 04:09:28 tanner Exp $";  
 /*  /*
     Crossfire client, a client program for the crossfire program.   * static char *rcsid_xio_c =
    *   "$Id: xutil.c,v 1.1 2001/11/02 08:22:03 mwedel Exp $";
     Copyright (C) 2001-2003 Mark Wedel & Crossfire Development Team   *
    * This contains varous 'support' functions.  These functions will probably
     This program is free software; you can redistribute it and/or modify  
     it under the terms of the GNU General Public License as published by  
     the Free Software Foundation; either version 2 of the License, or  
     (at your option) any later version.  
   
     This program is distributed in the hope that it will be useful,  
     but WITHOUT ANY WARRANTY; without even the implied warranty of  
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
     GNU General Public License for more details.  
   
     You should have received a copy of the GNU General Public License  
     along with this program; if not, write to the Free Software  
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
   
     The author can be reached via e-mail to crossfire-devel@real-time.com  
 */  
   
 /* This contains various 'support' functions.  These functions will probably  
  * go mostly unaltered between different toolkits, as long as X11 is still   * go mostly unaltered between different toolkits, as long as X11 is still
  * used.    * used.  This file is not compiled seperately, rather it is included by
    * x11.c, so all statics will still work fine.
  */   */
   
 #include <client.h>  #include <client.h>
 #include <item.h>  #include <item.h>
 #include <config.h>  #include <config.h>
 #include <p_cmd.h>  
   
 #ifdef HAVE_LIBXPM  #ifdef HAVE_LIBXPM
 #include <X11/xpm.h>  #include <X11/xpm.h>
Line 50
 
Line 30
 "White",                /* 1  */  "White",                /* 1  */
 "Navy",                 /* 2  */  "Navy",                 /* 2  */
 "Red",                  /* 3  */  "Red",                  /* 3  */
 "Chocolate",            /* 4  was Orange, but impossible to read on DarkSeaGreen */  "Orange",               /* 4  */
 "DodgerBlue",           /* 5  */  "DodgerBlue",           /* 5  */
 "DarkOrange2",          /* 6  */  "DarkOrange2",          /* 6  */
 "SeaGreen",             /* 7  */  "SeaGreen",             /* 7  */
Line 129
 
Line 109
 char *facetoname[MAXPIXMAPNUM];  char *facetoname[MAXPIXMAPNUM];
   
 /* Can be set when user is moving to new machine type */  /* Can be set when user is moving to new machine type */
 uint8 updatekeycodes=FALSE;  uint8 updatekeycodes=FALSE, keepcache=FALSE;
   
 #ifndef GDK_XUTIL  #ifndef GDK_XUTIL
 /* Initializes the data for image caching */  /* Initializes the data for image caching */
 void init_cache_data()  void init_cache_data()
 {  {
     int i;      int i;
     Pixmap  ptmp;  
 #include "pixmaps/question.111"  
          
   #include "pixmaps/question.111"
   
     /* Currently, we can cache in all face modes currently supported,      /* Currently, we can cache in all face modes currently supported,
      * so I removed the code that did checks on that.       * so I removed the code that did checks on that.
      */       */
   
     pixmaps[0] = malloc(sizeof(struct PixmapInfo));      pixmaps[0].mask=None;
     pixmaps[0]->mask=None;      pixmaps[0].bitmap=XCreateBitmapFromData(display,
     ptmp=XCreateBitmapFromData(display,DefaultRootWindow(display),   RootWindow(display, screen_num), (const char*)question_bits, image_size,image_size);
  question_bits,question_width,question_height);  
   
     /* In xpm mode, XCopyArea is used from this data, so we need to copy      /* In xpm mode, XCopyArea is used from this data, so we need to copy
      * the image into an pixmap of appropriate depth.       * the image into an pixmap of appropriate depth.
        * Note that while are image created is the image size, since we know
        * that are filler image is currently only 24x24, we only copy that much
        * data.
      */       */
     pixmaps[0]->pixmap=XCreatePixmap(display, win_root, image_size, image_size,       pixmaps[0].pixmap=XCreatePixmap(display, win_root, image_size, image_size,
  DefaultDepth(display,DefaultScreen(display)));   DefaultDepth(display,DefaultScreen(display)));
     XCopyPlane(display, ptmp, pixmaps[0]->pixmap, gc_game,      XCopyPlane(display, pixmaps[0].bitmap, pixmaps[0].pixmap, gc_game,
         0,0,image_size,image_size,0,0,1);          0,0,24,24,0,0,1);
     XFreePixmap(display, ptmp);  
    
       pixmaps[0].bg = 0;
       pixmaps[0].fg = 1;
     facetoname[0]=NULL;      facetoname[0]=NULL;
   
     /* Initialize all the images to be of the same value. */      /* Initialize all the images to be of the same value. */
Line 166
 
Line 148
  facetoname[i]=NULL;   facetoname[i]=NULL;
     }      }
   
     init_common_cache_data();  #ifdef IMAGECACHEDIR
       strcpy(facecachedir, IMAGECACHEDIR);
   #else
       sprintf(facecachedir,"%s/.crossfire/images", getenv("HOME"));
   #endif
   
       if (make_path_to_dir(facecachedir)==-1) {
        fprintf(stderr,"Could not create directory %s, exiting\n", facecachedir);
        exit(1);
       }
   
 }  }
 #endif  #endif
   
   static void requestface(int pnum, char *facename, char *facepath)
   {
       char buf[MAX_BUF];
   
       facetoname[pnum] = strdup_local(facepath);
       sprintf(buf,"askface %d", pnum);
       cs_write_string(csocket.fd, buf, strlen(buf));
       /* Need to make sure we have the directory */
       sprintf(buf,"%s/%c%c", facecachedir, facename[0], facename[1]);
       if (access(buf,R_OK)) make_path_to_dir(buf);
   }
 /* Rotate right from bsd sum. */  /* Rotate right from bsd sum. */
 #define ROTATE_RIGHT(c) if ((c) & 01) (c) = ((c) >>1) + 0x80000000; else (c) >>= 1;  #define ROTATE_RIGHT(c) if ((c) & 01) (c) = ((c) >>1) + 0x80000000; else (c) >>= 1;
   
 /*#define CHECKSUM_DEBUG*/  /*#define CHECKSUM_DEBUG*/
   
   /* This is common for both face1 and face commands. */
   void finish_face_cmd(int pnum, uint32 checksum, int has_sum, char *face)
   {
       char buf[MAX_BUF];
       int fd,len;
       char data[65536];
       uint32 newsum=0;
   #ifndef GDK_XUTIL
       Pixmap pixmap, mask;
   #endif
   
       /* Check private cache first */
       sprintf(buf,"%s/.crossfire/gfx/%s", getenv("HOME"), face);
       if (display_mode == Png_Display)
    strcat(buf,".png");
   
       if ((fd=open(buf, O_RDONLY))!=-1) {
    len=read(fd, data, 65535);
    close(fd);
    has_sum=0;  /* Maybe not really true, but we want to use this image
         * and not request a replacement.
         */
       } else {
   
    /* Hmm.  Should we use this file first, or look in our home
    * dir cache first?
    */
    if (use_private_cache) {
        len = find_face_in_private_cache(face, checksum);
        if ( len > 0 ) {
   #ifdef GDK_XUTIL
    pixmaps[pnum].gdkpixmap = private_cache[len].pixmap;
    pixmaps[pnum].gdkmask = private_cache[len].mask;
    pixmaps[pnum].png_data = private_cache[len].png_data;
   
   #else
    pixmaps[pnum].pixmap = private_cache[len].pixmap;
    pixmaps[pnum].mask = private_cache[len].mask;
   #endif
    /* we may want to find a better match */
    if (private_cache[len].checksum == checksum ||
        !has_sum || keepcache) return;
        }
    }
   
   
    /* To prevent having a directory with 2000 images, we do a simple
    * split on the first 2 characters.
    */
    sprintf(buf,"%s/%c%c/%s", facecachedir, face[0], face[1],face);
    if (display_mode == Png_Display)
        strcat(buf,".png");
   
    if ((fd=open(buf, O_RDONLY))==-1) {
        requestface(pnum, face, buf);
        return;
    }
    len=read(fd, data, 65535);
    close(fd);
       }
   
       if (has_sum && !keepcache) {
    for (fd=0; fd<len; fd++) {
        ROTATE_RIGHT(newsum);
        newsum += data[fd];
        newsum &= 0xffffffff;
    }
   
    if (newsum != checksum) {
   #ifdef CHECKSUM_DEBUG
        fprintf(stderr,"finish_face_command: checksums differ: %s, %x != %x\n",
        face, newsum, checksum);
   #endif
        requestface(pnum, face, buf);
   #ifdef CHECKSUM_DEBUG
    } else {
        fprintf(stderr,"finish_face_command: checksums match: %s, %x == %x\n",
        face, newsum, checksum);
   #endif
    }
       }
       if (display_mode==Png_Display) {
    unsigned long w,h;
   
    /* Fail on this read, we will request a new copy */
    if (png_to_xpixmap(display, win_game, data, len,
       &pixmap, &mask, &colormap, &w, &h)) {
        requestface(pnum, face, buf);
    } else {
        pixmaps[pnum].pixmap = pixmap;
        pixmaps[pnum].mask = mask;
    }
   
       } else if (display_mode==Pix_Display) {
    pixmaps[pnum].bitmap = XCreateBitmapFromData(display,
    RootWindow(display,DefaultScreen(display)),
    (char*)data,24,24);
    pixmaps[pnum].fg = (data[24] << 24) + (data[25] << 16) + (data[26] << 8) +
        data[27];
    pixmaps[pnum].bg = (data[28] << 24) + (data[29] << 16 )+ (data[30] << 8 )+
        data[31];
       }
   }
   
   
   #ifndef GDK_XUTIL
   
 int allocate_colors(Display *disp, Window w, long screen_num,  int allocate_colors(Display *disp, Window w, long screen_num,
         Colormap *colormap, XColor discolor[16])          Colormap *colormap, XColor discolor[16])
Line 230
 
Line 338
   return iscolor;    return iscolor;
 }  }
   
   #endif /* GDK_XUTIL */
   
   
   
Line 245
 
Line 354
     Key_Entry *newkey;      Key_Entry *newkey;
     int i, direction=-1;      int i, direction=-1;
   
 #if 0  
     /* This is at least a meaningless check on my system that results in  
      * a compile warning (always false result), so may was well comment it  
      * out - MSW 2005-02-09  
      */  
     if (keycode>MAX_KEYCODE) {      if (keycode>MAX_KEYCODE) {
  LOG(LOG_WARNING,"x11::insert_key", "keycode that is passed is greater than 255.");   fprintf(stderr,"Warning insert_key:keycode that is passed is greater than 255.\n");
  keycode=0; /* hopefully the rest of the data is OK */   keycode=0; /* hopefully the rest of the data is OK */
     }      }
 #endif  
     if (keys[keycode]==NULL) {      if (keys[keycode]==NULL) {
  keys[keycode]=malloc(sizeof(Key_Entry));   keys[keycode]=malloc(sizeof(Key_Entry));
  keys[keycode]->command=NULL;   keys[keycode]->command=NULL;
Line 307
 
Line 410
   
     if (buf[0]=='#' || buf[0]=='\n') return;      if (buf[0]=='#' || buf[0]=='\n') return;
     if ((cpnext = strchr(buf,' '))==NULL) {      if ((cpnext = strchr(buf,' '))==NULL) {
  LOG(LOG_WARNING,"x11::parse_keybind_line","Line %d (%s) corrupted.", line,buf);   fprintf(stderr,"Line %d (%s) corrupted in keybinding file.\n", line,buf);
  return;   return;
     }      }
     /* Special keybinding line */      /* Special keybinding line */
Line 316
 
Line 419
  while (*cpnext == ' ') ++cpnext;   while (*cpnext == ' ') ++cpnext;
  cp = strchr(cpnext, ' ');   cp = strchr(cpnext, ' ');
  if (!cp) {   if (!cp) {
      LOG(LOG_WARNING,"x11::parse_keybind_line","Line %d (%s) corrupted in keybinding file.", line,buf);       fprintf(stderr,"Line %d (%s) corrupted in keybinding file.\n", line,buf);
      return;       return;
  }   }
  *cp++ = 0;  /* Null terminate it */   *cp++ = 0;  /* Null terminate it */
  cp1 = strchr(cp, ' ');   cp1 = strchr(cp, ' ');
  if (!cp1) {   if (!cp1) {
      LOG(LOG_WARNING,"x11::parse_keybind_line","Line %d (%s) corrupted in keybinding file.", line,buf);       fprintf(stderr,"Line %d (%s) corrupted in keybinding file.\n", line,buf);
      return;       return;
  }   }
  *cp1 ++ = 0;/* Null terminate it */   *cp1 ++ = 0;/* Null terminate it */
Line 330
 
Line 433
  keysym = XStringToKeysym(cp);   keysym = XStringToKeysym(cp);
  /* As of now, all these keys must have keysyms */   /* As of now, all these keys must have keysyms */
  if (keysym == NoSymbol) {   if (keysym == NoSymbol) {
      LOG(LOG_WARNING,"x11::parse_keybind_line","Could not convert %s into keysym", cp);       fprintf(stderr,"Could not convert %s into keysym\n", cp);
      return;       return;
  }   }
  if (!strcmp(cpnext,"commandkey")) {   if (!strcmp(cpnext,"commandkey")) {
Line 381
 
Line 484
     keysym = XStringToKeysym(buf);      keysym = XStringToKeysym(buf);
     cp = cpnext;      cp = cpnext;
     if ((cpnext = strchr(cp,' '))==NULL) {      if ((cpnext = strchr(cp,' '))==NULL) {
  LOG(LOG_WARNING,"x11::parse_keybind_line","Line %d (%s) corrupted in keybinding file.", line, cp);   fprintf(stderr,"Line %d (%s) corrupted in keybinding file.\n", line, cp);
  return;   return;
     }      }
     *cpnext++ = '\0';      *cpnext++ = '\0';
Line 390
 
Line 493
     keycode = atoi(cp);      keycode = atoi(cp);
     cp = cpnext;      cp = cpnext;
     if ((cpnext = strchr(cp,' '))==NULL) {      if ((cpnext = strchr(cp,' '))==NULL) {
  LOG(LOG_WARNING,"x11::parse_keybind_line","Line %d (%s) corrupted in keybinding file.", line, cp);   fprintf(stderr,"Line %d (%s) corrupted in keybinding file.\n", line, cp);
  return;   return;
     }      }
     *cpnext++ = '\0';      *cpnext++ = '\0';
Line 416
 
Line 519
  flags |= KEYF_STANDARD;   flags |= KEYF_STANDARD;
  break;   break;
  default:   default:
      LOG(LOG_WARNING,"x11::parse_keybind_line","Unknown flag (%c) line %d in key binding file",       fprintf(stderr,"Warning:  Unknown flag (%c) line %d in key binding file\n",
  *cp, line);   *cp, line);
         }          }
         cp++;          cp++;
Line 439
 
Line 542
          * it away, but at least print a warning message.           * it away, but at least print a warning message.
          */           */
         if (keycode==0) {          if (keycode==0) {
      LOG(LOG_WARNING,"x11::parse_keybind_line","could not convert keysym %s into keycode, ignoring",       fprintf(stderr,"Warning: could not convert keysym %s into keycode, ignoring\n",
  buf);   buf);
  }   }
     }      }
     /* Rest of the line is the actual command.  Lets kill the newline */      /* Rest of the line is the actual command.  Lets kill the newline */
     cpnext[strlen(cpnext)-1]='\0';      cpnext[strlen(cpnext)-1]='\0';
     if (strlen(cpnext)>(sizeof(bind_buf)-1)){  
         cpnext[sizeof(bind_buf)-1]='\0';  
         LOG(LOG_WARNING,"gtk::parse_keybind_line","Had to truncate a too long command");  
     }  
     insert_key(keysym, keycode, flags | standard, cpnext);      insert_key(keysym, keycode, flags | standard, cpnext);
 }  }
   
Line 525
 
Line 624
   
     sprintf(buf,"%s/.crossfire/keys", getenv("HOME"));      sprintf(buf,"%s/.crossfire/keys", getenv("HOME"));
     if ((fp=fopen(buf,"r"))==NULL) {      if ((fp=fopen(buf,"r"))==NULL) {
  LOG(LOG_INFO,"x11::init_keys","Could not open ~/.crossfire/keys, trying to load global bindings");   fprintf(stderr,"Could not open ~/.crossfire/keys, trying to load global bindings\n");
  if (client_libdir==NULL) {   if (client_libdir==NULL) {
      init_default_keybindings();       init_default_keybindings();
      return;       return;
Line 576
 
Line 675
     else if (kc==runkey[0] || ks==runkeysym[0] ||      else if (kc==runkey[0] || ks==runkeysym[0] ||
  kc==runkey[1] || ks==runkeysym[1]) {   kc==runkey[1] || ks==runkeysym[1]) {
  cpl.run_on=0;   cpl.run_on=0;
  if (use_config[CONFIG_ECHO]) draw_info("stop run",NDI_BLACK);   if (cpl.echo_bindings) draw_info("stop run",NDI_BLACK);
 #ifdef GDK_XUTIL  #ifdef GDK_XUTIL
  clear_run();   clear_run();
  gtk_label_set (GTK_LABEL(run_label),"   ");   gtk_label_set (GTK_LABEL(run_label),"   ");
Line 590
 
Line 689
      * to stop.  This should do that.       * to stop.  This should do that.
      */       */
     else if (cpl.fire_on)       else if (cpl.fire_on)
   #ifdef GDK_XUTIL
    clear_fire();
   #else
  stop_fire();   stop_fire();
   #endif
 }  }
   
 /* This parses a keypress.  It should only be called when in Playing  /* This parses a keypress.  It should only be called when in Playing
  * mode.   * mode.
  */   */
 void parse_key(char key, KeyCode keycode, KeySym keysym, int repeated)  void parse_key(char key, KeyCode keycode, KeySym keysym)
 {  {
     Key_Entry *keyentry, *first_match=NULL;      Key_Entry *keyentry, *first_match=NULL;
     int present_flags=0;      int present_flags=0;
     char buf[MAX_BUF];      char buf[MAX_BUF];
   
     if (keycode == commandkey && keysym==commandkeysym) {      if (keycode == commandkey && keysym==commandkeysym) {
   #ifdef GDK_XUTIL
         if (split_windows) {
    gtk_widget_grab_focus (GTK_WIDGET(gtkwin_info));
    gtk_widget_grab_focus (GTK_WIDGET(entrytext));
         } else {
    gtk_widget_grab_focus (GTK_WIDGET(entrytext));
         }
         gtk_entry_set_visibility(GTK_ENTRY(entrytext), 1);
   
   #else
  draw_prompt(">");   draw_prompt(">");
   #endif
  cpl.input_state = Command_Mode;   cpl.input_state = Command_Mode;
  cpl.no_echo=FALSE;   cpl.no_echo=FALSE;
  return;   return;
Line 674
 
Line 788
  run_dir(first_match->direction);   run_dir(first_match->direction);
  sprintf(buf,"run %s", first_match->command);   sprintf(buf,"run %s", first_match->command);
      }       }
      else if (!repeated) {       else {
  strcpy(buf,first_match->command);   strcpy(buf,first_match->command);
  extended_command(first_match->command);   extended_command(first_match->command);
      }       }
      else       if (cpl.echo_bindings) draw_info(buf,NDI_BLACK);
  sprintf(buf,"move %s (ignored)", first_match->command);  
      if (use_config[CONFIG_ECHO]) draw_info(buf,NDI_BLACK);  
  }   }
         else {          else {
      if (use_config[CONFIG_ECHO]) draw_info(first_match->command,NDI_BLACK);       if (cpl.echo_bindings) draw_info(first_match->command,NDI_BLACK);
      extended_command(first_match->command);       extended_command(first_match->command);
  }   }
  return;   return;
Line 712
 
Line 824
  */   */
 static char * get_key_info(Key_Entry *key, KeyCode kc, int save_mode)  static char * get_key_info(Key_Entry *key, KeyCode kc, int save_mode)
 {  {
     /* bind buf is the maximum space allowed for a      static char buf[MAX_BUF];
      * binded command. We will add additional datas to  
      * it so we increase by MAX_BUF*/  
     static char buf[MAX_BUF+sizeof(bind_buf)];  
     char buff[MAX_BUF];      char buff[MAX_BUF];
     int bi=0;      int bi=0;
   
Line 816
 
Line 925
   
   
   
 void bind_key(const char *params)  void bind_key(char *params)
 {  {
   char buf[MAX_BUF];    char buf[MAX_BUF];
   
Line 929
 
Line 1038
     return;      return;
   }    }
   
   strncpy(bind_buf, params, sizeof(bind_buf)-1);    sprintf(buf, "Push key to bind '%s'.", params);
   bind_buf[sizeof(bind_buf)-1]=0;  
   if (strlen(params) >= sizeof(bind_buf)) {  
     draw_info("Keybinding too long! Truncated:",NDI_RED);  
     draw_info(bind_buf,NDI_RED);  
   }  
   
   sprintf(buf, "Push key to bind '%s'.", bind_buf);  
   draw_info(buf,NDI_BLACK);    draw_info(buf,NDI_BLACK);
     strcpy(bind_buf, params);
   bind_keycode=NULL;    bind_keycode=NULL;
   cpl.input_state = Configure_Keys;    cpl.input_state = Configure_Keys;
   return;    return;
Line 966
 
Line 1069
   
     sprintf(buf,"%s/.crossfire/keys", getenv("HOME"));      sprintf(buf,"%s/.crossfire/keys", getenv("HOME"));
     if (make_path_to_file(buf)==-1) {      if (make_path_to_file(buf)==-1) {
  LOG(LOG_WARNING,"x11::save_keys","Could not create %s", buf);   fprintf(stderr,"Could not create %s\n", buf);
  return;   return;
     }      }
     if ((fp=fopen(buf,"w"))==NULL) {      if ((fp=fopen(buf,"w"))==NULL) {
Line 1075
 
Line 1178
     draw_info("    -g unbinds a global binding", NDI_BLACK);      draw_info("    -g unbinds a global binding", NDI_BLACK);
 }  }
   
 void unbind_key(const char *params)  void unbind_key(char *params)
 {  {
     int count=0, keyentry, onkey,global=0;      int count=0, keyentry, onkey,global=0;
     Key_Entry *key, *tmp;      Key_Entry *key, *tmp;
Line 1125
 
Line 1228
  goto unbinded;   goto unbinded;
      }       }
  }   }
  LOG(LOG_ERROR,"x11::unbind_key","found number entry, but could not find actual key");   fprintf(stderr,"unbind_key - found number entry, but could not find actual key\n");
      }       }
  }   }
     }      }
Line 1150
 
Line 1253
 }  }
   
   
   /* This code is somewhat from the crossedit/xutil.c.
    * What we do is create a private copy of all the images
    * for ourselves.  Then, if we get a request to display
    * a new image, we see if we have it in this cache.
    *
    * This is only supported for PNG images.  I see now reason
    * to support the older image formats since they will be
    * going away.
    */
   
   int ReadImages() {
   
       int len,i,num ;
       FILE *infile;
       char *cp, databuf[10000], *last_cp=NULL;
       unsigned long  x;
   #ifndef GDK_XUTIL
       unsigned long y;
   #endif
   
       if ((display_mode != Png_Display) || (image_file[0] == 0)) return 0;
   
       if (!cache_images) {
    cache_images=1;     /* we want face commands from server */
    keepcache=TRUE;     /* Reduce requests for new image */
       }
   
       if ((infile = fopen(image_file,"r"))==NULL) {
           fprintf(stderr,"Unable to open %s\n", image_file);
    return 0;
       }
       for (i=0; i<MAXPIXMAPNUM; i++)
    private_cache[0].name = NULL;
   
       i=0;
       while (fgets(databuf,MAX_BUF,infile)) {
   
    /* First, verify that that image header line is OK */
           if(strncmp(databuf,"IMAGE ",6)!=0) {
        fprintf(stderr,"ReadImages:Bad image line - not IMAGE, instead\n%s",databuf);
        return 0;
    }
           num = atoi(databuf+6);
           if (num<0 || num > MAXPIXMAPNUM) {
               fprintf(stderr,"Pixmap number less than zero: %d, %s\n",num, databuf);
               return 0;
    }
    /* Skip accross the number data */
    for (cp=databuf+6; *cp!=' '; cp++) ;
    len = atoi(cp);
    if (len==0 || len>10000) {
        fprintf(stderr,"ReadImages: length not valid: %d\n%s",
                       len,databuf);
                   return 0;
    }
    /* We need the name so that when an FaceCmd comes in, we can look for
    the matching name.
    */
    while (*cp!=' ' && *cp!='\n') cp++; /* skip over len */
   
    /* We only want the last component of the name - not the full path */
    while (*cp != '\n') {
        if (*cp == '/') last_cp = cp+1; /* don't want the slah either */
        cp++;
    }
    *cp = '\0'; /* Clear newline */
   
    private_cache[num].name = strdup_local(last_cp);
   
    if (fread(databuf, 1, len, infile)!=len) {
              fprintf(stderr,"read_client_images: Did not read desired amount of data, wanted %d\n%s",
                       len, databuf);
                       return 0;
    }
    private_cache[num].checksum=0;
    for (x=0; x<len; x++) {
        ROTATE_RIGHT(private_cache[num].checksum);
        private_cache[num].checksum += databuf[x];
        private_cache[num].checksum &= 0xffffffff;
    }
    if (num > last_face_num) last_face_num = num;
   #ifdef HAVE_LIBPNG
   #ifdef GDK_XUTIL
    if (pngximage && !(private_cache[num].png_data = png_to_data(databuf, (int)len))) {
        fprintf(stderr,"Got error on png_to_data\n");
    }
    /* even if using pngximage, we standard image for the inventory list */
    if (png_to_gdkpixmap(gtkwin_root->window, databuf, len,
       &private_cache[num].pixmap, &private_cache[num].mask,
    gtk_widget_get_colormap(gtkwin_root))) {
   
    fprintf(stderr,"Error loading png file.\n");
    }
   #else
    if (png_to_xpixmap(display, win_game, databuf, len,
       &private_cache[num].pixmap, &private_cache[num].mask,
           &colormap, &x, &y)) {
   
    fprintf(stderr,"Error loading png file.\n");
    }
   #endif
   #endif
       }
       fclose(infile);
       use_private_cache=1;
       return 0;
   }
   
 /* try to find a face in our private cache.  We return the face  /* try to find a face in our private cache.  We return the face
  * number if we find one, -1 for no face match   * number if we find one, -1 for no face match
  */   */
Line 1164
 
Line 1375
     return -1;      return -1;
 }  }
   
   
 void image_update_download_status(int start, int end, int total)  
 {  
     char buf[MAX_BUF];  
   
     sprintf(buf,"Downloaded %d of %d images", start, total);  
   
     draw_info(buf,NDI_BLUE);  
 }  
   
 /* Start of map handling code.  /* Start of map handling code.
  * For the most part, this actually is not window system specific,   * For the most part, this actually is not window system specific,
  * but certainly how the client wants to store this may vary.   * but certainly how the client wants to store this may vary.
  *   
  * At least in the gtk and x11 clients, 95+% of this code  
  * is the same - the only think I think is different is  
  * that the gtk will call sdl_scroll.  This should  
  * probably be moved into the common area.  
  */   */
   
 #define MAXFACES 5  #define MAXFACES 5
Line 1195
 
Line 1391
  * FIX ME: Don't assume rectangle   * FIX ME: Don't assume rectangle
  */   */
   
   int map_size= 0;
 PlayerPosition pl_pos;  PlayerPosition pl_pos;
   
   
Line 1210
 
Line 1407
  */   */
 void allocate_map( struct Map* new_map, int ax, int ay)  void allocate_map( struct Map* new_map, int ax, int ay)
 {  {
   
     int i= 0;      int i= 0;
   
     if( new_map == NULL)      if( new_map == NULL)
Line 1221
 
Line 1419
     }      }
   
     new_map->cells= (struct MapCell**)calloc( sizeof( struct MapCell*) * ay      new_map->cells= (struct MapCell**)calloc( sizeof( struct MapCell*) * ay
      + sizeof( struct MapCell) * ax * ay, 1);       + sizeof( struct MapCell) *
        map_size * map_size, 1);
     if( new_map->cells == NULL)      if( new_map->cells == NULL)
  return;   return;
   
Line 1235
 
Line 1433
     /* Finish assigning the beginning of each row relative to the first row      /* Finish assigning the beginning of each row relative to the first row
      * assigned above       * assigned above
      */       */
     for( i= 0; i < ay; i++)  {    for( i= 0; i < ay; i++)
       {
  new_map->cells[i]= new_map->cells[0] + ( i * ax);   new_map->cells[i]= new_map->cells[0] + ( i * ax);
     }      }
   
     new_map->x= ax;      new_map->x= ax;
     new_map->y= ay;      new_map->y= ay;
   
Line 1251
 
Line 1451
  */   */
 void reset_map()  void reset_map()
 {  {
       if( fog_of_war == TRUE)
       {
     int x= 0;      int x= 0;
     int y= 0;      int y= 0;
   
     pl_pos.x= the_map.x/2;      pl_pos.x= the_map.x/2;
     pl_pos.y= the_map.y/2;      pl_pos.y= the_map.y/2;
     memset( the_map.cells[0], 0,       memset( the_map.cells[0], 0,
     sizeof( struct MapCell) * the_map.x * the_map.y);      sizeof( struct MapCell) * the_map.x * the_map.y);
     for( x= pl_pos.x; x < (pl_pos.x + use_config[CONFIG_MAPWIDTH]); x++)    for( x= pl_pos.x; x < (pl_pos.x + mapx); x++)
     {      {
  for( y= pl_pos.y; y < (pl_pos.y + use_config[CONFIG_MAPHEIGHT]); y++)       for( y= pl_pos.y; y < (pl_pos.y + mapy); y++)
  {   {
      the_map.cells[x][y].need_update= 1;       the_map.cells[x][y].need_update= 1;
  }   }
     }      }
     cs_print_string(csocket.fd, "mapredraw");      }
       else
       {
    int x= 0;
    int y= 0;
    memset( the_map.cells[0], 0,
    sizeof( struct MapCell) * the_map.x * the_map.y);
    for( x= 0; x < mapx; x++)
    {
        for( y= 0; y < mapy; y++)
        {
    the_map.cells[x][y].need_update= 1;
        }
    }
       }
      
       cs_write_string( csocket.fd, "mapredraw", 9);
      
       return;
   }
   
   void display_map_clearcell(long x,long y)
   {
       if( fog_of_war == TRUE)
       {
    /* we don't want to clear out the values yet. We will do that
    * next time we try to write some data to this tile. For now
    * we just mark that it has been cleared. Also mark it for
    * update so we can draw the proper fog cell over it
    */
    x+= pl_pos.x;
    y+= pl_pos.y;
    the_map.cells[x][y].cleared= 1;
    the_map.cells[x][y].need_update= 1;
       }
       else
       {
    int i;
    the_map.cells[x][y].count = 0;
    the_map.cells[x][y].darkness = 0;
    the_map.cells[x][y].need_update = 1;
    the_map.cells[x][y].have_darkness = 0;
    the_map.cells[x][y].cleared= 0;
    for (i=0; i<MAXFACES; i++)
        the_map.cells[x][y].faces[i] = -1;  /* empty/blank face */
       }
   
     return;      return;
 }  }
   
Line 1275
 
Line 1522
     int x= 0;      int x= 0;
     int y= 0;      int y= 0;
   
     for( y= 0; y < use_config[CONFIG_MAPHEIGHT]; y++)      for( y= 0; y < mapy; y++)
     {      {
  for( x= 0; x < use_config[CONFIG_MAPWIDTH]; x++)   for( x= 0; x < mapx; x++)
  {   {
        if( the_map.cells[x][y].count== 0)
    fprintf( stderr, "[ - ]");
        else
      fprintf( stderr, "[%3d]", the_map.cells[x][y].darkness);       fprintf( stderr, "[%3d]", the_map.cells[x][y].darkness);
  }   }
  fprintf( stderr, "\n");   fprintf( stderr, "\n");
Line 1291
 
Line 1541
     int y= 0;      int y= 0;
     int z= 0;      int z= 0;
   
     int local_mapx = pl_pos.x + use_config[CONFIG_MAPWIDTH];      int local_mapx;
     int local_mapy = pl_pos.y + use_config[CONFIG_MAPHEIGHT];      int local_mapy;
   
     if( use_config[CONFIG_FOGWAR] == TRUE)      if( fog_of_war == TRUE)
     {      {
    local_mapx= pl_pos.x + mapx;
    local_mapy= pl_pos.y + mapy;
  printf( " Current X pos: %d -- Current Y pos: %d\n",    printf( " Current X pos: %d -- Current Y pos: %d\n",
  pl_pos.x, pl_pos.y);   pl_pos.x, pl_pos.y);
     }      }
       else
       {
    local_mapx= mapx;
    local_mapy= mapy;
       }
   
     fprintf( stderr, "-----------------------\n");      fprintf( stderr, "-----------------------\n");
     for( y= pl_pos.y ; y < local_mapy; y++)      for( y= (fog_of_war == TRUE ? pl_pos.y : 0); y < local_mapy; y++)
     {      {
  for( z= 0; z < MAXFACES; z++)   for( z= 0; z < MAXFACES; z++)
  {   {
      for( x= pl_pos.x ; x < local_mapx; x++)       for( x= (fog_of_war == TRUE ? pl_pos.x : 0); x < local_mapx; x++)
      {       {
  if(the_map.cells[x][y].heads[z].face  <= 0)   if( the_map.cells[x][y].count == 0)
      fprintf( stderr, "[ -- ]");       fprintf( stderr, "[ -- ]");
  else    else
      fprintf( stderr, "[%4d]", the_map.cells[x][y].heads[z].face);       fprintf( stderr, "[%4d]", the_map.cells[x][y].faces[z]);
      }       }
      fprintf( stderr, "\n");       fprintf( stderr, "\n");
  }   }
Line 1322
 
Line 1579
   
 void set_map_darkness(int x, int y, uint8 darkness)  void set_map_darkness(int x, int y, uint8 darkness)
 {  {
     if( fog_of_war == TRUE)
     {
     x+= pl_pos.x;      x+= pl_pos.x;
     y+= pl_pos.y;      y+= pl_pos.y;
     }
   
     the_map.cells[x][y].have_darkness = 1;      the_map.cells[x][y].have_darkness = 1;
     if (darkness != (255 - the_map.cells[x][y].darkness )) {      if (darkness != (255 - the_map.cells[x][y].darkness )) {
  the_map.cells[x][y].darkness = 255 - darkness;   the_map.cells[x][y].darkness = 255 - darkness;
  the_map.cells[x][y].need_update = 1;   the_map.cells[x][y].need_update = 1;
   #ifdef GDK_XUTIL
  /* pretty ugly - since the light code with pngximage uses   /* pretty ugly - since the light code with pngximage uses
  * neighboring spaces to adjust the darkness, we now need to   * neighboring spaces to adjust the darkness, we now need to
  * let the neighbors know they should update their darkness   * let the neighbors know they should update their darkness
  * now.   * now.
  */   */
  if (use_config[CONFIG_SDL]) {   if (pngximage || sdlimage) {
      if (x-1>0) the_map.cells[x-1][y].need_update = 1;       if (x-1>0) the_map.cells[x-1][y].need_update = 1;
      if (y-1>0) the_map.cells[x][y-1].need_update = 1;       if (y-1>0) the_map.cells[x][y-1].need_update = 1;
      if (x+1<use_config[CONFIG_MAPWIDTH]) the_map.cells[x+1][y].need_update = 1;       if (x+1<mapx) the_map.cells[x+1][y].need_update = 1;
      if (y+1<use_config[CONFIG_MAPHEIGHT]) the_map.cells[x][y+1].need_update = 1;       if (y+1<mapy) the_map.cells[x][y+1].need_update = 1;
    }
   #endif /* GDK_XUTIL */
       }
   }
   
   /* sets the face at layer to some value.  We just can't
    * restact arbitrarily, as the server now sends faces only
    * for layers that change, and not the entire space.
    */
   void set_map_face(int x, int y, int layer, int face)
   {
     if( fog_of_war == TRUE)
     {
         x+= pl_pos.x;
         y+= pl_pos.y;
     }
   
     if( (fog_of_war == TRUE) && (the_map.cells[x][y].cleared == 1) )
     {
         /* This cell has been cleared previously but now we are
          * writing new data to do. So we have to clear it for real now
          */
         int i= 0;
         the_map.cells[x][y].count= 0;
         the_map.cells[x][y].darkness= 0;
         the_map.cells[x][y].need_update= 1;
         the_map.cells[x][y].have_darkness= 0;
         the_map.cells[x][y].cleared= 0;
         for (i=0; i<MAXFACES; i++)
      the_map.cells[x][y].faces[i]= -1;  /* empty/blank face */
     }
   
     the_map.cells[x][y].faces[layer] = face;
     if ((layer+1) > the_map.cells[x][y].count)
       the_map.cells[x][y].count = layer+1;
     the_map.cells[x][y].need_update = 1;
     the_map.cells[x][y].have_darkness = 1;
  }   }
   
   
   void display_map_addbelow(long x,long y,long face)
   {
   
       if( fog_of_war == TRUE)
       {
    x+= pl_pos.x;
    y+= pl_pos.y;
     }      }
      
       if( (fog_of_war == TRUE) && (the_map.cells[x][y].cleared == 1) )
       {
    /* This cell has been cleared previously but now we are
    * writing new data to do. So we have to clear it for real now
    */
    int i= 0;
    the_map.cells[x][y].count= 0;
    the_map.cells[x][y].darkness= 0;
    the_map.cells[x][y].need_update= 1;
    the_map.cells[x][y].have_darkness= 0;
    the_map.cells[x][y].cleared= 0;
    for (i=0; i<MAXFACES; i++)
        the_map.cells[x][y].faces[i]= -1;  /* empty/blank face */
 }  }
   
       the_map.cells[x][y].faces[the_map.cells[x][y].count] = face&0xFFFF;
       the_map.cells[x][y].count ++;
       the_map.cells[x][y].need_update = 1;
   }
   
 /*   /*
  * Returns true if virtual view is about to butt up against    * Returns true if virtual view is about to butt up against
Line 1351
 
Line 1676
  */   */
 static int need_recenter_map( int dx, int dy)  static int need_recenter_map( int dx, int dy)
 {  {
     if( pl_pos.x + dx + use_config[CONFIG_MAPWIDTH] + MAX_MAP_OFFSET >= the_map.x ||     
  pl_pos.y + dy + use_config[CONFIG_MAPHEIGHT] + MAX_MAP_OFFSET >= the_map.y ||      if( pl_pos.x + dx + mapx >= the_map.x ||
    pl_pos.y + dx + mapy >= the_map.y ||
  pl_pos.x + dx <= 0                ||   pl_pos.x + dx <= 0                ||
  pl_pos.y + dy <= 0 )   pl_pos.y + dy <= 0 )
     {      {
Line 1404
 
Line 1730
      * virtual maps with large views this could happen before our 0,0 view       * virtual maps with large views this could happen before our 0,0 view
      * coordinate is within 1/4 of the edge) we shift to the center.       * coordinate is within 1/4 of the edge) we shift to the center.
      */       */
     if( pl_pos.x <= (map->x/4) || (pl_pos.x +MAX_MAP_OFFSET) >= (map->x*3/4) ||      if( pl_pos.x <= (map->x/4) || pl_pos.x >= (map->x*3/4) ||
  pl_pos.x + use_config[CONFIG_MAPWIDTH] + 1 >= map->x )   pl_pos.x + mapx + 1 >= map->x )
     {      {
  x_shift= map->x/2 - pl_pos.x;   x_shift= map->x/2 - pl_pos.x;
     }      }
     if( pl_pos.y <= (map->y/4) || (pl_pos.y + MAX_MAP_OFFSET) >= (map->y*3/4) ||      if( pl_pos.y <= (map->y/4) || pl_pos.y >= (map->y*3/4) ||
  pl_pos.y + use_config[CONFIG_MAPHEIGHT] + 1 >= map->y )   pl_pos.y + mapy + 1 >= map->y )
     {      {
  y_shift= map->y/2 - pl_pos.y;   y_shift= map->y/2 - pl_pos.y;
     }      }
Line 1457
 
Line 1783
 void display_mapscroll(int dx,int dy)  void display_mapscroll(int dx,int dy)
 {  {
     int x,y;      int x,y;
       static struct Map newmap;
     int local_mapx= 0, local_mapy= 0;      int local_mapx= 0, local_mapy= 0;
   
       if( fog_of_war == TRUE)
       {
     /* We don't need to memcopy any of this stuff around cause       /* We don't need to memcopy any of this stuff around cause
      * we are keeping it in memory. We do need to update our       * we are keeping it in memory. We do need to update our
      * virtual position though       * virtual position though
      */       */
    
     if( need_recenter_map( dx, dy) == TRUE)       if( need_recenter_map( dx, dy) == TRUE)
    {
  recenter_virtual_map_view( &the_map);   recenter_virtual_map_view( &the_map);
    }
    
     pl_pos.x+= dx;      pl_pos.x+= dx;
     pl_pos.y+= dy;      pl_pos.y+= dy;
     local_mapx= pl_pos.x + use_config[CONFIG_MAPWIDTH];   local_mapx= pl_pos.x + mapx;
     local_mapy= pl_pos.y + use_config[CONFIG_MAPHEIGHT];   local_mapy= pl_pos.y + mapy;
    
     /*      /*
      * For cells about to enter the view, mark them as       * For cells about to enter the view, mark them as
Line 1479
 
Line 1810
      * the image data around. This is needed for proper        * the image data around. This is needed for proper
      * drawing of blank or black tiles coming into view       * drawing of blank or black tiles coming into view
      */       */
     for( x= pl_pos.x; x < pl_pos.x + use_config[CONFIG_MAPWIDTH]; x++) {   for( x= pl_pos.x; x < pl_pos.x + mapx; x++) {
  for( y= pl_pos.y; y < pl_pos.y + use_config[CONFIG_MAPHEIGHT]; y++) {       for( y= pl_pos.y; y < pl_pos.y + mapy; y++) {
      the_map.cells[x][y].need_update= 1;   if( (x + dx) < pl_pos.x || (x + dx) >= (mapx + pl_pos.x) ||
      if( (x + dx) < pl_pos.x || (x + dx) >= (use_config[CONFIG_MAPWIDTH] + pl_pos.x) ||       (y + dy) < pl_pos.y || (y + dy) >= (mapy + pl_pos.y) )
         (y + dy) < pl_pos.y || (y + dy) >= (use_config[CONFIG_MAPHEIGHT] + pl_pos.y) )    {
        if( x < 0 || y < 0 || x >= the_map.x ||
    y >= the_map.y)
      {       {
  if( x < 0 || y < 0 || x >= the_map.x || y >= the_map.y)  
      continue;       continue;
        }
   
  the_map.cells[x][y].cleared= 1;  
  the_map.cells[x][y].need_update= 1;   the_map.cells[x][y].need_update= 1;
         the_map.cells[x][y].keephead = 1;/*otherwise we will also mark the multipart as cleared*/       the_map.cells[x][y].cleared= 1;
      }       }
  } /* for y */   } /* for y */
     } /* for x */      } /* for x */
       }
       else
       {
    local_mapx= mapx;
    local_mapy= mapy;
       }
   
       if( newmap.cells == NULL)
    allocate_map( &newmap, map_size, map_size);
   
       /* Check to see if map_size changed since we allocated newmap */
       if( newmap.x != map_size)
       {
    if( newmap.cells)
        free( newmap.cells);
   
    allocate_map( &newmap, map_size, map_size);
       }
      
       if( fog_of_war == FALSE) {
         for(x=0;x<mapx;x++) {
    for(y=0;y<mapy;y++) {
      /* In case its own of range, set the count to zero */
      if (x+dx < 0 || x+dx >= mapx ||y+dy < 0 || y+dy >= mapy) {
        memset((char*)&newmap.cells[x][y], 0, sizeof(struct MapCell));
   #ifdef GDK_XUTIL
        /* basically, if using pngximage, don't want to update it,
         * since the scrolling below will effectively take care of
         * our redraw
         *
         * Changed my smacfiggen 6/20/2001 -- When new cells come onto
         * the map and we aren't using the new map command we want to
         * mark these as updated or else blank tiles get blitted with
         * old info.
         *
         */
        if ( !map1cmd)
          newmap.cells[x][y].need_update=1;
   #else
        newmap.cells[x][y].need_update=1;
   #endif
       
      } else {
        memcpy((char*)&(newmap.cells[x][y]), (char*)&(the_map.cells[x+dx][y+dy]),
       sizeof(struct MapCell));
   #ifdef GDK_XUTIL
        /* if using pngximage, we will instead set the map_did_scroll
         * to 1 - we don't want to regen the backing image
         */
        if (!pngximage) {
   #ifdef HAVE_SDL
          if( !sdlimage)
   #endif
    newmap.cells[x][y].need_update=1;
        }
   #else
        newmap.cells[x][y].need_update=1; /* new space needs to be redrawn */
   #endif
      }
    }
         }
         memcpy((char*)the_map.cells[0],(char*)newmap.cells[0],
         sizeof(struct MapCell)*newmap.x*newmap.y );
       }
   #ifdef GDK_XUTIL
       if (pngximage ) {
    /* move the screen data around - this is more efficient than re-calculating it all
    * memmove does support moving around overlapping data, so this is safe.
    *
    */
    if (dy<0) {
        int offset = -dy * mapx * image_size * image_size * BPP;
        memmove(screen +offset, screen, mapx * (mapy + dy)* image_size * image_size * BPP);
    } else if (dy>0) {
        int offset = dy * mapx * image_size * image_size * BPP;
        memmove(screen, screen + offset, mapx * (mapy + dy)* image_size * image_size * BPP);
    }
    if (dx) {
        int y;
   
        for (y=0; y < mapy * image_size; y++) {
    if (dx<0)
        /* -dx because dx is already negative, so this effective adds */
        memmove(screen + y * mapx * image_size * BPP - dx * image_size * BPP,
    screen + y * mapx * image_size * BPP,
    (mapx + dx) * image_size * BPP);
    else /* dx is positive */
        memmove(screen + y * mapx * image_size * BPP,
    screen + y * mapx * image_size * BPP + dx * image_size * BPP,
    (mapx - dx) * image_size * BPP);
        }
    }
    map_did_scroll=1;
       }
   #ifdef HAVE_SDL
       if( sdlimage)
         {
    /* a copy of what pngximage does except sdl specfic
    * mapsurface->pitch is the length of a scanline in bytes
    * including alignment padding
    */
   
    SDL_LockSurface( mapsurface);
    if( dy < 0)
      {
        int offset= mapsurface->pitch * (-dy*image_size);
        memmove( mapsurface->pixels + offset, mapsurface->pixels,
         mapsurface->pitch * (mapsurface->h + dy*image_size) );
      }
    else if( dy > 0)
      {
        int offset= mapsurface->pitch * (dy*image_size);
        memmove( mapsurface->pixels,  mapsurface->pixels + offset,
         mapsurface->pitch * (mapsurface->h - dy*image_size) );
      }
   
    if( dx)
      {
        int y;
        for( y= 0; y < mapsurface->h; y++)
          {
    if( dx < 0)
      {
        char* start_of_row= mapsurface->pixels + mapsurface->pitch * y;
        int offset= ( mapsurface->format->BytesPerPixel * image_size * -dx);
        memmove( start_of_row + offset, start_of_row,
         mapsurface->pitch - offset);
      }
    else
      {
        char* start_of_row= mapsurface->pixels + mapsurface->pitch * y;
        int offset= ( mapsurface->format->BytesPerPixel * image_size * dx);
        memmove( start_of_row, start_of_row + offset,
         mapsurface->pitch - offset);
      }
          }
      }
    SDL_UnlockSurface( mapsurface);
   
    map_did_scroll= 1;
         }
   
   #endif /* HAVE_SDL */
       
   /*    fprintf(stderr,"scroll command: %d %d\n", dx, dy);*/
   #endif
 }  }
   
   
Line 1506
 
Line 1983
  */   */
 void reset_map_data()  void reset_map_data()
 {  {
       if( fog_of_war == TRUE)
       {
     int x= 0;      int x= 0;
     int y= 0;      int y= 0;
   
     pl_pos.x= the_map.x/2;      pl_pos.x= the_map.x/2;
     pl_pos.y= the_map.y/2;      pl_pos.y= the_map.y/2;
     memset( the_map.cells[0], 0,      memset( the_map.cells[0], 0,
     sizeof( struct MapCell) * the_map.x * the_map.y);      sizeof( struct MapCell) * the_map.x * the_map.y);
     for( x= pl_pos.x; x < (pl_pos.x + use_config[CONFIG_MAPWIDTH]); x++)   for( x= pl_pos.x; x < (pl_pos.x + mapx); x++)
     {      {
  for( y= pl_pos.y; y < (pl_pos.y + use_config[CONFIG_MAPHEIGHT]); y++)       for( y= pl_pos.y; y < (pl_pos.y + mapy); y++)
  {   {
      the_map.cells[x][y].need_update= 1;       the_map.cells[x][y].need_update= 1;
  }   }
     }      }
 }  }
       else
       {
    int x= 0;
    int y= 0;
    memset( the_map.cells[0], 0,
    sizeof( struct MapCell) * the_map.x * the_map.y);
    for( x= 0; x < mapx; x++)
    {
        for( y= 0; y < mapy; y++)
        {
    the_map.cells[x][y].need_update= 1;
        }
    }
       }
   }


Legend:
line(s) removed in v.1.16.2.1 
line(s) changed
 line(s) added in v.1.1

File made using version 1.96 of cvs2html by leaf at 2006-02-16 21:08