소스 검색

- Took care of all the warnings in grfio and mapcache.
- Mapcache can run on system with any endianness.
The generated file contains data in little endian.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9980 54d463be-8e91-2dee-dedb-b68131a5f0ec

FlavioJS 18 년 전
부모
커밋
9e1989e51d
3개의 변경된 파일90개의 추가작업 그리고 37개의 파일을 삭제
  1. 2 0
      Changelog-Trunk.txt
  2. 9 9
      src/tool/grfio.c
  3. 79 28
      src/tool/mapcache.c

+ 2 - 0
Changelog-Trunk.txt

@@ -4,6 +4,8 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2007/03/09
+	* Mapcache can run on system with any endianness.
+	  The generated file contains data in little endian.
 	* Added info on packet 0x86 (simple move packet). Not usable until a clear 
 	  separation between entering sight/leaving sight/walking in sight is done.
 	* Propagating const char* from the script engine.

+ 9 - 9
src/tool/grfio.c

@@ -31,7 +31,6 @@
 #include <sys/stat.h>
 
 #include "grfio.h"
-#include "../common/mmo.h"
 #include "../zlib/unzip.h"
 
 #define CHUNK 16384
@@ -54,13 +53,13 @@ static char data_dir[1024] = "";	// "../";
 //----------------------------
 //	file entry table struct
 //----------------------------
