Is there a complete repository of information regarding file formats that StarCraft uses? I only found a
page on ShadowFlare's website, but it doesn't seem very complete. I suggest that we have a sticky topic that will contain this information too.
None.
I dunno if it's still around, but the modcrafters wiki had a bunch.
Or if you are looking for any particular file(s) I could probably help.
Post has been edited 1 time(s), last time on May 23 2016, 8:16 am by FaRTy1billion.
TinyMap2 - Latest in map compression! ( 7/09/14 - New build! )
EUD Action Enabler - Lightweight EUD/EPD support! (ChaosLauncher/MPQDraft support!)
EUDDB -
topic - Help out by adding your EUDs! Or Submit reference files in the References tab!
MapSketch - New image->map generator!
EUDTrig -
topic - Quickly and easily convert offsets to EUDs! (extended players supported)
SC2 Map Texture Mask Importer/Exporter - Edit texture placement in an image editor!
This page has been viewed [img]http://farty1billion.dyndns.org/Clicky.php?img.gif[/img] times!
I miss the modcrafters wiki... here's what I have, some of my formats may be inconvenient as I didn't like the way blizzard layed out the dat files and had them parsed instead.
CV5
From a tile value in MTXM...
offsetToCV5Entry = group*52 + tile*2 + 0x14
where: group = TileValue / 16 = high 12 bits
tile = TileValue & 0xF = low 4 bits
class CV5Entry
{
public:
u16 index;
u8 buildability;
u8 groundHeight;
u16 leftEdge;
u16 topEdge;
u16 rightEdge;
u16 bottomEdge;
u16 Unknown1;
u16 Unknown2;
u16 Unknown3;
u16 Unknown4;
u16 megaTileRef[16]; // To VF4/VX4
};
VF4 and VR4
VF4 and VR4 define mega tile data for a given tileset (I don't have the structs), and have indexes to mini tiles
VX4
VX4 defines mini tile data for a given tileset (I don't have the structs), and have indexes to the current palette
WPE
WPE is the initial palette for a given tileset, once loaded this palette is altered by various means for color cycling/sprite rendering/etc.
Upgrades.dat
Rather than like the following struct, upgrades.dat is layed out in arrays consisting of each member (see below for loading code, or make your own struct for the entire file if you wish).
struct UPGRADEDAT
{
u16 MineralCost;
u16 MineralFactor;
u16 VespeneCost;
u16 VespeneFactor;
u16 TimeCost;
u16 TimeFactor;
u16 Unknown;
u16 Icon;
u16 Label;
u8 Race;
u8 MaxRepeats;
u8 BroodWarSpecific;
};
u32 pos, i, numUpgrades = 46;
bool isExpansion = (upgradeDat.size() == 1281);
if ( isExpansion )
numUpgrades = 61;
if ( isExpansion )
{
pos = 0x000; for ( i=0; i<numUpgrades; i++ ) upgrade[i].MineralCost = upgradeDat.get<u16>(pos+2*i);
pos = 0x07A; for ( i=0; i<numUpgrades; i++ ) upgrade[i].MineralFactor = upgradeDat.get<u16>(pos+2*i);
pos = 0x0F4; for ( i=0; i<numUpgrades; i++ ) upgrade[i].VespeneCost = upgradeDat.get<u16>(pos+2*i);
pos = 0x16E; for ( i=0; i<numUpgrades; i++ ) upgrade[i].VespeneFactor = upgradeDat.get<u16>(pos+2*i);
pos = 0x1E8; for ( i=0; i<numUpgrades; i++ ) upgrade[i].TimeCost = upgradeDat.get<u16>(pos+2*i);
pos = 0x262; for ( i=0; i<numUpgrades; i++ ) upgrade[i].TimeFactor = upgradeDat.get<u16>(pos+2*i);
pos = 0x2DC; for ( i=0; i<numUpgrades; i++ ) upgrade[i].Unknown = upgradeDat.get<u16>(pos+2*i);
pos = 0x356; for ( i=0; i<numUpgrades; i++ ) upgrade[i].Icon = upgradeDat.get<u16>(pos+2*i);
pos = 0x3D0; for ( i=0; i<numUpgrades; i++ ) upgrade[i].Label = upgradeDat.get<u16>(pos+2*i);
pos = 0x44A; for ( i=0; i<numUpgrades; i++ ) upgrade[i].Race = upgradeDat.get< u8>(pos+ i);
pos = 0x487; for ( i=0; i<numUpgrades; i++ ) upgrade[i].MaxRepeats = upgradeDat.get< u8>(pos+ i);
pos = 0x4C4; for ( i=0; i<numUpgrades; i++ ) upgrade[i].BroodWarSpecific = upgradeDat.get< u8>(pos+ i);
}
else // Original
{
pos = 0x000; for ( i=0; i<numUpgrades; i++ ) upgrade[i].MineralCost = upgradeDat.get<u16>(pos+2*i);
pos = 0x05C; for ( i=0; i<numUpgrades; i++ ) upgrade[i].MineralFactor = upgradeDat.get<u16>(pos+2*i);
pos = 0x0B8; for ( i=0; i<numUpgrades; i++ ) upgrade[i].VespeneCost = upgradeDat.get<u16>(pos+2*i);
pos = 0x114; for ( i=0; i<numUpgrades; i++ ) upgrade[i].VespeneFactor = upgradeDat.get<u16>(pos+2*i);
pos = 0x170; for ( i=0; i<numUpgrades; i++ ) upgrade[i].TimeCost = upgradeDat.get<u16>(pos+2*i);
pos = 0x1CC; for ( i=0; i<numUpgrades; i++ ) upgrade[i].TimeFactor = upgradeDat.get<u16>(pos+2*i);
pos = 0x228; for ( i=0; i<numUpgrades; i++ ) upgrade[i].Unknown = upgradeDat.get<u16>(pos+2*i);
pos = 0x284; for ( i=0; i<numUpgrades; i++ ) upgrade[i].Icon = upgradeDat.get<u16>(pos+2*i);
pos = 0x2E0; for ( i=0; i<numUpgrades; i++ ) upgrade[i].Label = upgradeDat.get<u16>(pos+2*i);
pos = 0x33C; for ( i=0; i<numUpgrades; i++ ) upgrade[i].Race = upgradeDat.get< u8>(pos+ i);
pos = 0x36A; for ( i=0; i<numUpgrades; i++ ) upgrade[i].MaxRepeats = upgradeDat.get< u8>(pos+ i);
}
techdata.dat
Rather than like the following struct, techdata.dat is layed out in arrays consisting of each member (see below for loading code, or make your own struct for the entire file if you wish).
struct TECHDAT
{
u16 MineralCost;
u16 VespeneCost;
u16 ResearchTime;
u16 EnergyCost;
u32 Unknown;
u16 Icon;
u16 Label;
u8 Race;
u8 Unused;
u8 BroodWar;
};
u32 pos, i, numTechs = 24;
bool isExpansion = (techDat.size() == 836);
if ( isExpansion )
numTechs = 44;
if ( isExpansion )
{
pos = 0x000; for ( i=0; i<numTechs; i++ ) tech[i].MineralCost = techDat.get<u16>(pos+2*i);
pos = 0x058; for ( i=0; i<numTechs; i++ ) tech[i].VespeneCost = techDat.get<u16>(pos+2*i);
pos = 0x0B0; for ( i=0; i<numTechs; i++ ) tech[i].ResearchTime = techDat.get<u16>(pos+2*i);
pos = 0x108; for ( i=0; i<numTechs; i++ ) tech[i].EnergyCost = techDat.get<u16>(pos+2*i);
pos = 0x160; for ( i=0; i<numTechs; i++ ) tech[i].Unknown = techDat.get<u32>(pos+4*i);
pos = 0x210; for ( i=0; i<numTechs; i++ ) tech[i].Icon = techDat.get<u16>(pos+2*i);
pos = 0x268; for ( i=0; i<numTechs; i++ ) tech[i].Label = techDat.get<u16>(pos+2*i);
pos = 0x2C0; for ( i=0; i<numTechs; i++ ) tech[i].Race = techDat.get< u8>(pos+ i);
pos = 0x2EC; for ( i=0; i<numTechs; i++ ) tech[i].Unused = techDat.get< u8>(pos+ i);
pos = 0x318; for ( i=0; i<numTechs; i++ ) tech[i].BroodWar = techDat.get< u8>(pos+ i);
}
else // Original
{
pos = 0x000; for ( i=0; i<numTechs; i++ ) tech[i].MineralCost = techDat.get<u16>(pos+2*i);
pos = 0x030; for ( i=0; i<numTechs; i++ ) tech[i].VespeneCost = techDat.get<u16>(pos+2*i);
pos = 0x060; for ( i=0; i<numTechs; i++ ) tech[i].ResearchTime = techDat.get<u16>(pos+2*i);
pos = 0x090; for ( i=0; i<numTechs; i++ ) tech[i].EnergyCost = techDat.get<u16>(pos+2*i);
pos = 0x0C0; for ( i=0; i<numTechs; i++ ) tech[i].Unknown = techDat.get<u32>(pos+4*i);
pos = 0x120; for ( i=0; i<numTechs; i++ ) tech[i].Icon = techDat.get<u16>(pos+2*i);
pos = 0x150; for ( i=0; i<numTechs; i++ ) tech[i].Label = techDat.get<u16>(pos+2*i);
pos = 0x180; for ( i=0; i<numTechs; i++ ) tech[i].Race = techDat.get< u8>(pos+ i);
pos = 0x198; for ( i=0; i<numTechs; i++ ) tech[i].Unused = techDat.get< u8>(pos+ i);
}
units.dat
Rather than like the following struct, units.dat is layed out in arrays consisting of each member (see below for loading code, or make your own struct for the entire file if you wish).
struct UNITDAT
{
u8 Graphics;
u16 Subunit1;
u16 Subunit2;
u16 Infestation; // ID 106-201 only
u32 ConstructionAnimation;
u8 UnitDirection;
u8 ShieldEnable;
u16 ShieldAmount;
u32 HitPoints;
u8 ElevationLevel;
u8 Unknown;
u8 Sublabel;
u8 CompAIIdle;
u8 HumanAIIdle;
u8 ReturntoIdle;
u8 AttackUnit;
u8 AttackMove;
u8 GroundWeapon;
u8 MaxGroundHits;
u8 AirWeapon;
u8 MaxAirHits;
u8 AIInternal;
u32 SpecialAbilityFlags;
u8 TargetAcquisitionRange;
u8 SightRange;
u8 ArmorUpgrade;
u8 UnitSize;
u8 Armor;
u8 RightClickAction;
u16 ReadySound; // ID 0-105 only
u16 WhatSoundStart;
u16 WhatSoundEnd;
u16 PissSoundStart; // ID 0-105 only
u16 PissSoundEnd; // ID 0-105 only
u16 YesSoundStart; // ID 0-105 only
u16 YesSoundEnd; // ID 0-105 only
u16 StarEditPlacementBoxWidth;
u16 StarEditPlacementBoxHeight;
u16 AddonHorizontal; // ID 106-201 only
u16 AddonVertical; // ID 106-201 only
u16 UnitSizeLeft;
u16 UnitSizeUp;
u16 UnitSizeRight;
u16 UnitSizeDown;
u16 Portrait;
u16 MineralCost;
u16 VespeneCost;
u16 BuildTime;
u16 Unknown1;
u8 StarEditGroupFlags;
u8 SupplyProvided;
u8 SupplyRequired;
u8 SpaceRequired;
u8 SpaceProvided;
u16 BuildScore;
u16 DestroyScore;
u16 UnitMapString;
u8 BroodwarUnitFlag;
u16 StarEditAvailabilityFlags;
};
u32 pos, i;
pos = 0x0000; for ( i= 0; i<228; i++ ) unit[i].Graphics = unitDat.get<u8>(pos+i);
pos = 0x00E4; for ( i= 0; i<228; i++ ) unit[i].Subunit1 = unitDat.get<u16>(pos+i*2);
pos = 0x02AC; for ( i= 0; i<228; i++ ) unit[i].Subunit2 = unitDat.get<u16>(pos+i*2);
pos = 0x0474; for ( i=106; i<202; i++ ) unit[i].Infestation = unitDat.get<u16>(pos+i*2);
pos = 0x0534; for ( i= 0; i<228; i++ ) unit[i].ConstructionAnimation = unitDat.get<u32>(pos+i*4);
pos = 0x08C4; for ( i= 0; i<228; i++ ) unit[i].UnitDirection = unitDat.get<u8>(pos+i);
pos = 0x09A8; for ( i= 0; i<228; i++ ) unit[i].ShieldEnable = unitDat.get<u8>(pos+i);
pos = 0x0A8C; for ( i= 0; i<228; i++ ) unit[i].ShieldAmount = unitDat.get<u16>(pos+i*2);
pos = 0x0C54; for ( i= 0; i<228; i++ ) unit[i].HitPoints = unitDat.get<u32>(pos+i*4);
pos = 0x0FE4; for ( i= 0; i<228; i++ ) unit[i].ElevationLevel = unitDat.get<u8>(pos+i);
pos = 0x10C8; for ( i= 0; i<228; i++ ) unit[i].Unknown = unitDat.get<u8>(pos+i);
pos = 0x11AC; for ( i= 0; i<228; i++ ) unit[i].Sublabel = unitDat.get<u8>(pos+i);
pos = 0x1290; for ( i= 0; i<228; i++ ) unit[i].CompAIIdle = unitDat.get<u8>(pos+i);
pos = 0x1374; for ( i= 0; i<228; i++ ) unit[i].HumanAIIdle = unitDat.get<u8>(pos+i);
pos = 0x1458; for ( i= 0; i<228; i++ ) unit[i].ReturntoIdle = unitDat.get<u8>(pos+i);
pos = 0x153C; for ( i= 0; i<228; i++ ) unit[i].AttackUnit = unitDat.get<u8>(pos+i);
pos = 0x1620; for ( i= 0; i<228; i++ ) unit[i].AttackMove = unitDat.get<u8>(pos+i);
pos = 0x1704; for ( i= 0; i<228; i++ ) unit[i].GroundWeapon = unitDat.get<u8>(pos+i);
pos = 0x17E8; for ( i= 0; i<228; i++ ) unit[i].MaxGroundHits = unitDat.get<u8>(pos+i);
pos = 0x18CC; for ( i= 0; i<228; i++ ) unit[i].AirWeapon = unitDat.get<u8>(pos+i);
pos = 0x19B0; for ( i= 0; i<228; i++ ) unit[i].MaxAirHits = unitDat.get<u8>(pos+i);
pos = 0x1A94; for ( i= 0; i<228; i++ ) unit[i].AIInternal = unitDat.get<u8>(pos+i);
pos = 0x1B78; for ( i= 0; i<228; i++ ) unit[i].SpecialAbilityFlags = unitDat.get<u32>(pos+i*4);
pos = 0x1F08; for ( i= 0; i<228; i++ ) unit[i].TargetAcquisitionRange = unitDat.get<u8>(pos+i);
pos = 0x1FEC; for ( i= 0; i<228; i++ ) unit[i].SightRange = unitDat.get<u8>(pos+i);
pos = 0x20D0; for ( i= 0; i<228; i++ ) unit[i].ArmorUpgrade = unitDat.get<u8>(pos+i);
pos = 0x21B4; for ( i= 0; i<228; i++ ) unit[i].UnitSize = unitDat.get<u8>(pos+i);
pos = 0x2298; for ( i= 0; i<228; i++ ) unit[i].Armor = unitDat.get<u8>(pos+i);
pos = 0x237C; for ( i= 0; i<228; i++ ) unit[i].RightClickAction = unitDat.get<u8>(pos+i);
pos = 0x2460; for ( i= 0; i<106; i++ ) unit[i].ReadySound = unitDat.get<u16>(pos+i*2);
pos = 0x2534; for ( i= 0; i<228; i++ ) unit[i].WhatSoundStart = unitDat.get<u16>(pos+i*2);
pos = 0x26FC; for ( i= 0; i<228; i++ ) unit[i].WhatSoundEnd = unitDat.get<u16>(pos+i*2);
pos = 0x28C4; for ( i= 0; i<106; i++ ) unit[i].PissSoundStart = unitDat.get<u16>(pos+i*2);
pos = 0x2998; for ( i= 0; i<106; i++ ) unit[i].PissSoundEnd = unitDat.get<u16>(pos+i*2);
pos = 0x2A6C; for ( i= 0; i<106; i++ ) unit[i].YesSoundStart = unitDat.get<u16>(pos+i*2);
pos = 0x2B40; for ( i= 0; i<106; i++ ) unit[i].YesSoundEnd = unitDat.get<u16>(pos+i*2);
pos = 0x2C14;
for ( i= 0; i<228; i++ )
{
unit[i].StarEditPlacementBoxWidth = unitDat.get<u16>(pos+i*4);
unit[i].StarEditPlacementBoxHeight = unitDat.get<u16>(pos+i*4+2);
}
pos = 0x2FA4; for ( i=106; i<202; i++ ) unit[i].AddonHorizontal = unitDat.get<u16>(pos+(i-106)*2);
pos = 0x3064; for ( i=106; i<202; i++ ) unit[i].AddonVertical = unitDat.get<u16>(pos+(i-106)*2);
pos = 0x3124;
for ( i= 0; i<228; i++ )
{
unit[i].UnitSizeLeft = unitDat.get<u16>(pos+i*8);
unit[i].UnitSizeUp = unitDat.get<u16>(pos+i*8+2);
unit[i].UnitSizeRight = unitDat.get<u16>(pos+i*8+4);
unit[i].UnitSizeDown = unitDat.get<u16>(pos+i*8+6);
}
pos = 0x3844; for ( i= 0; i<228; i++ ) unit[i].Portrait = unitDat.get<u16>(pos+i*2);
pos = 0x3A0C; for ( i= 0; i<228; i++ ) unit[i].MineralCost = unitDat.get<u16>(pos+i*2);
pos = 0x3BD4; for ( i= 0; i<228; i++ ) unit[i].VespeneCost = unitDat.get<u16>(pos+i*2);
pos = 0x3D9C; for ( i= 0; i<228; i++ ) unit[i].BuildTime = unitDat.get<u16>(pos+i*2);
pos = 0x3F64; for ( i= 0; i<228; i++ ) unit[i].Unknown1 = unitDat.get<u16>(pos+i*2);
pos = 0x412C; for ( i= 0; i<228; i++ ) unit[i].StarEditGroupFlags = unitDat.get<u8>(pos+i);
pos = 0x4210; for ( i= 0; i<228; i++ ) unit[i].SupplyProvided = unitDat.get<u8>(pos+i);
pos = 0x42F4; for ( i= 0; i<228; i++ ) unit[i].SupplyRequired = unitDat.get<u8>(pos+i);
pos = 0x43D8; for ( i= 0; i<228; i++ ) unit[i].SpaceRequired = unitDat.get<u8>(pos+i);
pos = 0x44BC; for ( i= 0; i<228; i++ ) unit[i].SpaceProvided = unitDat.get<u8>(pos+i);
pos = 0x45A0; for ( i= 0; i<228; i++ ) unit[i].BuildScore = unitDat.get<u16>(pos+i*2);
pos = 0x4768; for ( i= 0; i<228; i++ ) unit[i].DestroyScore = unitDat.get<u16>(pos+i*2);
pos = 0x4930; for ( i= 0; i<228; i++ ) unit[i].UnitMapString = unitDat.get<u16>(pos+i*2);
pos = 0x4AF8; for ( i= 0; i<228; i++ ) unit[i].BroodwarUnitFlag = unitDat.get<u8>(pos+i);
pos = 0x4BDC; for ( i= 0; i<228; i++ ) unit[i].StarEditAvailabilityFlags = unitDat.get<u16>(pos+i*2);
weapons.dat
Rather than like the following struct, weapons.dat is layed out in arrays consisting of each member (see below for loading code, or make your own struct for the entire file if you wish).
struct WEAPONDAT
{
u16 Label;
u32 Graphics;
u8 Unused;
u16 TargetFlags;
u32 MinimumRange;
u32 MaximumRange;
u8 DamageUpgrade;
u8 WeaponType;
u8 WeaponBehavior;
u8 RemoveAfter;
u8 WeaponEffect;
u16 InnerSplashRadius;
u16 MediumSplashRadius;
u16 OuterSplashRadius;
u16 DamageAmount;
u16 DamageBonus;
u8 WeaponCooldown;
u8 DamageFactor;
u8 AttackAngle;
u8 LaunchSpin;
u8 ForwardOffset;
u8 UpwardOffset;
u16 TargetErrorMessage;
u16 Icon;
};
u32 pos, i;
pos = 0x0000; for ( i=0; i<130; i++ ) weapons[i].Label = weaponDat.get<u16>(pos+i*2);
pos = 0x0104; for ( i=0; i<130; i++ ) weapons[i].Graphics = weaponDat.get<u32>(pos+i*4);
pos = 0x030C; for ( i=0; i<130; i++ ) weapons[i].Unused = weaponDat.get<u8 >(pos+i );
pos = 0x038E; for ( i=0; i<130; i++ ) weapons[i].TargetFlags = weaponDat.get<u16>(pos+i*2);
pos = 0x0492; for ( i=0; i<130; i++ ) weapons[i].MinimumRange = weaponDat.get<u32>(pos+i*4);
pos = 0x069A; for ( i=0; i<130; i++ ) weapons[i].MaximumRange = weaponDat.get<u32>(pos+i*4);
pos = 0x08A2; for ( i=0; i<130; i++ ) weapons[i].DamageUpgrade = weaponDat.get<u8 >(pos+i );
pos = 0x0924; for ( i=0; i<130; i++ ) weapons[i].WeaponType = weaponDat.get<u8 >(pos+i );
pos = 0x09A6; for ( i=0; i<130; i++ ) weapons[i].WeaponBehavior = weaponDat.get<u8 >(pos+i );
pos = 0x0A28; for ( i=0; i<130; i++ ) weapons[i].RemoveAfter = weaponDat.get<u8 >(pos+i );
pos = 0x0AAA; for ( i=0; i<130; i++ ) weapons[i].WeaponEffect = weaponDat.get<u8 >(pos+i );
pos = 0x0B2C; for ( i=0; i<130; i++ ) weapons[i].InnerSplashRadius = weaponDat.get<u16>(pos+i*2);
pos = 0x0C30; for ( i=0; i<130; i++ ) weapons[i].MediumSplashRadius = weaponDat.get<u16>(pos+i*2);
pos = 0x0D34; for ( i=0; i<130; i++ ) weapons[i].OuterSplashRadius = weaponDat.get<u16>(pos+i*2);
pos = 0x0E38; for ( i=0; i<130; i++ ) weapons[i].DamageAmount = weaponDat.get<u16>(pos+i*2);
pos = 0x0F3C; for ( i=0; i<130; i++ ) weapons[i].DamageBonus = weaponDat.get<u16>(pos+i*2);
pos = 0x1040; for ( i=0; i<130; i++ ) weapons[i].WeaponCooldown = weaponDat.get<u8 >(pos+i );
pos = 0x10C2; for ( i=0; i<130; i++ ) weapons[i].DamageFactor = weaponDat.get<u8 >(pos+i );
pos = 0x1144; for ( i=0; i<130; i++ ) weapons[i].AttackAngle = weaponDat.get<u8 >(pos+i );
pos = 0x11C6; for ( i=0; i<130; i++ ) weapons[i].LaunchSpin = weaponDat.get<u8 >(pos+i );
pos = 0x1248; for ( i=0; i<130; i++ ) weapons[i].ForwardOffset = weaponDat.get<u8 >(pos+i );
pos = 0x12CA; for ( i=0; i<130; i++ ) weapons[i].UpwardOffset = weaponDat.get<u8 >(pos+i );
pos = 0x134C; for ( i=0; i<130; i++ ) weapons[i].TargetErrorMessage = weaponDat.get<u16>(pos+i*2);
pos = 0x1450; for ( i=0; i<130; i++ ) weapons[i].Icon = weaponDat.get<u16>(pos+i*2);
flingy.dat
Rather than like the following struct, flingy.dat is layed out in arrays consisting of each member (see below for loading code, or make your own struct for the entire file if you wish).
struct FLINGYDAT
{
u16 Sprite;
u32 TopSpeed;
u16 Acceleration;
u32 HaltDistance;
u8 TurnRadius;
u8 Unused;
u8 MoveControl;
};
u32 pos, i;
pos = 0x000; for ( i=0; i<209; i++ ) flingy[i].Sprite = flingyDat.get<u16>(pos+i*2);
pos = 0x1A2; for ( i=0; i<209; i++ ) flingy[i].TopSpeed = flingyDat.get<u32>(pos+i*4);
pos = 0x4E6; for ( i=0; i<209; i++ ) flingy[i].Acceleration = flingyDat.get<u16>(pos+i*2);
pos = 0x688; for ( i=0; i<209; i++ ) flingy[i].HaltDistance = flingyDat.get<u32>(pos+i*4);
pos = 0x9CC; for ( i=0; i<209; i++ ) flingy[i].TurnRadius = flingyDat.get<u8>(pos+i);
pos = 0xA96; for ( i=0; i<209; i++ ) flingy[i].Unused = flingyDat.get<u8>(pos+i);
pos = 0xB6E; for ( i=0; i<209; i++ ) flingy[i].MoveControl = flingyDat.get<u8>(pos+i);
sprites.dat
Rather than like the following struct, sprites.dat is layed out in arrays consisting of each member (see below for loading code, or make your own struct for the entire file if you wish).
struct SPRITEDAT
{
u16 ImageFile;
u8 HealthBar;
u8 Unknown;
u8 IsVisible;
u8 SelectionCircleImage;
u8 SelectionCircleOffset;
};
pos = 0x000; for ( i= 0; i<517; i++ ) sprite[i].ImageFile = spriteDat.get<u16>(pos+i*2);
pos = 0x40A; for ( i=130; i<517; i++ ) sprite[i].HealthBar = spriteDat.get<u8>(pos+i-130);
pos = 0x58D; for ( i= 0; i<517; i++ ) sprite[i].Unknown = spriteDat.get<u8>(pos+i);
pos = 0x792; for ( i= 0; i<517; i++ ) sprite[i].IsVisible = spriteDat.get<u8>(pos+i);
pos = 0x997; for ( i=130; i<517; i++ ) sprite[i].SelectionCircleImage = spriteDat.get<u8>(pos+i-130);
pos = 0xB1A; for ( i=130; i<517; i++ ) sprite[i].SelectionCircleOffset = spriteDat.get<u8>(pos+i-130);
(out of characters)
TheNitesWhoSay - Clan Aura -
githubReached the top of StarCraft theory crafting 2:12 AM CST, August 2nd, 2014.
I can provide some of the lesser known file formats (.spk, font files, replay files) if needed.
Does anyone have the specs for the .bin dialog files?
?????
ALL PRAISE YOUR SUPREME LORD CORBO
I can provide some of the lesser known file formats (.spk, font files, replay files) if needed.
Does anyone have the specs for the .bin dialog files?
Farty should have some SPK. I remember him talking all bad things about you and how you sucked and that you couldn't get the algorithm right for the parallax and all that stuff.
I'm naturally just making this up
but he did make spkedit so he should also have some stuff.
I can contribute with the link to where I got many formats when I was programming stuff:
http://www.staredit.net/wiki/index.php?title=Category:ReferenceThere's SPK, several .dats, Font, GRP, Bins...
Post has been edited 1 time(s), last time on May 24 2016, 3:39 pm by Corbo.
fuck you all
Does anyone have the specs for the .bin dialog files?
I think Heinermann had a more correct one somewhere. It has a ton of unknowns because it's just sort of the internal memory structure dumped in to a file or something.
TinyMap2 - Latest in map compression! ( 7/09/14 - New build! )
EUD Action Enabler - Lightweight EUD/EPD support! (ChaosLauncher/MPQDraft support!)
EUDDB -
topic - Help out by adding your EUDs! Or Submit reference files in the References tab!
MapSketch - New image->map generator!
EUDTrig -
topic - Quickly and easily convert offsets to EUDs! (extended players supported)
SC2 Map Texture Mask Importer/Exporter - Edit texture placement in an image editor!
This page has been viewed [img]http://farty1billion.dyndns.org/Clicky.php?img.gif[/img] times!
SDE, BWAPI owner, hacker.
Does anyone have the specs for the .bin dialog files?
I think Heinermann had a more correct one somewhere. It has a ton of unknowns because it's just sort of the internal memory structure dumped in to a file or something.
It's more or less a forward linked list in fixed memory space.
https://github.com/bwapi/bwapi/blob/develop/bwapi/BWAPI/Source/BW/Dialog.hNo info on the SMK struct in the dialog files or some of the function callback signatures (i.e. pModalFcn and pfcnScrollerUpdate).
Decrypted font file:
https://github.com/bwapi/bwapi/blob/develop/bwapi/BWAPI/Source/BW/Font.hGRP is in this file for some reason:
https://github.com/bwapi/bwapi/blob/develop/bwapi/BWAPI/Source/BW/CImage.hEDIT: I have some more info dumped into
https://code.google.com/archive/p/vgce/source/default/sourceI saw the BIN SMK structure and replay format in there, along with some other things. I was thinking of porting some of that stuff to Google docs or something. A wiki would also work.
EDIT2: Speaking of replay format, this used to be in BWAPI, but it's too large for myself to maintain, and didn't serve much purpose for me, so I dumped it off to another repository:
https://github.com/bwapi/ReplayToolReplay header:
https://github.com/bwapi/ReplayTool/blob/master/libReplayTool/RepHeader.hThis interpretation of the header just shows how other known structures were mashed together to create it.
units.dat
Rather than like the following struct, units.dat is layed out in arrays consisting of each member (see below for loading code, or make your own struct for the entire file if you wish).
struct UNITDAT
{
u8 Graphics;
u16 Subunit1;
u16 Subunit2;
u16 Infestation; // ID 106-201 only
u32 ConstructionAnimation;
u8 UnitDirection;
u8 ShieldEnable;
u16 ShieldAmount;
u32 HitPoints;
u8 ElevationLevel;
u8 Unknown;
u8 Sublabel;
u8 CompAIIdle;
u8 HumanAIIdle;
u8 ReturntoIdle;
u8 AttackUnit;
u8 AttackMove;
u8 GroundWeapon;
u8 MaxGroundHits;
u8 AirWeapon;
u8 MaxAirHits;
u8 AIInternal;
u32 SpecialAbilityFlags;
u8 TargetAcquisitionRange;
u8 SightRange;
u8 ArmorUpgrade;
u8 UnitSize;
u8 Armor;
u8 RightClickAction;
u16 ReadySound; // ID 0-105 only
u16 WhatSoundStart;
u16 WhatSoundEnd;
u16 PissSoundStart; // ID 0-105 only
u16 PissSoundEnd; // ID 0-105 only
u16 YesSoundStart; // ID 0-105 only
u16 YesSoundEnd; // ID 0-105 only
u16 StarEditPlacementBoxWidth;
u16 StarEditPlacementBoxHeight;
u16 AddonHorizontal; // ID 106-201 only
u16 AddonVertical; // ID 106-201 only
u16 UnitSizeLeft;
u16 UnitSizeUp;
u16 UnitSizeRight;
u16 UnitSizeDown;
u16 Portrait;
u16 MineralCost;
u16 VespeneCost;
u16 BuildTime;
u16 Unknown1;
u8 StarEditGroupFlags;
u8 SupplyProvided;
u8 SupplyRequired;
u8 SpaceRequired;
u8 SpaceProvided;
u16 BuildScore;
u16 DestroyScore;
u16 UnitMapString;
u8 BroodwarUnitFlag;
u16 StarEditAvailabilityFlags;
};
u32 pos, i;
pos = 0x0000; for ( i= 0; i<228; i++ ) unit[i].Graphics = unitDat.get<u8>(pos+i);
pos = 0x00E4; for ( i= 0; i<228; i++ ) unit[i].Subunit1 = unitDat.get<u16>(pos+i*2);
pos = 0x02AC; for ( i= 0; i<228; i++ ) unit[i].Subunit2 = unitDat.get<u16>(pos+i*2);
pos = 0x0474; for ( i=106; i<202; i++ ) unit[i].Infestation = unitDat.get<u16>(pos+i*2);
pos = 0x0534; for ( i= 0; i<228; i++ ) unit[i].ConstructionAnimation = unitDat.get<u32>(pos+i*4);
pos = 0x08C4; for ( i= 0; i<228; i++ ) unit[i].UnitDirection = unitDat.get<u8>(pos+i);
pos = 0x09A8; for ( i= 0; i<228; i++ ) unit[i].ShieldEnable = unitDat.get<u8>(pos+i);
pos = 0x0A8C; for ( i= 0; i<228; i++ ) unit[i].ShieldAmount = unitDat.get<u16>(pos+i*2);
pos = 0x0C54; for ( i= 0; i<228; i++ ) unit[i].HitPoints = unitDat.get<u32>(pos+i*4);
pos = 0x0FE4; for ( i= 0; i<228; i++ ) unit[i].ElevationLevel = unitDat.get<u8>(pos+i);
pos = 0x10C8; for ( i= 0; i<228; i++ ) unit[i].Unknown = unitDat.get<u8>(pos+i);
pos = 0x11AC; for ( i= 0; i<228; i++ ) unit[i].Sublabel = unitDat.get<u8>(pos+i);
pos = 0x1290; for ( i= 0; i<228; i++ ) unit[i].CompAIIdle = unitDat.get<u8>(pos+i);
pos = 0x1374; for ( i= 0; i<228; i++ ) unit[i].HumanAIIdle = unitDat.get<u8>(pos+i);
pos = 0x1458; for ( i= 0; i<228; i++ ) unit[i].ReturntoIdle = unitDat.get<u8>(pos+i);
pos = 0x153C; for ( i= 0; i<228; i++ ) unit[i].AttackUnit = unitDat.get<u8>(pos+i);
pos = 0x1620; for ( i= 0; i<228; i++ ) unit[i].AttackMove = unitDat.get<u8>(pos+i);
pos = 0x1704; for ( i= 0; i<228; i++ ) unit[i].GroundWeapon = unitDat.get<u8>(pos+i);
pos = 0x17E8; for ( i= 0; i<228; i++ ) unit[i].MaxGroundHits = unitDat.get<u8>(pos+i);
pos = 0x18CC; for ( i= 0; i<228; i++ ) unit[i].AirWeapon = unitDat.get<u8>(pos+i);
pos = 0x19B0; for ( i= 0; i<228; i++ ) unit[i].MaxAirHits = unitDat.get<u8>(pos+i);
pos = 0x1A94; for ( i= 0; i<228; i++ ) unit[i].AIInternal = unitDat.get<u8>(pos+i);
pos = 0x1B78; for ( i= 0; i<228; i++ ) unit[i].SpecialAbilityFlags = unitDat.get<u32>(pos+i*4);
pos = 0x1F08; for ( i= 0; i<228; i++ ) unit[i].TargetAcquisitionRange = unitDat.get<u8>(pos+i);
pos = 0x1FEC; for ( i= 0; i<228; i++ ) unit[i].SightRange = unitDat.get<u8>(pos+i);
pos = 0x20D0; for ( i= 0; i<228; i++ ) unit[i].ArmorUpgrade = unitDat.get<u8>(pos+i);
pos = 0x21B4; for ( i= 0; i<228; i++ ) unit[i].UnitSize = unitDat.get<u8>(pos+i);
pos = 0x2298; for ( i= 0; i<228; i++ ) unit[i].Armor = unitDat.get<u8>(pos+i);
pos = 0x237C; for ( i= 0; i<228; i++ ) unit[i].RightClickAction = unitDat.get<u8>(pos+i);
pos = 0x2460; for ( i= 0; i<106; i++ ) unit[i].ReadySound = unitDat.get<u16>(pos+i*2);
pos = 0x2534; for ( i= 0; i<228; i++ ) unit[i].WhatSoundStart = unitDat.get<u16>(pos+i*2);
pos = 0x26FC; for ( i= 0; i<228; i++ ) unit[i].WhatSoundEnd = unitDat.get<u16>(pos+i*2);
pos = 0x28C4; for ( i= 0; i<106; i++ ) unit[i].PissSoundStart = unitDat.get<u16>(pos+i*2);
pos = 0x2998; for ( i= 0; i<106; i++ ) unit[i].PissSoundEnd = unitDat.get<u16>(pos+i*2);
pos = 0x2A6C; for ( i= 0; i<106; i++ ) unit[i].YesSoundStart = unitDat.get<u16>(pos+i*2);
pos = 0x2B40; for ( i= 0; i<106; i++ ) unit[i].YesSoundEnd = unitDat.get<u16>(pos+i*2);
pos = 0x2C14;
for ( i= 0; i<228; i++ )
{
unit[i].StarEditPlacementBoxWidth = unitDat.get<u16>(pos+i*4);
unit[i].StarEditPlacementBoxHeight = unitDat.get<u16>(pos+i*4+2);
}
pos = 0x2FA4; for ( i=106; i<202; i++ ) unit[i].AddonHorizontal = unitDat.get<u16>(pos+(i-106)*2);
pos = 0x3064; for ( i=106; i<202; i++ ) unit[i].AddonVertical = unitDat.get<u16>(pos+(i-106)*2);
pos = 0x3124;
for ( i= 0; i<228; i++ )
{
unit[i].UnitSizeLeft = unitDat.get<u16>(pos+i*8);
unit[i].UnitSizeUp = unitDat.get<u16>(pos+i*8+2);
unit[i].UnitSizeRight = unitDat.get<u16>(pos+i*8+4);
unit[i].UnitSizeDown = unitDat.get<u16>(pos+i*8+6);
}
pos = 0x3844; for ( i= 0; i<228; i++ ) unit[i].Portrait = unitDat.get<u16>(pos+i*2);
pos = 0x3A0C; for ( i= 0; i<228; i++ ) unit[i].MineralCost = unitDat.get<u16>(pos+i*2);
pos = 0x3BD4; for ( i= 0; i<228; i++ ) unit[i].VespeneCost = unitDat.get<u16>(pos+i*2);
pos = 0x3D9C; for ( i= 0; i<228; i++ ) unit[i].BuildTime = unitDat.get<u16>(pos+i*2);
pos = 0x3F64; for ( i= 0; i<228; i++ ) unit[i].Unknown1 = unitDat.get<u16>(pos+i*2);
pos = 0x412C; for ( i= 0; i<228; i++ ) unit[i].StarEditGroupFlags = unitDat.get<u8>(pos+i);
pos = 0x4210; for ( i= 0; i<228; i++ ) unit[i].SupplyProvided = unitDat.get<u8>(pos+i);
pos = 0x42F4; for ( i= 0; i<228; i++ ) unit[i].SupplyRequired = unitDat.get<u8>(pos+i);
pos = 0x43D8; for ( i= 0; i<228; i++ ) unit[i].SpaceRequired = unitDat.get<u8>(pos+i);
pos = 0x44BC; for ( i= 0; i<228; i++ ) unit[i].SpaceProvided = unitDat.get<u8>(pos+i);
pos = 0x45A0; for ( i= 0; i<228; i++ ) unit[i].BuildScore = unitDat.get<u16>(pos+i*2);
pos = 0x4768; for ( i= 0; i<228; i++ ) unit[i].DestroyScore = unitDat.get<u16>(pos+i*2);
pos = 0x4930; for ( i= 0; i<228; i++ ) unit[i].UnitMapString = unitDat.get<u16>(pos+i*2);
pos = 0x4AF8; for ( i= 0; i<228; i++ ) unit[i].BroodwarUnitFlag = unitDat.get<u8>(pos+i);
pos = 0x4BDC; for ( i= 0; i<228; i++ ) unit[i].StarEditAvailabilityFlags = unitDat.get<u16>(pos+i*2);
Instead of being misleading, why not just specify it exactly:
units.dat altered
struct UNITDAT
{
u8 Graphics[228];
u16 Subunit1[228];
u16 Subunit2[228];
u16 Infestation[96]; // ID 106-201 only
u32 ConstructionAnimation[228];
u8 UnitDirection[228];
u8 ShieldEnable[228];
s16 ShieldAmount[228];
s32 HitPoints[228];
u8 ElevationLevel[228];
u8 Unknown[228];
u8 Sublabel[228];
u8 CompAIIdle[228];
u8 HumanAIIdle[228];
u8 ReturntoIdle[228];
u8 AttackUnit[228];
u8 AttackMove[228];
u8 GroundWeapon[228];
u8 MaxGroundHits[228];
u8 AirWeapon[228];
u8 MaxAirHits[228];
u8 AIInternal[228];
u32 SpecialAbilityFlags[228];
u8 TargetAcquisitionRange[228];
u8 SightRange[228];
u8 ArmorUpgrade[228];
u8 UnitSize[228];
u8 Armor[228];
u8 RightClickAction[228];
u16 ReadySound[106]; // ID 0-105 only
u16 WhatSoundStart[228];
u16 WhatSoundEnd[228];
u16 PissSoundStart[106]; // ID 0-105 only
u16 PissSoundEnd[106]; // ID 0-105 only
u16 YesSoundStart[106]; // ID 0-105 only
u16 YesSoundEnd[106]; // ID 0-105 only
struct {
u16 width, height;
} placeboxSize[228];
u16 AddonHorizontal[96]; // ID 106-201 only
u16 AddonVertical[96]; // ID 106-201 only
struct {
u16 left, up, right, down;
} unitSize[228];
u16 Portrait[228];
u16 MineralCost[228];
u16 VespeneCost[228];
u16 BuildTime[228];
u16 requirementIndex[228];
u8 StarEditGroupFlags[228];
u8 SupplyProvided[228];
u8 SupplyRequired[228];
u8 SpaceRequired[228];
u8 SpaceProvided[228];
u16 BuildScore[228];
u16 DestroyScore[228];
u16 UnitMapString[228];
u8 BroodwarUnitFlag[228];
u16 StarEditAvailabilityFlags[228];
};
Can't verify if that's precisely the correct structure, but it sure as hell is easier to read from file (one-liner). To further enhance it, you can use more explicit typing (i.e.
enum class UnitType : u16 { ... };
)
Post has been edited 7 time(s), last time on May 26 2016, 4:45 am by Heinermann.
Can't verify if that's precisely the correct structure,
Other than addon horizontal/vertical, which should be in a struct, it's good.
TinyMap2 - Latest in map compression! ( 7/09/14 - New build! )
EUD Action Enabler - Lightweight EUD/EPD support! (ChaosLauncher/MPQDraft support!)
EUDDB -
topic - Help out by adding your EUDs! Or Submit reference files in the References tab!
MapSketch - New image->map generator!
EUDTrig -
topic - Quickly and easily convert offsets to EUDs! (extended players supported)
SC2 Map Texture Mask Importer/Exporter - Edit texture placement in an image editor!
This page has been viewed [img]http://farty1billion.dyndns.org/Clicky.php?img.gif[/img] times!
Instead of being misleading, why not just specify it exactly:
units.dat altered
struct UNITDAT
{
u8 Graphics[228];
u16 Subunit1[228];
u16 Subunit2[228];
u16 Infestation[96]; // ID 106-201 only
u32 ConstructionAnimation[228];
u8 UnitDirection[228];
u8 ShieldEnable[228];
s16 ShieldAmount[228];
s32 HitPoints[228];
u8 ElevationLevel[228];
u8 Unknown[228];
u8 Sublabel[228];
u8 CompAIIdle[228];
u8 HumanAIIdle[228];
u8 ReturntoIdle[228];
u8 AttackUnit[228];
u8 AttackMove[228];
u8 GroundWeapon[228];
u8 MaxGroundHits[228];
u8 AirWeapon[228];
u8 MaxAirHits[228];
u8 AIInternal[228];
u32 SpecialAbilityFlags[228];
u8 TargetAcquisitionRange[228];
u8 SightRange[228];
u8 ArmorUpgrade[228];
u8 UnitSize[228];
u8 Armor[228];
u8 RightClickAction[228];
u16 ReadySound[106]; // ID 0-105 only
u16 WhatSoundStart[228];
u16 WhatSoundEnd[228];
u16 PissSoundStart[106]; // ID 0-105 only
u16 PissSoundEnd[106]; // ID 0-105 only
u16 YesSoundStart[106]; // ID 0-105 only
u16 YesSoundEnd[106]; // ID 0-105 only
struct {
u16 width, height;
} placeboxSize[228];
u16 AddonHorizontal[96]; // ID 106-201 only
u16 AddonVertical[96]; // ID 106-201 only
struct {
u16 left, up, right, down;
} unitSize[228];
u16 Portrait[228];
u16 MineralCost[228];
u16 VespeneCost[228];
u16 BuildTime[228];
u16 requirementIndex[228];
u8 StarEditGroupFlags[228];
u8 SupplyProvided[228];
u8 SupplyRequired[228];
u8 SpaceRequired[228];
u8 SpaceProvided[228];
u16 BuildScore[228];
u16 DestroyScore[228];
u16 UnitMapString[228];
u8 BroodwarUnitFlag[228];
u16 StarEditAvailabilityFlags[228];
};
Can't verify if that's precisely the correct structure, but it sure as hell is easier to read from file (one-liner). To further enhance it, you can use more explicit typing (i.e.
enum class UnitType : u16 { ... };
)
I'd like to, but I don't have those stored and didn't feel like building them
TheNitesWhoSay - Clan Aura -
githubReached the top of StarCraft theory crafting 2:12 AM CST, August 2nd, 2014.
SDE, BWAPI owner, hacker.
I'd like to, but I don't have those stored and didn't feel like building them
I don't understand the issue. You just read in the entire original DAT file, passing in a pointer to the structure so that it reads directly onto it as a 1-1 mapping.
I'd like to, but I don't have those stored and didn't feel like building them
I don't understand the issue.
I get that those would be better, the issue is I don't have structs like that for the files, I have the loading code shown above and would have to work backwards to the structs from it (which of course takes work
) since the wiki I got the info from is dead.
TheNitesWhoSay - Clan Aura -
githubReached the top of StarCraft theory crafting 2:12 AM CST, August 2nd, 2014.
Heinermann, I wonder how the replay format implementation diverged:
https://github.com/RElesgoe/bwreplib/blob/master/bwreplib_unix/BWrepAPI.h#L124Yours doesn't seem to contain any data for the date of the replay for example.
None.
SDE, BWAPI owner, hacker.
Actually, there was an original "replay lib" thing in BWAPI, but it was incomplete and I only used it to fix replays with broken headers.
Then some team from some university wrote the rest of it, which I didn't really have anything to do with. I believe they used it to analyze replays en mass. The library they wrote is a very high level approach compared to bwreplib. I would have taken a different approach than they did, but it would still have been equally high level, and this is what we ended up with.
If you mean replay action data, it's all there AFAIK.
The major decompress-and-read-all function you're looking for is
here. The part that actually parses the actions is
here.
The actions themselves are registered into some game action factory class, in which case it does a lookup and constructs the correct one. For example, if you look at
SetSpeedAction, you'll see the read function, which reads the correct parameters from the replay actions data.
EDIT: bwreplib seems to have way too many unknowns (especially actions, "objects" (which should be unit types), etc). Most things are known by now.
Post has been edited 1 time(s), last time on May 30 2016, 6:36 am by Heinermann.