diff --git a/src/common/grfio.cpp b/src/common/grfio.cpp index 4951325fe7..e1122e6cad 100644 --- a/src/common/grfio.cpp +++ b/src/common/grfio.cpp @@ -455,6 +455,40 @@ void* grfio_reads(const char* fname, int* size) return buf2; } +int32 grfio_read_rsw_water_level( const char* fname ){ + unsigned char* rsw = (unsigned char *)grfio_read( fname ); + + if( rsw == nullptr ){ + // Error already reported in grfio_read + return RSW_NO_WATER; + } + + if( strncmp( (char*)rsw, "GRSW", strlen( "GRSW" ) ) ){ + ShowError( "grfio_read_rsw_water_level: Invalid RSW signature in file %s\n", fname ); + aFree( rsw ); + return RSW_NO_WATER; + } + + uint16 version = ( rsw[4] << 8 ) | rsw[5]; + + if( version < 0x104 || version > 0x202 ){ + ShowError( "grfio_read_rsw_water_level: Unsupported RSW version 0x%04x in file %s\n", version, fname ); + aFree( rsw ); + return RSW_NO_WATER; + } + + int32 level; + + if( version >= 0x202 ){ + level = (int32)*(float*)( rsw + 167 ); + }else{ + level = (int32)*(float*)( rsw + 166 ); + } + + aFree( rsw ); + + return level; +} /// Decodes encrypted filename from a version 01xx grf index. static char* decode_filename(unsigned char* buf, int len) diff --git a/src/common/grfio.hpp b/src/common/grfio.hpp index 38f196dd62..a39f2a158e 100644 --- a/src/common/grfio.hpp +++ b/src/common/grfio.hpp @@ -4,11 +4,16 @@ #ifndef GRFIO_HPP #define GRFIO_HPP +#include "cbasetypes.hpp" + +const int32 RSW_NO_WATER = 1000000; + void grfio_init(const char* fname); void grfio_final(void); void* grfio_reads(const char* fname, int* size); char* grfio_find_file(const char* fname); #define grfio_read(fn) grfio_reads(fn, NULL) +int32 grfio_read_rsw_water_level( const char* fname ); unsigned long grfio_crc32(const unsigned char *buf, unsigned int len); int decode_zip(void* dest, unsigned long* destLen, const void* source, unsigned long sourceLen); diff --git a/src/map/map.cpp b/src/map/map.cpp index 2aece64f6f..29044b0cdc 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -3704,8 +3704,6 @@ void map_data_copyall (void) { } } -#define NO_WATER 1000000 - /* * Reads from the .rsw for each map * Returns water height (or NO_WATER if file doesn't exist) or other error is encountered. @@ -3715,7 +3713,7 @@ void map_data_copyall (void) { int map_waterheight(char* mapname) { char fn[256]; - char *rsw, *found; + char *found; //Look up for the rsw sprintf(fn, "data\\%s.rsw", mapname); @@ -3724,15 +3722,7 @@ int map_waterheight(char* mapname) if (found) strcpy(fn, found); // replace with real name // read & convert fn - rsw = (char *) grfio_read (fn); - if (rsw) - { //Load water height from file - int wh = (int) *(float*)(rsw+166); //FIXME Casting between integer* and float* which have an incompatible binary data representation. - aFree(rsw); - return wh; - } - ShowWarning("Failed to find water level for (%s)\n", mapname, fn); - return NO_WATER; + return grfio_read_rsw_water_level( fn ); } /*================================== @@ -3767,7 +3757,7 @@ int map_readgat (struct map_data* m) uint32 type = *(uint32*)( gat + off + 16 ); off += 20; - if( type == 0 && water_height != NO_WATER && height > water_height ) + if( type == 0 && water_height != RSW_NO_WATER && height > water_height ) type = 3; // Cell is 0 (walkable) but under water level, set to 3 (walkable water) m->cell[xy] = map_gat2cell(type); diff --git a/src/tool/mapcache.cpp b/src/tool/mapcache.cpp index 76fb5e9210..39ddb0224e 100644 --- a/src/tool/mapcache.cpp +++ b/src/tool/mapcache.cpp @@ -17,8 +17,6 @@ #include "../common/showmsg.hpp" #include "../common/utils.hpp" -#define NO_WATER 1000000 - std::string grf_list_file = "conf/grf-files.txt"; std::string map_list_file = "map_index.txt"; std::string map_cache_file; @@ -66,14 +64,9 @@ int read_map(char *name, struct map_data *m) // Open map RSW sprintf(filename,"data\\%s.rsw", name); - rsw = (unsigned char *)grfio_read(filename); // Read water height - if (rsw) { - water_height = (int)GetFloat(rsw+166); - aFree(rsw); - } else - water_height = NO_WATER; + water_height = grfio_read_rsw_water_level( filename ); // Read map size and allocate needed memory m->xs = (int16)GetULong(gat+6); @@ -95,7 +88,7 @@ int read_map(char *name, struct map_data *m) uint32 type = GetULong( gat + off + 16 ); off += 20; - if (type == 0 && water_height != NO_WATER && height > water_height) + if (type == 0 && water_height != RSW_NO_WATER && height > water_height) type = 3; // Cell is 0 (walkable) but under water level, set to 3 (walkable water) m->cells[xy] = (unsigned char)type;