-typedef struct {
+typedef struct _FILELIST {
 	int 	srclen;				// compressed size
 	int		srclen_aligned;		//
 	int		declen;				// original size
 	int		srcpos;
-	short	next;
-	int	cycle;
+	int		next;
+	int		cycle;
 	char	type;
 	char	fn[128-4*5];		// file name
 	char	*fnd;
@@ -219,7 +218,7 @@ static void decode_des_etc(BYTE *buf,int len,int type,int cycle)
 			BitConvert(buf,BitSwapTable2);
 		} else {
 			if(cnt==7 && type==0){
-				int a;
+				BYTE a;
 				BYTE tmp[8];
 				*(DWORD*)tmp     = *(DWORD*)buf;
 				*(DWORD*)(tmp+4) = *(DWORD*)(buf+4);
@@ -599,7 +598,7 @@ void* grfio_reads(char *fname, int *size)
 					decode_des_etc(buf, entry->srclen_aligned, entry->cycle == 0, entry->cycle);
 				len = entry->declen;
 				decode_zip(buf2, &len, buf, entry->srclen);
-				if (len != entry->declen) {
+				if (len != (uLong)entry->declen) {
 					printf("decode_zip size mismatch err: %d != %d\n", (int)len, entry->declen);
 					free(buf);
 					free(buf2);
@@ -679,7 +678,8 @@ static int grfio_entryread(char *gfname,int gentry)
 
 		// Get an entry
 		for (entry = 0,ofs = 0; entry < entrys; entry++) {
-			int ofs2, srclen, srccount, type;
+			int ofs2, srclen, srccount;
+			unsigned char type;
 			char *period_ptr;
 			FILELIST aentry;
 
@@ -764,7 +764,7 @@ static int grfio_entryread(char *gfname,int gentry)
 				exit(1);
 			}
 			//ofs2 = ofs+strlen((char*)(grf_filelist+ofs))+1;
-			ofs2 = ofs + strlen(fname)+1;
+			ofs2 = ofs + (int)strlen(fname)+1;
 			type = grf_filelist[ofs2+12];
 			if (type == 1 || type == 3 || type == 5) {
 				srclen = getlong(grf_filelist+ofs2);
@@ -896,7 +896,7 @@ static int grfio_add(char *fname)
 
 char *grfio_alloc_ptr(char *fname)
 {
-	int len;
+	size_t len;
 	char *buf;
 
 	if (gentry_entrys >= GENTRY_LIMIT) {

+ 79 - 28
src/tool/mapcache.c

@@ -42,52 +42,101 @@ FILE *map_cache_fp;
 
 int filesize;
 
+/// Converts an unsigned short (16 bits) from current machine order to little-endian
+unsigned short MakeUShortLE(unsigned short val)
+{
+	unsigned char buf[2];
+	buf[0] = (unsigned char)( (val & 0x00FF)         );
+	buf[1] = (unsigned char)( (val & 0xFF00) >> 0x08 );
+	return *((unsigned short*)buf);
+}
+
+/// Converts a short (16 bits) from current machine order to little-endian
+short MakeShortLE(short val)
+{
+	unsigned char buf[2];
+	buf[0] = (unsigned char)( (val & 0x00FF)         );
+	buf[1] = (unsigned char)( (val & 0xFF00) >> 0x08 );
+	return *((short*)buf);
+}
+
+/// Converts a long (32 bits) from current machine order to little-endian
+long MakeLongLE(long val)
+{
+	unsigned char buf[4];
+	buf[0] = (unsigned char)( (val & 0x000000FF)         );
+	buf[1] = (unsigned char)( (val & 0x0000FF00) >> 0x08 );
+	buf[2] = (unsigned char)( (val & 0x00FF0000) >> 0x10 );
+	buf[3] = (unsigned char)( (val & 0xFF000000) >> 0x18 );
+	return *((long*)buf);
+}
+
+/// Reads an unsigned long (32 bits) in little-endian from the buffer
+unsigned long GetULong(const unsigned char *buf)
+{
+	return	 ( ((unsigned long)(buf[0]))         )
+			|( ((unsigned long)(buf[1])) << 0x08 )
+			|( ((unsigned long)(buf[2])) << 0x10 )
+			|( ((unsigned long)(buf[3])) << 0x18 );
+}
+
+// Reads a float (32 bits) from the buffer
+float GetFloat(const unsigned char *buf)
+{
+	unsigned long val = GetULong(buf);
+	return *((float*)&val);
+}
+
 
 // Read map from GRF's GAT and RSW files
 int read_map(char *name, struct map_data *m)
 {
 	char filename[256];
-	char *gat, *rsw;
+	unsigned char *gat, *rsw;
 	int water_height;
-	int x, y, xs, ys;
-	struct gat_cell {
-		float height[4];
-		int type;
-	} *p = NULL;
+	size_t xy, off, num_cells;
+	float height[4];
+	unsigned long type;
 
 	// Open map GAT
 	sprintf(filename,"data\\%s.gat", name);
-	gat = (char *)grfio_read(filename);
+	gat = (unsigned char *)grfio_read(filename);
 	if (gat == NULL)
 		return 0;
 
 	// Open map RSW
 	sprintf(filename,"data\\%s.rsw", name);
-	rsw = (char *)grfio_read(filename);
+	rsw = (unsigned char *)grfio_read(filename);
 
 	// Read water height
 	if (rsw) { 
-		float temp = *(float*)(rsw+166);
-		water_height = (int)temp;
+		water_height = (int)GetFloat(rsw+166);
 		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);
+	m->xs = (short)GetULong(gat+6);
+	m->ys = (short)GetULong(gat+10);
+	num_cells = (size_t)m->xs*m->ys;
+	m->cells = (unsigned char *)malloc(num_cells);
 
 	// 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++;
-		}
+	off = 14;
+	for (xy = 0; xy < num_cells; xy++)
+	{
+		// Height of the corners
+		height[0] = GetFloat( gat + off      );
+		height[1] = GetFloat( gat + off + 4  );
+		height[2] = GetFloat( gat + off + 8  );
+		height[3] = GetFloat( gat + off + 12 );
+		// Type of cell
+		type      = GetULong( gat + off + 16 );
+		off += 20;
+		if (water_height != NO_WATER && type == 0 && (height[0] > water_height || height[1] > water_height || height[2] > water_height || height[3] > water_height))
+			m->cells[xy] = 3; // Cell is 0 (walkable) but under water level, set to 3 (walkable water)
+		else
+			m->cells[xy] = (unsigned char)type;
 	}
 
 	free(gat);
@@ -109,10 +158,10 @@ void cache_map(char *name, unsigned short index, struct map_data *m)
 
 	// 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;
+	info.index = MakeUShortLE(index);
+	info.xs = MakeShortLE(m->xs);
+	info.ys = MakeShortLE(m->ys);
+	info.len = MakeLongLE((long)len);
 
 	// Append map header then compressed cells at the end of the file
 	fseek(map_cache_fp, filesize, SEEK_SET);
@@ -146,13 +195,15 @@ int main(int argc, char *argv[])
 	grfio_init(grf_list_file);
 
 	printf("Opening map cache: %s\n", map_cache_file);
-	if(!(map_cache_fp = fopen(map_cache_file, "wb"))) {
+	map_cache_fp = fopen(map_cache_file, "wb");
+	if( map_cache_fp == NULL ) {
 		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"))) {
+	list = fopen(map_list_file, "r");
+	if( list == NULL ) {
 		printf("Failure when opening maps list file %s\n", map_list_file);
 		exit(1);
 	}