User:Viader
Najpierw pozbierajmy informacje znalezione w internecie :)
Contents
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...