User:Viader

From VCMI Project Wiki
Jump to: navigation, search

Najpierw pozbierajmy informacje znalezione w internecie :)


Text formats

Format TXT

http://en.wikipedia.org/wiki/Text_file

TXT's use language-specific encoding: - Win-1250/Win-1251/Win-1252/...

Format JSON

http://en.wikipedia.org/wiki/Json


Image formats

Format BMP

http://en.wikipedia.org/wiki/BMP_file_format

Format JPG

https://en.wikipedia.org/wiki/JPEG

Format PNG

http://en.wikipedia.org/wiki/Portable_Network_Graphics

Format TGA

https://en.wikipedia.org/wiki/Truevision_TGA

Format PCX

struct h3pcx_color_indexed {
	uint8_t r;
	uint8_t g;
	uint8_t b;
};
 
struct h3pcx_indexed {
	uint32_t bitmap_size; // equals to width*height - 1 byte per pixel
	uint32_t width;
	uint32_t height;
	uint8_t bitmap[width*height];
	h3pcx_color_indexed palette[256];
};
 
struct h3pcx_color_bgr {
	uint8_t b;
	uint8_t g;
	uint8_t r;
};
 
struct h3pcx_bgr {
	uint32_t bitmap_size; // equals to 3*width*height - 3 bytes per pixel
	uint32_t width;
	uint32_t height;
	h3pcx_color_bgr bitmap[width*height];
};

Source: http://wiki.enleth.com/homm:homm3-pcx-graphics


Animation formats

Format DEF

struct h3def_color_indexed {
	uint8_t r;
	uint8_t g;
	uint8_t b;
};
 
struct h3def_header {
	uint32_t type;
	uint32_t width;
	uint32_t height;
	uint32_t sequences_count;
	h3def_color_indexed palette[256];
};

struct h3def_sequence {
        uint32_t type;
        uint32_t length;
        uint32_t unknown1;
        uint32_t unknown2;
        char *names[length];
        uint32_t offsets[length];
};

struct h3def_frame_header {
        uint32_t data_size;
        uint32_t type;
        uint32_t width;
        uint32_t height;
        uint32_t img_width;
        uint32_t img_height;
        uint32_t x;
        uint32_t y;
};

Source: http://wiki.enleth.com/homm:homm3-def-animations


Music formats

Format MP3

http://en.wikipedia.org/wiki/MP3

Format OGG

https://en.wikipedia.org/wiki/Ogg

Format 82M

Renamed WAVE format https://ccrma.stanford.edu/courses/422/projects/WaveFormat/


Video formats

Format AVI

http://en.wikipedia.org/wiki/Audio_Video_Interleave

Format SMK

http://en.wikipedia.org/wiki/Smacker_video

Format BIK

http://en.wikipedia.org/wiki/Bink_Video

Format MJPG //better link needed

http://www.digitalpreservation.gov/formats/fdd/fdd000063.shtml#notes

Format MPG

http://pl.wikipedia.org/wiki/Moving_Picture_Experts_Group


Palette formats

FORMAT PAL

http://worms2d.info/Palette_file


Archive formats

Format LOD and PAC

struct h3lod {
	uint32_t magic; // always 0x00444f4c, that is, a null-terminated "LOD" string
	uint32_t type; // 200 for base archives, 500 for expansion pack archives, probably completely arbitrary numbers
	uint32_t files_count; // obvious
	uint8_t unknown[80]; // 80 bytes of hell knows what - in most cases that's all zeros, but in H3sprite.lod there's a bunch of seemingly irrelevant numbers here, any information is welcome
	struct h3lod_file[10000]; // file list
}
 
struct h3lod_file {
	char name[16]; // null-terminated, sometimes null-padded too, sometimes padded with, well, something after the null
	uint32_t offset; // includes the header size, no preprocessing required
	uint32_t size_original; // before compression, that is
	uint32_t type; // what's in the file - probably not used by the game directly, more on that below
	uint32_t size_compressed; // how many bytes to read, starting from offset - can be zero for stored files, use size_original in such case 
}

Source: http://wiki.enleth.com/homm:homm3-lod-archives

Format VID

struct h3vid {
	uint32_t files_count;
	struct h3vid_file[files_count]
}
 
struct h3vid_file {
	char name[40];
	uint32_t offset;
}

Note: Archive VID doesn't contain information about file's size. For h3vid_file[x]:

