Page 1 of 1

Can somebody explain this to me

Posted: 11 Jul 2008, 09:22
by lordango
First of all im just new to perl. I am trying to make map viewer. in C# but i need to understand some perl codes first.
I hope someone would be kind enough to help.

Code: Select all

		my $f;
		if (open($f, "<", $filename)) {
			binmode($f);
			local($/);
			$fieldData = <$f>;
			close($f);
		} else {
			IOException->throw("Cannot open $filename for reading.");
		}
	}

	($width, $height) = unpack("v v", substr($fieldData, 0, 4, ''));

Questions:
What is the $fieldData? i mean its data type...
Is it a file containing binary codes of the .fld map?

sub getBlock {
	my ($self, $x, $y) = @_;
	if ($x < 0 || $x >= $self->{width} || $y < 0 || $y >= $self->{height}) {
		return NON_WALKABLE;
	} else {
		return ord(substr($self->{rawMap}, ($y * $self->{width}) + $x, 1));
	}
}
What is rawmap here?



Finally, how to get the values 0-7 for the block type?

Thank you

Re: Can somebody explain this to me

Posted: 11 Jul 2008, 14:35
by sli
Find what calls getBlock and see what the first argument passed to it is. It will contain the rawmap data.

Re: Can somebody explain this to me

Posted: 12 Jul 2008, 02:42
by Motivus
C/C++ code from a mini project I made for myself not long ago.

Code: Select all

struct FLD
{
	unsigned short width;
	unsigned short height;

	unsigned char* block;
};

struct GAT
{
	unsigned char magic[6];     // 0
	unsigned short width;               // 6
	short garbageone;
	unsigned short height;              // 10
	short garbagetwo;
	struct GATblock* block; //14
};

struct GATblock 
{                 // Offset
	float ulHeight;        // 0
	float urHeight;       // 4
	float llHeight;        // 8
	float lrHeight;       // 12
	unsigned char type;           // 16
	unsigned char unknown[3];     // 17
};
Note that width/height are actually unsigned integer values, but I have them as unsigned short because RO maps don't get bigger than 400x400.

The following code is terrible and you shouldn't reuse it. At the same time it gives an idea of how to load structures from a file. You said you are using C# so you probably can't reuse it any way.

Code: Select all

bool GenFld(char* gatName, FLDtwo* fldReturn) 
{
	FLD fldInfo;

	char rswName[255];
	strcpy(rswName, gatName);
	ChangeFileType((char*)rswName, ".rsw");

	unsigned int waterDepth;
	waterDepth=GetWaterDepth((char*)rswName);

	FILE* gat=fopen(gatName, "r");

	if (!gat)
		return 0;

	GAT gatInfo;
	fread(&gatInfo, 14, 1, gat);

	unsigned int maxIndex=gatInfo.height*gatInfo.width;

	GATblock* blocks=(GATblock*)malloc(sizeof(GATblock)*maxIndex+1);
	gatInfo.block=blocks;

	fread(blocks, sizeof(GATblock), maxIndex, gat);

	FILE* debug=fopen("debug.txt", "w+");
	fwrite(&gatInfo, sizeof(gatInfo), 1, debug);
	fclose(debug);

	fclose(gat);

	fldInfo.height=gatInfo.height;
	fldInfo.width=gatInfo.width;
	fldInfo.block=(unsigned char*)malloc(sizeof(char)*maxIndex+1);


	for (unsigned int i=0; i<maxIndex; i++)
	{
		GATblock thisBlock=gatInfo.block[i];

		char type=0;

		type=thisBlock.type;

		unsigned short y=i/fldInfo.width;
		unsigned short x=i- (y*fldInfo.width);

		if (x == (fldInfo.width-1) || y == (fldInfo.height-1))
		{
			type=1;
		}
		else
		{
			unsigned int tileDepth=(unsigned int)(thisBlock.ulHeight + thisBlock.urHeight + thisBlock.llHeight + thisBlock.lrHeight) >> 2;

			if (tileDepth > waterDepth) //Below ater level
			{
				if (type == 0 || type == 3) 
				{
					type=3; //Walkable water
				}
				else if (type == 1 || type == 6)
				{
					type=2; //Non-walkable water
				}
				else if (type == 5)
				{
					type=4;
				}
				else
				{
					type=7;
				}
			}
		}

		fldInfo.block[i]=type;
	}

	char fldName[255];
	strcpy(fldName, gatName);
	ChangeFileType((char*)fldName, ".fld");
	SaveFld((char*)fldName, &fldInfo);

	return 1;
}

bool LoadFld(char* fldName, FLDtwo* fldReturn)
{
	FLD fldInfo;

	FILE* fld=fopen(fldName, "r");

	if (!fld)
		return 0;

	fread((void*)&fldInfo, 4, 1, fld);

	unsigned int maxIndex=fldInfo.height*fldInfo.width;

	unsigned char* blocks=(unsigned char*)malloc(sizeof(char)*maxIndex+1);
	fldInfo.block=blocks;

	fread(blocks, sizeof(char), maxIndex, fld);

	//Fix edge tiles, OpenKore fld marks them as walkable because the gat does - oh hell no
	for (unsigned int i=0; i<maxIndex; i++)
	{
		unsigned short y=i/fldInfo.width;
		unsigned short x=i- (y*fldInfo.width);

		if (x == (fldInfo.width-1) || y == (fldInfo.height-1))
		{
			fldInfo.block[i]=1;
		}
	}

	fclose(fld);
	return 1;
}

unsigned int GetWaterDepth(char* rswName)
{
	FILE* rsw=fopen(rswName, "r");

	if (!rsw)
		return 0;

	char buffer[255];
	unsigned int depth;
	fread(buffer, 1, 166, rsw);
	fread(&depth, 4, 1, rsw);

	fclose(rsw);

	return depth;
}