partial void PointsCustomParse(OverlayStream stream, long finalPos, int offset, RecordType type, PreviousParse lastParsed) { if (stream.Complete) { return; } var subMeta = stream.GetSubrecord(); if (subMeta.RecordType != RecordTypes.PGRP) { return; } stream.Position += subMeta.HeaderLength; var pointBytes = stream.ReadMemory(subMeta.ContentLength); subMeta = stream.GetSubrecord(); switch (subMeta.RecordTypeInt) { case 0x52524750: // "PGRR": stream.Position += subMeta.HeaderLength; var connBytes = stream.ReadMemory(subMeta.ContentLength); this.Points = BinaryOverlayList.FactoryByLazyParse <IRoadPointGetter>( pointBytes, _package, getter: (s, p) => { int numPts = pointBytes.Length / RoadBinaryCreateTranslation.POINT_LEN; RoadPoint[] points = new RoadPoint[numPts]; var connFloats = connBytes.Span.AsFloatSpan(); for (int i = 0; i < numPts; i++) { var pt = RoadBinaryCreateTranslation.ReadPathGridPoint(s, out var numConn); s = s.Slice(RoadBinaryCreateTranslation.POINT_LEN); P3Float[] conns = new P3Float[numConn]; for (int j = 0; j < numConn; j++) { conns[j] = new P3Float( x: connFloats[0], y: connFloats[1], z: connFloats[2]); connFloats = connFloats.Slice(3); } pt.Connections.AddRange(conns); points[i] = pt; } return(points); }); break; default: this.Points = BinaryOverlayList.FactoryByStartIndex <IRoadPointGetter>( pointBytes, _package, itemLength: RoadBinaryCreateTranslation.POINT_LEN, getter: (s, p) => RoadBinaryCreateTranslation.ReadPathGridPoint(s, out var numConn)); break; } }
partial void RegionAreaLogicCustomParse( OverlayStream stream, int offset) { var rdat = stream.GetSubrecord(); while (rdat.RecordType.Equals(RecordTypes.RDAT)) { ParseRegionData(stream, offset); if (stream.Complete) { break; } rdat = stream.GetSubrecord(); } }
public static VirtualMachineAdapterBinaryOverlay VirtualMachineAdapterFactory( OverlayStream stream, BinaryOverlayFactoryPackage package, RecordTypeConverter?recordTypeConverter = null) { var ret = new VirtualMachineAdapterBinaryOverlay( bytes: HeaderTranslation.ExtractSubrecordMemory(stream.RemainingMemory, package.MetaData.Constants), package: package); var finalPos = checked ((int)(stream.Position + stream.GetSubrecord().TotalLength)); int offset = stream.Position + package.MetaData.Constants.SubConstants.TypeAndLengthLength; stream.Position += 0x0 + package.MetaData.Constants.SubConstants.HeaderLength; ret.CustomFactoryEnd( stream: stream, finalPos: stream.Length, offset: offset); return(ret); }
partial void PointToPointConnectionsCustomParse(OverlayStream stream, long finalPos, int offset, RecordType type, int?lastParsed) { var dataFrame = stream.ReadSubrecordFrame(); uint ptCount = BinaryPrimitives.ReadUInt16LittleEndian(dataFrame.Content); var pgrpMeta = stream.GetSubrecord(); if (pgrpMeta.RecordType != PathGridBinaryCreateTranslation.PGRP) { return; } stream.Position += pgrpMeta.HeaderLength; var pointData = stream.ReadMemory(pgrpMeta.ContentLength); var bytePointsNum = pgrpMeta.ContentLength / PathGridBinaryCreateTranslation.POINT_LEN; if (bytePointsNum != ptCount) { throw new ArgumentException($"Unexpected point byte length, when compared to expected point count. {pgrpMeta.ContentLength} bytes: {bytePointsNum} != {ptCount} points."); } bool readPGRR = false; for (int recAttempt = 0; recAttempt < 2; recAttempt++) { if (stream.Complete) { break; } var subMeta = stream.GetSubrecord(); switch (subMeta.RecordType.TypeInt) { case 0x47414750: //"PGAG": this._PGAGLocation = stream.Position - offset; stream.Position += subMeta.TotalLength; break; case 0x52524750: // "PGRR": stream.Position += subMeta.HeaderLength; var connectionPtData = stream.ReadMemory(subMeta.ContentLength); this.PointToPointConnections = BinaryOverlayList.FactoryByLazyParse <IPathGridPointGetter>( pointData, _package, getter: (s, p) => { var connectionInts = connectionPtData.Span.AsInt16Span(); IPathGridPointGetter[] pathGridPoints = new IPathGridPointGetter[bytePointsNum]; for (int i = 0; i < bytePointsNum; i++) { var pt = PathGridPointBinaryOverlay.Factory(s, p); pt.Connections.AddRange(connectionInts.Slice(0, pt.NumConnections).ToArray()); pathGridPoints[i] = pt; s = s.Slice(16); connectionInts = connectionInts.Slice(pt.NumConnections); } return(pathGridPoints); }); readPGRR = true; break; default: break; } } if (!readPGRR) { this.PointToPointConnections = BinaryOverlayList.FactoryByStartIndex <IPathGridPointGetter>( pointData, this._package, itemLength: 16, getter: (s, p) => { return(PathGridBinaryCreateTranslation.ReadPathGridPoint(s, out var numConn)); }); } }
private void ParseRegionData(OverlayStream stream, int offset) { int loc = stream.Position - offset; var rdatFrame = stream.ReadSubrecordFrame(); RegionData.RegionDataType dataType = (RegionData.RegionDataType)BinaryPrimitives.ReadUInt32LittleEndian(rdatFrame.Content); var len = rdatFrame.TotalLength; if (!stream.Complete) { var contentMeta = stream.GetSubrecord(); var recType = contentMeta.RecordType; if (recType == RecordTypes.ICON) { var totalLen = contentMeta.TotalLength; len += totalLen; // Skip icon subrecord for now contentMeta = stream.GetSubrecord(offset: rdatFrame.TotalLength + totalLen); } if (RegionBinaryCreateTranslation.IsExpected(dataType, contentMeta.RecordType)) { len += contentMeta.TotalLength; stream.Position += contentMeta.TotalLength; } } switch (dataType) { case RegionData.RegionDataType.Object: _ObjectsSpan = this._data.Slice(loc, len); break; case RegionData.RegionDataType.Map: _MapSpan = this._data.Slice(loc, len); break; case RegionData.RegionDataType.Grass: _GrassesSpan = this._data.Slice(loc, len); break; case RegionData.RegionDataType.Land: _LandSpan = this._data.Slice(loc, len); break; case RegionData.RegionDataType.Sound: if (stream.TryGetSubrecord(out var nextRec) && (nextRec.RecordType.Equals(RegionBinaryCreateTranslation.RDSA) || nextRec.RecordType.Equals(RegionBinaryCreateTranslation.RDMO))) { len += nextRec.TotalLength; } _SoundsSpan = this._data.Slice(loc, len); break; case RegionData.RegionDataType.Weather: _WeatherSpan = this._data.Slice(loc, len); break; default: throw new NotImplementedException(); } }