// Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder #include #include #include #include #ifndef _WIN32 #include #endif #include "grfio.h" char grf_list_file[256] = "tools/mapcache/grf_files.txt"; char map_list_file[256] = "tools/mapcache/map_list.txt"; char map_cache_file[256] = "map_cache.dat"; #define MAP_NAME_LENGTH 16 #define NO_WATER 1000000 // Used internally, this structure contains the physical map cells struct map_data { short xs; short ys; unsigned char *cells; }; // This is the header appended before every compressed map cells info struct map_cache_info { char name[MAP_NAME_LENGTH]; unsigned short index; short xs; short ys; long len; }; // This is the main header found at the very beginning of the file struct map_cache_head { short sizeof_header; short sizeof_mapinfo; long filesize; unsigned short map_count; } header; FILE *map_cache_fp; // Read map from GRF's GAT and RSW files int read_map(char *name, struct map_data *m) { char filename[256]; char *gat, *rsw; int water_height; int x, y, xs, ys; struct gat_cell { float height[4]; int type; } *p = NULL; // Open map GAT sprintf(filename,"data\\%s.gat", name); gat = (char *)grfio_read(filename); if (gat == NULL) return 0; // Open map RSW sprintf(filename,"data\\%s.rsw", name); rsw = (char *)grfio_read(filename); // Read water height if (rsw) { float temp = *(float*)(rsw+166); water_height = (int)temp; free(rsw); } else water_height = NO_WATER; // Read map size and allocate needed memory xs = m->xs = *(int*)(gat+6); ys = m->ys = *(int*)(gat+10); m->cells = (unsigned char *)malloc(xs*ys); // Set cell properties for (y = 0; y < ys; y++) { p = (struct gat_cell*)(gat+14+y*xs*20); for (x = 0; x < xs; x++) { if (water_height != NO_WATER && p->type == 0 && (p->height[0] > water_height || p->height[1] > water_height || p->height[2] > water_height || p->height[3] > water_height)) m->cells[x+y*xs] = 3; // Cell is 0 (walkable) but under water level, set to 3 (walkable water) else m->cells[x+y*xs] = p->type; p++; } } free(gat); return 1; } void cache_map(char *name, unsigned short index, struct map_data *m) { struct map_cache_info info; unsigned long len; char *write_buf; // Create an output buffer twice as big as the uncompressed map... this way we're sure it fits len = m->xs*m->ys*2; write_buf = (char *)malloc(len); // Compress the cells and get the compressed length encode_zip((unsigned char *)write_buf, &len, m->cells, m->xs*m->ys); // Fill the map header strncpy(info.name, name, MAP_NAME_LENGTH); info.index = index; info.xs = m->xs; info.ys = m->ys; info.len = len; // Append map header then compressed cells at the end of the file fseek(map_cache_fp, header.filesize, SEEK_SET); fwrite(&info, sizeof(struct map_cache_info), 1, map_cache_fp); fwrite(write_buf, 1, len, map_cache_fp); header.map_count++; header.filesize += header.sizeof_mapinfo + len; free(write_buf); free(m->cells); return; } int main(int argc, char *argv[]) { FILE *list; char line[1024]; struct map_data map; char name[MAP_NAME_LENGTH]; unsigned short index = 1; if(argc > 1) strcpy(grf_list_file, argv[1]); if(argc > 2) strcpy(map_list_file, argv[2]); if(argc > 3) strcpy(map_cache_file, argv[3]); printf("Initializing grfio with %s\n", grf_list_file); grfio_init(grf_list_file); printf("Opening map cache: %s\n", map_cache_file); if(!(map_cache_fp = fopen(map_cache_file, "wb"))) { printf("Failure when opening map cache file %s\n", map_cache_file); exit(1); } printf("Opening map list: %s\n", map_list_file); if(!(list = fopen(map_list_file, "r"))) { printf("Failure when opening maps list file %s\n", map_list_file); exit(1); } // Initialize the main header header.sizeof_header = sizeof(struct map_cache_head); header.sizeof_mapinfo = sizeof(struct map_cache_info); header.map_count = 0; header.filesize = sizeof(struct map_cache_head); // Read and process the map list while(fgets(line, 1020, list)){ if(line[0] == '/' && line[1] == '/') continue; if(sscanf(line, "%16s %hu", name, &index) > 0) { // No defines in strings, 16 is hardcoded here printf("Index %d : %s\n", index, name); if(read_map(name, &map)) cache_map(name, index, &map); else printf("Map file not found in GRF\n"); // If the 2nd argument is omitted at next line, we'll keep last used index + 1 index++; } else printf("Skipping incorrect line\n"); } printf("Closing map list: %s\n", map_list_file); fclose(list); printf("Closing map cache: %s\n", map_cache_file); // Write the main header and close the map cache fseek(map_cache_fp, 0, SEEK_SET); fwrite(&header, sizeof(struct map_cache_head), 1, map_cache_fp); fclose(map_cache_fp); printf("Finalizing grfio\n"); grfio_final(); printf("%d maps cached\n", header.map_count); return 0; }