Size = h3vid_file[x+1].offset - h3vid_file[x].offset.

If we read last file in archive:

Size = archive_size - h3vid_file[x].offset.


Format SND

struct h3snd {
	uint32 files_count;
	struct h3vid_file[files_count]
}
 
struct h3snd_file {
	char name[40];
	uint32 offset;
	uint32 size;
}

Note: For some reason entries in snd have format NAME(null)WAVRUBBISH....


Font formats

Format TTF

http://en.wikipedia.org/wiki/TrueType

Format FNT

Bitmap font, specific for Heroes3. Describe soon...


Mask formats

Format MSK

Describe soon...

Format MSG

Describe soon...


Map formats

Format H3M

Source:

struct h3map{
	    h3map_header;
	    h3map_disposedHeroes;
	    h3map_allowedArtifacts;
	    h3map_allowedSpells;
	    h3map_allowedAbilities;
	    h3map_rumors;
	    h3map_predefinedHeroes;
	    h3map_terrain;
	    h3map_defs;
	    h3map_objects;
	    h3map_events;
}

struct string{
	uint32 count;
	char data[count];
}

struct h3map_header{
	uint32			version;
	uint8			areAnyPlayers;
	uint32			width/height;
	uint8			twoLevel;
	string 			name;
	string			describe;
	char			difficulty;
	
	if(version != ROE)
	{
		uint8 		levelLimit;
	}
	
	playerInfo 		playerInfo[8];
	uint8			victoryConditions;
	uint8			lossConditions;
	uint8			teamCount;
	
	uint8 			player[0].team;
	uint8 			player[1].team;
	uint8 			player[2].team;
	uint8			player[3].team;
	uint8 			player[4].team;
	uint8 			player[5].team;
	uint8 			player[6].team;
	uint8 			player[7].team;
	
	if(version = ROE)
	{
		uint8 		allowedHeroes[16]
	}
	else
	{
		uint8 		allowedHeroes[20]
	}	
	
	if(version > ROE)
	{
		uint32 		placeholdersQty //unknown_1
	}
}

struct h3map_disposedHeroes{

	if(version >= SOD)
	{
		uint8 	        disposedHeroesCount;
		disposedHeroes 	disposedHeroes[disposedHeroesCount]
	}
	
	char nulls[31];
}

struct h3map_allowedArtifacts{

	if(version != ROE)
	{
		if(version = AB)
		{
			bool artifactsBits[17];
		}
		else
		{
			bool artifactsBits[18];
		}
	}
}

struct h3map_allowedSpells{

	if(version >= SOD)
	{
		bool spellBits[9];
	}
}


struct h3map_allowedAbilities{

	if(version >= SOD)
	{
		bool abilitiesBits[4];
	}
}

struct h3map_rumors{

	uint32 rumorsCount;
	rumor rumors[rumorsCount];
}

struct h3map_predefinedHeroes{
	if(version = SOD || version = WOG)
	{
		predefinedHeroes predefinedHeroes[156];
	}
}


struct playerInfo{
	uint8 			canHumanPlay;
	uint8			canComputerPlay;
	uint8			computer_tactic;
	uint8			aiTactic;
	
	if(version == SOD || version == WOG)
	{
		uint8		p7; //unknown_2
	}
	
	bool			allowedFactions[32];
	uint8			isFactionRandom;
	uint8			hasMainTown;
	
	if(hasMainTown == 1)
	{
		if(version != ROE)
		{
			uint8	generateHeroAtMainTown;
			uint8	generateHeroAtMainTown;
		}
		
		uint8		posOfMainTown_x;
		uint8		posOfMainTown_y;
		uint8		posOfMainTown_z;
	}
	
	uint8 			hasHero;
	uint8 			customHeroID;
	
	if(customHeroID != 0xff)
	{
		uint8		mainHeroPortrait;
		string		mainHeroName;
	}
	
	if(version != ROE)
	{
		uint8 		powerPlaceholders	//unknown_3
		uint8 		heroCount;
		uint8		unknow_4;			//unknown_4
		uint8 		unknow_5;			//unknown_5
		uint8 		unknow_6;			//unknown_6
		heroesNames	heroesNames[heroCount];
	}
}

struct heroesNames{
	uint8 			heroId;
	string 			heroName;
}

struct disposedHeroes{
	uint8			heroId;
	uint8			portrait;
	string			name;
	bool			player[8];
}

