public static Vcf ParseVcf(string filename) { var vcf = new Vcf(); using (var br = new Bwd2Reader(filename)) { br.FindNext("VCFC"); vcf.VariantName = br.ReadCString(16); vcf.VdfFilename = br.ReadCString(13); vcf.VtfFilename = br.ReadCString(13); vcf.EngineType = br.ReadUInt32(); vcf.SuspensionType = br.ReadUInt32(); vcf.BrakesType = br.ReadUInt32(); vcf.WdfFrontFilename = br.ReadCString(13); vcf.WdfMidFilename = br.ReadCString(13); vcf.WdfBackFilename = br.ReadCString(13); vcf.ArmorFront = br.ReadUInt32(); vcf.ArmorLeft = br.ReadUInt32(); vcf.ArmorRight = br.ReadUInt32(); vcf.ArmorRear = br.ReadUInt32(); vcf.ChassisFront = br.ReadUInt32(); vcf.ChassisLeft = br.ReadUInt32(); vcf.ChassisRight = br.ReadUInt32(); vcf.ChassisRear = br.ReadUInt32(); vcf.ArmorOrChassisLeftToAdd = br.ReadUInt32(); br.FindNext("WEPN"); vcf.Weapons = new List <VcfWeapon>(); while (br.Current != null && br.Current.Name != "EXIT") { var vcfWeapon = new VcfWeapon { MountPoint = (MountPoint)br.ReadUInt32(), GdfFilename = br.ReadCString(13) }; vcf.Weapons.Add(vcfWeapon); br.Next(); } } if (vcf.WdfFrontFilename.ToUpper() != "NULL") { vcf.FrontWheelDef = WdfParser.ParseWdf(vcf.WdfFrontFilename); } if (vcf.WdfMidFilename.ToUpper() != "NULL") { vcf.MidWheelDef = WdfParser.ParseWdf(vcf.WdfMidFilename); } if (vcf.WdfBackFilename.ToUpper() != "NULL") { vcf.BackWheelDef = WdfParser.ParseWdf(vcf.WdfBackFilename); } return(vcf); }
public static Sdf LoadSdf(string filename) { filename = filename.ToLower(); if (SdfCache.ContainsKey(filename)) { return(SdfCache[filename]); } using (var br = new Bwd2Reader(filename)) { var sdf = new Sdf(); br.FindNext("SDFC"); sdf.Name = br.ReadCString(16); var one = br.ReadUInt32(); var size = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); var unk1 = br.ReadUInt32(); var unk2 = br.ReadUInt32(); var fifty = br.ReadUInt32(); var xdf = br.ReadCString(13); var wav = br.ReadCString(13); br.FindNext("SGEO"); var numParts = br.ReadUInt32(); sdf.Parts = new SdfPart[numParts]; for (int i = 0; i < numParts; i++) { var sdfPart = new SdfPart(); sdfPart.Name = br.ReadCString(8); sdfPart.Right = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.Up = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.Forward = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.Position = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.ParentName = br.ReadCString(8); br.BaseStream.Seek(56, SeekOrigin.Current); sdf.Parts[i] = sdfPart; } SdfCache.Add(filename, sdf); return(sdf); } }
public static Wdf ParseWdf(string filename) { using (var br = new Bwd2Reader(filename)) { var wdf = new Wdf(); br.FindNext("WDFC"); wdf.Name = br.ReadCString(20); wdf.Float1 = br.ReadSingle(); //160 wdf.Float2 = br.ReadSingle(); //100 wdf.Float3 = br.ReadSingle(); //70 wdf.Float4 = br.ReadSingle(); //30 wdf.Byte1 = br.ReadByte(); // 255 wdf.Byte2 = br.ReadByte(); // 255 wdf.Byte3 = br.ReadByte(); // 127 wdf.Byte4 = br.ReadByte(); // 127 wdf.Int1 = br.ReadUInt32(); // 100 wdf.Float5 = br.ReadSingle(); //10 wdf.Radius = br.ReadSingle(); br.FindNext("WGEO"); var numParts = br.ReadUInt32(); wdf.Parts = new SdfPart[numParts]; for (int i = 0; i < numParts; i++) { var sdfPart = new SdfPart(); sdfPart.Name = br.ReadCString(8); sdfPart.Right = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.Up = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.Forward = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.Position = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.ParentName = br.ReadCString(8); br.BaseStream.Seek(36, SeekOrigin.Current); wdf.Parts[i] = sdfPart; } return(wdf); } }
public Bwd2Reader(Bwd2Reader parentReader) : this(new PartStream(parentReader.BaseStream, parentReader.Current.DataPosition, parentReader.Current.DataLength)) { }
public static Vdf ParseVdf(string filename) { using (var br = new Bwd2Reader(filename)) { var vdf = new Vdf(); br.FindNext("VDFC"); vdf.Name = br.ReadCString(16); vdf.Unk0 = br.ReadUInt32(); vdf.Unk1 = br.ReadUInt32(); vdf.Unk2 = br.ReadUInt32(); vdf.Unk70f = br.ReadSingle(); vdf.Unk35f = br.ReadSingle(); vdf.Unk30f = br.ReadSingle(); vdf.Unk25f = br.ReadSingle(); vdf.Unk255b = br.ReadByte(); vdf.Unk255b2 = br.ReadByte(); vdf.Unk127b = br.ReadByte(); vdf.Unk127b2 = br.ReadByte(); vdf.Unk1320f = br.ReadSingle(); vdf.Unk1f = br.ReadSingle(); vdf.Unk63b = br.ReadByte(); vdf.Unk82b = br.ReadByte(); vdf.Unk73b = br.ReadByte(); vdf.Unk157b = br.ReadByte(); vdf.Unk57b = br.ReadByte(); vdf.Unk4 = br.ReadUInt32(); br.FindNext("SOBJ"); vdf.SOBJGeoName = br.ReadCString(8); vdf.VLocs = new List <VLoc>(); br.FindNext("VLOC"); while (br.Current != null && br.Current.Name != "EXIT") { var vloc = new VLoc { Number = br.ReadUInt32(), Right = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()), Up = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()), Forward = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()), Position = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()) }; vdf.VLocs.Add(vloc); br.Next(); } br.FindNext("VGEO"); var numParts = br.ReadUInt32(); vdf.PartsThirdPerson = new List <SdfPart[]>(4); for (int damageState = 0; damageState < 4; damageState++) { var parts = new SdfPart[numParts]; for (int i = 0; i < numParts; i++) { var sdfPart = new SdfPart(); sdfPart.Name = br.ReadCString(8); sdfPart.Right = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.Up = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.Forward = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.Position = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.ParentName = br.ReadCString(8); br.BaseStream.Seek(36, SeekOrigin.Current); parts[i] = sdfPart; } vdf.PartsThirdPerson.Add(parts); } br.BaseStream.Seek(100 * numParts * 12, SeekOrigin.Current); vdf.PartsFirstPerson = new SdfPart[numParts]; for (int i = 0; i < numParts; i++) { var sdfPart = new SdfPart(); sdfPart.Name = br.ReadCString(8); sdfPart.Right = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.Up = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.Forward = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.Position = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); sdfPart.ParentName = br.ReadCString(8); br.BaseStream.Seek(36, SeekOrigin.Current); vdf.PartsFirstPerson[i] = sdfPart; } br.FindNext("WLOC"); vdf.WheelLoc = new WheelLoc[6]; for (int i = 0; i < 6; i++) { var wheelLoc = vdf.WheelLoc[i] = new WheelLoc(); var unk1 = br.ReadUInt32(); wheelLoc.Right = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); wheelLoc.Up = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); wheelLoc.Forward = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); wheelLoc.Position = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); var unk2 = br.ReadSingle(); } vdf.HLocs = new List <HLoc>(); br.FindNext("HLOC"); while (br.Current != null && br.Current.Name != "EXIT") { var hloc = new HLoc { Label = br.ReadCString(16), Num1 = br.ReadUInt32(), Num2 = br.ReadUInt32(), Num3 = br.ReadUInt32(), Right = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()), Up = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()), Forward = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()), Position = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()), Unk = br.ReadSingle() }; vdf.HLocs.Add(hloc); br.Next(); } return(vdf); } }
public static MissonDefinition ReadMsnMission(string filename) { var mdef = new MissonDefinition(); using (var msn = new Bwd2Reader(filename)) { msn.FindNext("WDEF"); using (var wdef = new Bwd2Reader(msn)) { wdef.FindNext("WRLD"); wdef.BaseStream.Seek(30, SeekOrigin.Current); mdef.PaletteFilePath = wdef.ReadCString(13); mdef.LumaTableFilePath = wdef.ReadCString(13); mdef.XlucencyTableFilePath = wdef.ReadCString(13); mdef.ObjectiveFilePath = wdef.ReadCString(13); mdef.SkyTextureFilePath = wdef.ReadCString(13); mdef.ScroungeTextureFilePath = wdef.ReadCString(13); mdef.SurfaceTextureFilePath = wdef.ReadCString(13); mdef.LevelMapFilePath = wdef.ReadCString(13); mdef.HzdFilePath = wdef.ReadCString(13); } msn.FindNext("TDEF"); var heights = new List <float[, ]>(); byte[] patchConfig; using (var tdef = new Bwd2Reader(msn)) { tdef.FindNext("ZMAP"); var numUniqueTerrainPatches = tdef.ReadByte(); patchConfig = tdef.ReadBytes(80 * 80); tdef.FindNext("ZONE"); var unk = tdef.ReadByte(); var terrainFilePath = tdef.ReadCString(13); using (var terr = new BinaryReader(VirtualFilesystem.Instance.GetFileStream(terrainFilePath))) { for (var i = 0; i < numUniqueTerrainPatches; i++) { var h = new float[129, 129]; for (int z = 0; z < 128; z++) { for (int x = 0; x < 128; x++) { var tpoint = terr.ReadUInt16(); var height = (tpoint & 0x0FFF) / 4096.0f; h[z, x] = height; } } heights.Add(h); } } var botLeft = new Vector2(80, 80); var topRight = new Vector2(0, 0); var defaultHeights = new float[129, 129]; for (int z = 0; z < 80; z++) { for (int x = 0; x < 80; x++) { var patchIdx = patchConfig[z * 80 + x]; if (patchIdx == 0xFF) { //mdef.TerrainPatches[x, z] = new TerrainPatch(defaultTerrainData); } else { if (x < botLeft.x) { botLeft.x = x; } if (z < botLeft.y) { botLeft.y = z; } if (x > topRight.x) { topRight.x = x; } if (z > topRight.y) { topRight.y = z; } var h = heights[patchIdx]; var rightPatchIdx = x == 79 ? 0xFF : patchConfig[z * 80 + x + 1]; var rightHeights = rightPatchIdx == 0xFF ? defaultHeights : heights[rightPatchIdx]; for (int xx = 0; xx < 129; xx++) { h[xx, 128] = rightHeights[xx, 0]; } var bottomPatchIdx = z == 79 ? 0xFF : patchConfig[(z + 1) * 80 + x]; var bottomHeights = bottomPatchIdx == 0xFF ? defaultHeights : heights[bottomPatchIdx]; for (int zz = 0; zz < 129; zz++) { h[128, zz] = bottomHeights[0, zz]; } var bottomRightPatchIdx = z == 79 || x == 79 ? 0xFF : patchConfig[(z + 1) * 80 + x + 1]; var bottomRightHeights = bottomRightPatchIdx == 0xFF ? defaultHeights : heights[bottomRightPatchIdx]; h[128, 128] = bottomRightHeights[0, 0]; var tdata = CreateTerrainData(); tdata.SetHeights(0, 0, h); mdef.TerrainPatches[x, z] = new TerrainPatch(tdata); } } } mdef.Middle = (topRight + botLeft) / 2.0f; } msn.FindNext("RDEF"); using (var rdef = new Bwd2Reader(msn)) { rdef.FindNext("RSEG"); while (rdef.Current != null && rdef.Current.Name != "EXIT") { var segmentType = rdef.ReadUInt32(); var segmentPieceCount = rdef.ReadUInt32(); var road = new Road { SegmentType = (RoadSegmentType)segmentType }; for (int i = 0; i < segmentPieceCount; i++) { var roadSegment = new RoadSegment { Left = new Vector3(rdef.ReadSingle(), rdef.ReadSingle(), rdef.ReadSingle()), Right = new Vector3(rdef.ReadSingle(), rdef.ReadSingle(), rdef.ReadSingle()) }; var pos = roadSegment.Left; var patchPosX = (int)(pos.x / 640.0f); var patchPosZ = (int)(pos.z / 640.0f); var localPositionX = (pos.x % 640) / 640.0f; var localPositionZ = (pos.z % 640) / 640.0f; var y = mdef.TerrainPatches[patchPosX, patchPosZ].TerrainData.GetInterpolatedHeight(localPositionX, localPositionZ) + 0.1f; pos.y = y; roadSegment.Left = pos; pos = roadSegment.Right; patchPosX = (int)(pos.x / 640.0f); patchPosZ = (int)(pos.z / 640.0f); localPositionX = (pos.x % 640) / 640.0f; localPositionZ = (pos.z % 640) / 640.0f; y = mdef.TerrainPatches[patchPosX, patchPosZ].TerrainData.GetInterpolatedHeight(localPositionX, localPositionZ) + 0.1f; pos.y = y; roadSegment.Right = pos; road.RoadSegments.Add(roadSegment); //TODO: Figure out } mdef.Roads.Add(road); rdef.Next(); } } msn.FindNext("ODEF"); using (var odef = new Bwd2Reader(msn)) { odef.FindNext("OBJ"); while (odef.Current.Name != "EXIT") { var rawlabel = odef.ReadBytes(8); int labelhigh = 0; StringBuilder labelBuilder = new StringBuilder(); for (int i = 0; i < 8; i++) { var v = rawlabel[i]; if (v > 0x7f) { labelhigh = (labelhigh << 1) | 0x01; } else { labelhigh = (labelhigh << 1) & 0xfe; } v = (byte)(v & 0x7f); if (v != 0) { labelBuilder.Append((char)v); } } var label = labelBuilder.ToString(); var right = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle()); var upwards = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle()); var forward = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle()); var pos = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle()); odef.BaseStream.Position += 36; var classId = (ClassId)odef.ReadUInt32(); odef.ReadUInt16(); var teamId = odef.ReadUInt16(); var localPosition = new Vector3(pos.x % 640, pos.y, pos.z % 640); var patchPosX = (int)(pos.x / 640.0f); var patchPosZ = (int)(pos.z / 640.0f); mdef.TerrainPatches[patchPosX, patchPosZ].Objects.Add(new Odef { Label = label, Id = labelhigh, LocalPosition = localPosition, ClassId = classId, TeamId = teamId, LocalRotation = Quaternion.LookRotation(forward, upwards) }); odef.Next(); } } msn.FindNext("LDEF"); using (var ldef = new Bwd2Reader(msn)) { ldef.FindNext("OBJ"); while (ldef.Current != null && ldef.Current.Name != "EXIT") { var label = ldef.ReadCString(8); ldef.BaseStream.Position += 84; var classId = (ClassId)ldef.ReadUInt32(); ldef.ReadUInt32(); var numStrings = ldef.ReadUInt32(); var stringPositions = new List <Vector3>(); for (int i = 0; i < numStrings; i++) { var stringPos = new Vector3(ldef.ReadSingle(), ldef.ReadSingle(), ldef.ReadSingle()); stringPositions.Add(stringPos); } mdef.StringObjects.Add(new Ldef { Label = label, StringPositions = stringPositions }); ldef.Next(); } } } return(mdef); }
/* * TMT's are referred in this order: * Front, Back, Right, Left, Top, Under * * Given a filename of: * 1CP1FTFT * * decodes as * 1CP = First cop car skin * 1 = LOD level * FTFT = Front Front * * Sequence of tmt files: * Front * Mid * Back * Top * * Full list: * * FTFT * FTBK * FTRT * FTLT * FTTP * FTUN * * MDFT * MDBK * MDRT * MDLT * MDTP * MDUN * * BKFT * BKBK * BKRT * BKLT * BKTP * BKUN * * TPFT * TPBK * TPRT * TPLT * TPTP * TPUN */ public static Vtf ParseVtf(string filename) { var vtf = new Vtf(); using (var br = new Bwd2Reader(filename)) { br.FindNext("VTFC"); vtf.VdfFilename = br.ReadCString(13); vtf.PaintSchemeName = br.ReadCString(16); vtf.TmtFilenames = new string[78]; for (int i = 0; i < vtf.TmtFilenames.Length; i++) { vtf.TmtFilenames[i] = br.ReadCString(13); } vtf.Maps = new string[13]; for (int i = 0; i < vtf.Maps.Length; i++) { vtf.Maps[i] = br.ReadCString(13).Replace(".map", ""); } } vtf.Tmts = new Dictionary <string, Tmt>(); for (var tmtIdx = 0; tmtIdx < vtf.TmtFilenames.Length; tmtIdx++) { var tmtFilename = vtf.TmtFilenames[tmtIdx]; if (tmtFilename != "NULL") { using (var br = new BinaryReader(VirtualFilesystem.Instance.GetFileStream(tmtFilename))) { var one = br.ReadUInt32(); var zero1 = br.ReadUInt32(); var zero2 = br.ReadUInt32(); var zero3 = br.ReadUInt32(); var zero4 = br.ReadUInt32(); var two = br.ReadUInt32(); var two2 = br.ReadUInt32(); var four = br.ReadUInt32(); var zero5 = br.ReadUInt32(); var zero6 = br.ReadUInt32(); var tenFloat = br.ReadSingle(); var zero7 = br.ReadSingle(); var zero8 = br.ReadSingle(); var zero9 = br.ReadSingle(); var zero10 = br.ReadSingle(); var zero11 = br.ReadSingle(); var tmt = new Tmt { TextureNames = new List <string>() }; while (br.BaseStream.Position < br.BaseStream.Length) { var textureName = br.ReadCString(8); tmt.TextureNames.Add(textureName); } vtf.Tmts.Add(tmtFilename.Substring(3), tmt); } } } return(vtf); }