Loading .DEF files (hch/CDefHandler.cpp)

Hello! New here.

I’m working on my own little HoMM3-library (written in haskell). I’m looking at your code for documentation, especially the CDefHandler.h/CDefHandler.cpp and also here:
wiki.enleth.com/homm:homm3-def-animations
But I’m kind of stuck here. I’ve managed to parse all the way up until where the actual data begins, so i have what you call a
struct SSpriteDef
but here i run into trouble. If someone could please explain what happends in the switch-block on line 200 that would be of great help :wink:

Hi!

In short, there are 4 types of def file compression, each case of that switch corresponds to one of them. We just fill there ret, an SDL_Surface, with pixels obtained from FDef. FDef is just the loaded def file, ret->pixels has pixels ordered line by line, starting from left top corner. I could explain more if you were more specific about your problems.

First of all i don’t understand how long to “go on” for. You assign to prSize but never use it.
Also: what is ftcp? It’s initialized with

	int ftcp=0;

and used like this:

	if (TopMargin > 0)
		ftcp += TopMargin*(FullWidth+add);

	switch(defType2)
	{
	case 0:
	{
		for (unsigned int i=0;i<SpriteHeight;i++)
		{
			if (LeftMargin>0)
				ftcp += LeftMargin;

			memcpy(reinterpret_cast<char*>(ret->pixels)+ftcp, 
                                &FDef[BaseOffset], 
                                SpriteWidth);

			ftcp += SpriteWidth;
			BaseOffset += SpriteWidth;
			
			if (RightMargin>0)
				ftcp += RightMargin;
		}
	}

I don’t know what can be more explanatory than these for (do do…wile) loops with well-defined number of iterations and no gotos or breaks inside.

Therefore it’s probably not useful. We could remove it but I believe VCMI needs a lot of more important refactorings.

ftcp represents the number of the next pixel we need to write to the resultant surface. We should start with 0 and then, using memcpy, fill all pixels. Pixels are numbered according to SDL_Surface ordering (as described in my post above). I think ret->pixels must be initialized with zeros to make “ftcp jumps” (e.g. ftcp += RightMargin;) working correctly.

In code there are several cases where margins are supposed to be below zero.
At line 163-166:

if(LeftMargin<0)
	SpriteWidth+=LeftMargin;
if(RightMargin<0)
	SpriteWidth+=RightMargin;

Or more interesting at line 319-320:

int len = std::min<unsigned int>(value, SpriteWidth - TotalRowLength) - std::max(0, -LeftMargin);
amax(len, 0);

But I haven’t found any def files with negative borders. Does anyone knows such files?

I think there is such .def… but I don’t remember its name. You can always make a loop over all .defs, load them, write an if for negativeness of margin and put there a breakpoint…