struct rumor{
	string name;
	string text;
}

struct PredefinedHeroes{

	uint8	custom;
	if(custom != 0)
	{
		uint8	hasExp;
		
		if(hasExp)
		{
		        uint32 	Exp
		}
		uint8	hasSecSkills;
		
		if(hasSecSkills)
		{
			uint32	        SecSkillsCount;
			secondarySkill	SecondarySkill[SecSkillsCount];
		}
		uint8	hasArt;
		
		if(hasArt)
		{
			if(version == ROE)
			{
				uint8	ArtifactToSlot[19];
			}
			
			if(version > ROE)
			{
				uint16	ArtifactToSlot[19];
			}			
			
			uint16 backpack_amount;

			if(version == ROE)
			{
				uint8	ArtifactToBackpack[backpack_amount];
			}
			
			if(version > ROE)
			{
				uint16	ArtifactToBackpack[backpack_amount];
			}
		}		
		
		uint8	hasCustomBio;
		if(hasCustomBio)
		{
			string	biography;
		}
		uint8	sex;
		uint8	hasCustomSpells;
		if(hasCustomSpells)
		{
			uint8 spells[9];
		}
		uint8 hasCustomPrimSkills;
		if(hasCustomPrimSkills)
		uint8 PrimarySkill;
	}
}

struct Hero{

	if(version > ROE)
	{
		uint32	identifier;
	}
	uint8	PlayerColor;
	uint8	subID;
	
	uint8	hasName;
	if(hasName)
	{
		string name;
	}
	
	if(version > AB)
	{
		uint8 hasExp;
		if(hasExp)
		{
			uint32 Exp;
		}
	}
	else
	{
		uint32 Exp;
	}
	
	uint8 hasPortrait;
	if(hasPortrait)
	{
		uint8 portrait;
	}
	
	uint8 hasSecSkills;
	if(hasSecSkills)
	{
		uint32			SecSkillsCount;
		secondarySkill	SecondarySkill[SecSkillsCount];
	}
	
	uint8 hasGarison;
	if(hasGarison)
	{
		creature army[7];
	}
	
	uint8 formation;
	
	uint8 hasArt;
	if(hasArt)
	{
		if(version == ROE)
		{
			uint8			ArtifactToSlot[19];
		}
		
		if(version > ROE)
		{
			uint16			ArtifactToSlot[19];
		}			
		
		uint16 backpack_amount;
		if(version == ROE)
		{
			uint8			ArtifactToBackpack[backpack_amount];
		}
		
		if(version > ROE)
		{
			uint16			ArtifactToBackpack[backpack_amount];
		}
	}

	uint8	patrolRadious; //if(patrolRadious == 0xff then patrolRadious = false, else patrolRadious = true)
	
		
	uint8	hasCustomBio;
	if(hasCustomBio)
	{
		string	biography;
	}
	uint8	sex;
	
	if(version > AB)
	{
		uint8	hasCustomSpells;
		if(hasCustomSpells)
		{
			uint8 spells[9];
		}
	}
	else if(version == AB)
	{
		uint8 spells[1];
	}
	
	uint8 hasCustomPrimSkills;
	if(hasCustomPrimSkills)
	{
		uint8 PrimarySkill[GameConstants::PRIMARY_SKILLS];
	}
	uint8 unknown[16];
}

struct secondarySkill{
	uint8 Skill;
	uint8 level;
}

struct h3map_terrain{
	terrain world_tileset[width][height];
	if(TwoLevel)
	{
		terrain second_world_tileset[width][height];
	}
}

struct creature{

	if(version > ROE)
	{
		uint16 ID;
	}
	else
	{
		uint8 ID;
	}
	
	uint16 count;
}

struct terrain{
	uint8 Type;
	uint8 View;
	uint8 riverType;
	uint8 riverDir;
	uint8 roadType;
	uint8 roadDir;
	uint8 extTileFlags;
}

struct h3map_def{
	uint32 defAmount;
	def def[defAmount]
}

struct def{
	string name;
	uint8 bytes[12];
	uint16 terrainAllowed;
	uint16 terrainMenu;
	uint32 id;
	uint32 subid;
	uint8 type;
	uint8 printPriority;
	uint16 unknown;
}

struct h3map_object{
	uint32 count;
	object object[count];
}

