| version 1.6 | | version 1.7 |
|---|
| | |
| /* | | /* |
| * static char *rcsid_xutil_c = | | * static char *rcsid_xutil_c = |
| * "$Id: xutil.c,v 1.6 2002/03/27 07:56:53 mwedel Exp $"; | | * "$Id: xutil.c,v 1.7 2002/04/03 07:46:52 mwedel Exp $"; |
| */ | | */ |
| /* | | /* |
| Crossfire client, a client program for the crossfire program. | | Crossfire client, a client program for the crossfire program. |
| | |
| 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 (cpl.echo_bindings) draw_info("stop run",NDI_BLACK); | | if (use_config[CONFIG_ECHO]) 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)," "); |
| | |
| * 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 |
| | |
| 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; |
| | |
| } | | } |
| else | | else |
| sprintf(buf,"move %s (ignored)", first_match->command); | | sprintf(buf,"move %s (ignored)", first_match->command); |
| if (cpl.echo_bindings) draw_info(buf,NDI_BLACK); | | if (use_config[CONFIG_ECHO]) draw_info(buf,NDI_BLACK); |
| } | | } |
| else { | | else { |
| if (cpl.echo_bindings) draw_info(first_match->command,NDI_BLACK); | | if (use_config[CONFIG_ECHO]) draw_info(first_match->command,NDI_BLACK); |
| extended_command(first_match->command); | | extended_command(first_match->command); |
| } | | } |
| return; | | return; |
| | |
| } | | } |
| | | |
| | | |
| /* 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 (image_file[0] == 0) return 0; | | |
| | | |
| if (!face_info.cache_images) { | | |
| face_info.cache_images=1; /* we want face commands from server */ | | |
| } | | |
| | | |
| 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, (uint8*)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 |
| */ | | */ |
| | |
| 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 |
| | |
| * FIX ME: Don't assume rectangle | | * FIX ME: Don't assume rectangle |
| */ | | */ |
| | | |
| int map_size= 0; | | |
| PlayerPosition pl_pos; | | PlayerPosition pl_pos; |
| | | |
| | | |
| | |
| */ | | */ |
| 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) |
| | |
| } | | } |
| | | |
| new_map->cells= (struct MapCell**)calloc( sizeof( struct MapCell*) * ay | | new_map->cells= (struct MapCell**)calloc( sizeof( struct MapCell*) * ay |
| + sizeof( struct MapCell) * | | + sizeof( struct MapCell) * ax * ay, 1); |
| map_size * map_size, 1); | | |
| if( new_map->cells == NULL) | | if( new_map->cells == NULL) |
| return; | | return; |
| | | |
| | |
| /* 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; |
| | | |
| | |
| */ | | */ |
| 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 + mapx); x++) | | for( x= pl_pos.x; x < (pl_pos.x + use_config[CONFIG_MAPWIDTH]); x++) |
| { | | |
| for( y= pl_pos.y; y < (pl_pos.y + mapy); y++) | | |
| { | | |
| 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++) | | for( y= pl_pos.y; y < (pl_pos.y + use_config[CONFIG_MAPHEIGHT]); y++) |
| { | | { |
| the_map.cells[x][y].need_update= 1; | | the_map.cells[x][y].need_update= 1; |
| } | | } |
| } | | } |
| } | | |
| | | |
| cs_print_string(csocket.fd, "mapredraw"); | | cs_print_string(csocket.fd, "mapredraw"); |
| return; | | return; |
| } | | } |
| | | |
| void display_map_clearcell(long x,long y) | | void display_map_clearcell(long x,long y) |
| { | | { |
| if( fog_of_war == TRUE) | | |
| | | x+= pl_pos.x; |
| | | y+= pl_pos.y; |
| | | |
| | | if(use_config[CONFIG_FOGWAR] == TRUE) |
| { | | { |
| | | int i,got_one=0; |
| | | |
| /* we don't want to clear out the values yet. We will do that | | /* 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 | | * 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 | | * we just mark that it has been cleared. Also mark it for |
| * update so we can draw the proper fog cell over it | | * update so we can draw the proper fog cell over it |
| */ | | */ |
| x+= pl_pos.x; | | |
| y+= pl_pos.y; | | /* If the space is completly black, don't mark this as a |
| | | * fog cell - that chews up extra cpu time. Likewise, |
| | | * if the space is completely dark, don't draw it either. |
| | | */ |
| | | for (i=0; i<MAXFACES; i++) |
| | | if (the_map.cells[x][y].faces[i]>0) got_one=1; |
| | | |
| | | if (!got_one || the_map.cells[x][y].darkness>200) { |
| | | 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; |
| | | } |
| | | else { |
| the_map.cells[x][y].cleared= 1; | | the_map.cells[x][y].cleared= 1; |
| the_map.cells[x][y].need_update= 1; | | the_map.cells[x][y].need_update= 1; |
| } | | } |
| | | } |
| else | | else |
| { | | { |
| int i; | | int i; |
| | |
| int x= 0; | | int x= 0; |
| int y= 0; | | int y= 0; |
| | | |
| for( y= 0; y < mapy; y++) | | for( y= 0; y < use_config[CONFIG_MAPHEIGHT]; y++) |
| { | | { |
| for( x= 0; x < mapx; x++) | | for( x= 0; x < use_config[CONFIG_MAPWIDTH]; x++) |
| { | | { |
| if( the_map.cells[x][y].count== 0) | | if( the_map.cells[x][y].count== 0) |
| fprintf( stderr, "[ - ]"); | | fprintf( stderr, "[ - ]"); |
| | |
| int y= 0; | | int y= 0; |
| int z= 0; | | int z= 0; |
| | | |
| int local_mapx; | | int local_mapx = pl_pos.x + use_config[CONFIG_MAPWIDTH]; |
| int local_mapy; | | int local_mapy = pl_pos.y + use_config[CONFIG_MAPHEIGHT]; |
| | | |
| if( fog_of_war == TRUE) | | if( use_config[CONFIG_FOGWAR] == 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= (fog_of_war == TRUE ? pl_pos.y : 0); y < local_mapy; y++) | | for( y= pl_pos.y ; y < local_mapy; y++) |
| { | | { |
| for( z= 0; z < MAXFACES; z++) | | for( z= 0; z < MAXFACES; z++) |
| { | | { |
| for( x= (fog_of_war == TRUE ? pl_pos.x : 0); x < local_mapx; x++) | | for( x= pl_pos.x ; x < local_mapx; x++) |
| { | | { |
| if( the_map.cells[x][y].count == 0) | | if( the_map.cells[x][y].count == 0) |
| fprintf( stderr, "[ -- ]"); | | fprintf( stderr, "[ -- ]"); |
| | |
| | | |
| 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 (pngximage || sdlimage) { | | if (use_config[CONFIG_SDL]) { |
| 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<mapx) the_map.cells[x+1][y].need_update = 1; | | if (x+1<use_config[CONFIG_MAPWIDTH]) the_map.cells[x+1][y].need_update = 1; |
| if (y+1<mapy) the_map.cells[x][y+1].need_update = 1; | | if (y+1<use_config[CONFIG_MAPHEIGHT]) the_map.cells[x][y+1].need_update = 1; |
| } | | } |
| #endif /* GDK_XUTIL */ | | |
| } | | } |
| } | | } |
| | | |
| | |
| */ | | */ |
| void set_map_face(int x, int y, int layer, int face) | | void set_map_face(int x, int y, int layer, int face) |
| { | | { |
| if( fog_of_war == TRUE) | | |
| { | | |
| x+= pl_pos.x; | | x+= pl_pos.x; |
| y+= pl_pos.y; | | y+= pl_pos.y; |
| } | | if(use_config[CONFIG_FOGWAR] && (the_map.cells[x][y].cleared == 1)) { |
| | | |
| if( (fog_of_war == TRUE) && (the_map.cells[x][y].cleared == 1) ) | | |
| { | | |
| /* This cell has been cleared previously but now we are | | /* This cell has been cleared previously but now we are |
| * writing new data to do. So we have to clear it for real now | | * writing new data to do. So we have to clear it for real now |
| */ | | */ |
| int i= 0; | | int i= 0; |
| | | |
| the_map.cells[x][y].count= 0; | | the_map.cells[x][y].count= 0; |
| the_map.cells[x][y].darkness= 0; | | the_map.cells[x][y].darkness= 0; |
| the_map.cells[x][y].need_update= 1; | | the_map.cells[x][y].need_update= 1; |
| | |
| void display_map_addbelow(long x,long y,long face) | | void display_map_addbelow(long x,long y,long face) |
| { | | { |
| | | |
| if( fog_of_war == TRUE) | | |
| { | | |
| x+= pl_pos.x; | | x+= pl_pos.x; |
| y+= pl_pos.y; | | y+= pl_pos.y; |
| } | | if (use_config[CONFIG_FOGWAR] && (the_map.cells[x][y].cleared == 1) ) |
| | | |
| if( (fog_of_war == TRUE) && (the_map.cells[x][y].cleared == 1) ) | | |
| { | | { |
| /* This cell has been cleared previously but now we are | | /* This cell has been cleared previously but now we are |
| * writing new data to do. So we have to clear it for real now | | * writing new data to do. So we have to clear it for real now |
| | |
| static int need_recenter_map( int dx, int dy) | | static int need_recenter_map( int dx, int dy) |
| { | | { |
| | | |
| if( pl_pos.x + dx + mapx >= the_map.x || | | if( pl_pos.x + dx + use_config[CONFIG_MAPWIDTH] >= the_map.x || |
| pl_pos.y + dx + mapy >= the_map.y || | | pl_pos.y + dx + use_config[CONFIG_MAPHEIGHT] >= the_map.y || |
| pl_pos.x + dx <= 0 || | | pl_pos.x + dx <= 0 || |
| pl_pos.y + dy <= 0 ) | | pl_pos.y + dy <= 0 ) |
| { | | { |
| | |
| * 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 >= (map->x*3/4) || | | if( pl_pos.x <= (map->x/4) || pl_pos.x >= (map->x*3/4) || |
| pl_pos.x + mapx + 1 >= map->x ) | | pl_pos.x + use_config[CONFIG_MAPWIDTH] + 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 >= (map->y*3/4) || | | if( pl_pos.y <= (map->y/4) || pl_pos.y >= (map->y*3/4) || |
| pl_pos.y + mapy + 1 >= map->y ) | | pl_pos.y + use_config[CONFIG_MAPHEIGHT] + 1 >= map->y ) |
| { | | { |
| y_shift= map->y/2 - pl_pos.y; | | y_shift= map->y/2 - pl_pos.y; |
| } | | } |
| | |
| 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 + mapx; | | local_mapx= pl_pos.x + use_config[CONFIG_MAPWIDTH]; |
| local_mapy= pl_pos.y + mapy; | | local_mapy= pl_pos.y + use_config[CONFIG_MAPHEIGHT]; |
| | | |
| /* | | /* |
| * For cells about to enter the view, mark them as | | * For cells about to enter the view, mark them as |
| | |
| * 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 + mapx; x++) { | | for( x= pl_pos.x; x < pl_pos.x + use_config[CONFIG_MAPWIDTH]; x++) { |
| for( y= pl_pos.y; y < pl_pos.y + mapy; y++) { | | for( y= pl_pos.y; y < pl_pos.y + use_config[CONFIG_MAPHEIGHT]; y++) { |
| if( (x + dx) < pl_pos.x || (x + dx) >= (mapx + pl_pos.x) || | | the_map.cells[x][y].need_update= 1; |
| (y + dy) < pl_pos.y || (y + dy) >= (mapy + pl_pos.y) ) | | if( (x + dx) < pl_pos.x || (x + dx) >= (use_config[CONFIG_MAPWIDTH] + pl_pos.x) || |
| { | | (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].need_update= 1; | | if (use_config[CONFIG_FOGWAR]) |
| the_map.cells[x][y].cleared= 1; | | 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 | | |
| } | | } |
| | | |
| | | |
| | |
| */ | | */ |
| 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 + mapx); x++) | | for( x= pl_pos.x; x < (pl_pos.x + use_config[CONFIG_MAPWIDTH]); x++) |
| { | | { |
| for( y= pl_pos.y; y < (pl_pos.y + mapy); y++) | | for( y= pl_pos.y; y < (pl_pos.y + use_config[CONFIG_MAPHEIGHT]); 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; | | |
| } | | |
| } | | |
| } | | |
| } | | |
| | | |
| 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); | | |
| } | | |