Kaynağa Gözat

Added support for RSW 2.2 (#4627)

Merged mapserver and mapcache RSW reading code
Lemongrass3110 5 yıl önce
ebeveyn
işleme
d12b4fdca0
4 değiştirilmiş dosya ile 44 ekleme ve 22 silme
  1. 34 0
      src/common/grfio.cpp
  2. 5 0
      src/common/grfio.hpp
  3. 3 13
      src/map/map.cpp
  4. 2 9
      src/tool/mapcache.cpp

+ 34 - 0
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)

+ 5 - 0
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);

+ 3 - 13
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);

+ 2 - 9
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;