struct object{
	uint8 x;
	uint8 y;
	uint8 z;
	uint32 defnum;
	uint8 unknown[5];
		
	if(h3map_def.def[defnum].id == EVENT)
	{
		uint8 hasMessage;
		if(hasMessage)
		{
			string message;
		}
		uint8 hasGuards;
		if(hasGuards)
		{
			creature guards[7];
		}
		uint32 unknow;
		
		uint32 gainedExp;
		uint32 manaDiff;
		uint8 moraleDiff;
		uint8 luckDiff;
		uint32 resources[7];
		uint8 primskills[4];
		uint8 countSkill;
		secondarySkill skill[ count_gained_abilities];
		uint8 countArtifact;
		if(version == ROE)
		{
			uint8 ArtifactID[countArtifact];
		}
		else
		{
			uint16 ArtifactID[countArtifact];
		}
		uint8 countSpell;
		uint8 SpellID[countSpell];
		uint8 countCreature;
		creature creature[countCreature];
		uint8 unknown_1[8];
		uint8 availableFor;
		uint8 computerActivate;
		uint8 removeAfterVisit;
		uint32 unknown_2;
	}	
	
	if(h3map_def.def[defnum].id == HERO)
	{
		hero hero;
	}
	
	if(h3map_def.def[defnum].id == MONSTER)
	{
		if(version > ROE)
		{
			uint32 creID;
		}
		
		uint16 creCount;
		uint8 creCharacter;
		uint8 hasMessage;
		
		if(hasMessage)
		{
			string message;
			uint32 resources[7];
			
			if(version == ROE)
			{
				uint8 artID;
			}
			
			else
			{
				uint8 artID;
			}
		}
		uint8 creNeverFlees;
		uint8 creNotGrowingTeam;
		uint8 unknown_1[2];
	}
	
	if(h3map_def.def[defnum].id == BOOTLE)
	{
		string message;
		uint32 unknown_1;
	}

	if(h3map_def.def[defnum].id == SEER_HUT)
	{
		if(version > ROE)
		{
			quest quest;
			
			if(quest.missionType > 0)
			{
				uint8 rewardType;
				
				if(rewardType == EXPERIENCE || rewardType == MANA_POINTS)
				{
					uint32 value;
				}
				
				if(rewardType == MORALE_BONUS || rewardType == LUCK_BONUS || rewardType == SPELL)
				{
					uint8 value;
				}		

				if(rewardType == RESOURCES)
				{
					uint8 ID;
					uint32 value;
				}
				
				if(rewardType == PRIMARY_SKILL || rewardType == SECONDARY_SKILL)
				{
					uint8 ID;
					uint8 value;
				}

				if(rewardType == ARTIFACT)
				{
					if(version == ROE)
					{
						uint8 ID;
					}
					else
					{
						uint16 ID;
					}
				}
				
				if(rewardType == CREATURE)
				{
					if(version == ROE)
					{
						uint16 ID;
						uint16 value;
					}
					else
					{
						uint8 ID;
						uint16 value;
					}					
				}
			}
			uint8 unknown_1[2];
		}
		else
		{
			uint8 unknown_1[3];
		}
	}
	
	if(h3map_def.def[defnum].id == SCHOLAR)
	{
		uint8 bonusType;
		uint8 bonusID;
		uint8 unknown_1[6];
	}

	if(h3map_def.def[defnum].id == GARRISON)
	{
		uint8 playerColor;
		uint8 unknown_1[3];
		creature army[7];
		if(version > ROE)
		{
			uint8 removableUnits;
		}
		uint8 unknown_2[8];
	}

	if(h3map_def.def[defnum].id == ARTIFACT || h3map_def.def[defnum].id == SPELL_SCROLL)
	{		
		if(hasMessage)
		{
			string message;
		}
		uint8 hasGuards;
		if(hasGuards)
		{
			creature guards[7];
		}
		uint32 unknow;

		if(h3map_def.def[defnum].id == SPELL_SCROLL)
		{
			uint32 spellID;
		}		
	}
	
	if(h3map_def.def[defnum].id == RESOURCE)
	{		
		if(hasMessage)
		{
			string message;
		}
		uint8 hasGuards;
		if(hasGuards)
		{
			creature guards[7];
		}
		uint32 unknow;
		uint32 amount;
		uint32 unknow_1;
	}

	if(h3map_def.def[defnum].id == TOWN)
	{		
		if(hasMessage)
		{
			string message;
		}
		uint8 hasGuards;
		if(hasGuards)
		{
			creature guards[7];
		}
		
		uint32 unknow;
		uint32 amount;
		uint32 unknow_1;
	}

	if(h3map_def.def[defnum].id == MINE || h3map_def.def[defnum].id == CREATURE_GENERATOR)
	{		
		uint8 playerColor;
		uint8 unknown_1[3];
	}

	if(h3map_def.def[defnum].id == SHRINE_OF_MAGIC_THOUGHT)
	{		
		uint8 spellID;
		uint8 unknown_1[3];
	}

	if(h3map_def.def[defnum].id == PANDORAS_BOX)
	{		
		uint8 hasMessage;
		if(hasMessage)
		{
			string message;
		}
		uint8 hasGuards;
		if(hasGuards)
		{
			creature guards[7];
		}
		uint32 unknow;
		
		uint32 gainedExp;
		uint32 manaDiff;
		uint8 moraleDiff;
		uint8 luckDiff;
		uint32 resources[7];
		uint8 primskills[4];
		uint8 countSkill;
		secondarySkill skill[ count_gained_abilities];
		uint8 countArtifact;
		if(version == ROE)
		{
			uint8 ArtifactID[countArtifact];
		}
		else
		{
			uint16 ArtifactID[countArtifact];
		}
		uint8 countSpell;
		uint8 SpellID[countSpell];
		uint8 countCreature;
		creature creature[countCreature];
		uint8 unknown_1[8];
	}
	
	if(h3map_def.def[defnum].id == GRAIL)
	{
		uint32 grailRadious;
	}
	
	if(h3map_def.def[defnum].id == QUEST_GUARD || h3map_def.def[defnum].id == BORDERGUARD || h3map_def.def[defnum].id == BORDER_GATE)
	{
		quest quest;
	}	
	
	if(h3map_def.def[defnum].id == SHIPYARD || h3map_def.def[defnum].id == LIGHTHOUSE)
	{
		uint32 playercolor;
	}	

}

struct quest{
	uint8 missionType;
	if(missionType == 2)
	{
		uint8 m2stats[4];
	}

	if(missionType == 1 || missionType == 3 || missionType == 4)
	{
		uint32 m13489val;
	}

	if(missionType == 5)
	{
		uint8 artCount;
		uint16 artID[artCount];
	}
	
	if(missionType == 6)
	{
		uint8 typeCount;
		quest_creature quest_creature[typeCount];
	}
	
	if(missionType == 7)
	{
		uint32 m7resources[7]
	}
	
	if(missionType == 8 || missionType == 9)
	{
		uint8 m13489val;
	}	
	
	uint32 limit;
	string firstVisitText;
	string nextVisitText;
	string completedText;
}

struct quest_creature{
	uint16 type;
	uint16 count;
}

struct town{

	if(version > ROE)
	{
		uint32 ID;
	}
	uint8 playerColor;
	uint8 hasName;
	if(hasName)
	{
		string name;
	}
	uint8 hasGarrison;
	if(hasGarrison)
	{
		creature army[7];
	}
	uint8 formation;
	uint8 hasCustomBuildings;
	if(hasCustomBuildings)
	{
		uint8 builtBuildings[6];
		uint8 forbiddenBuildings[6];
	}
	else
	{
		uint8 hasFort;
	}
	
	if(version > ROE)
	{
		uint8 obligatorySpells[9];
	}
	uint8 possibleSpells;
	uint8 eventCount;
	castleEvent castleEvent[eventCount];
	
	if(version > AB)
	{
		uint8 alignment;
	}
	uint8 unknown[3];
}

struct h3map_event{
	uint32 count;
	event event[count];
}

struct event{
	string name;
	string message;
	uint32 resources[7];
	uint8 players;
	if(version > AB)
	{
		uint8 humanAffected;
	}
	uint8 computerAffected;
	uint16 firstOccurence;
	uint8 nextOccurence;
	uint8 unknow[17];
}

struct castleEvent{
	event event;
	uint8 buildings[6];
	uint16 creaturesBonus[7];
	uint32 unknown;
}

http://corexii.com/h3m_description.english.txt (uncomplete)

http://svn.code.sf.net/p/vcmi/code/tags/0.8/h3m.txt (complete - Polish)

Campaigns formats

Describe soon...