public override float ReadSingle() { FillBuffer(4); fixed(byte *p = buffer) return(Reinterpret.Int32AsFloat(BigEndian.ReadInt32(p))); }
internal static T Admixed <T>(this object admixee) where T : class { var untyped = Admixed(admixee); var typed = Reinterpret <object> .Cast <T>(untyped); return(typed); }
public override double ReadDouble() { FillBuffer(8); fixed(byte *p = buffer) return(Reinterpret.Int64AsDouble(BigEndian.ReadInt64(p))); }
public PCM(Stream stream) : base(stream) { format = Reinterpret.Memory <PCMFormat>(this["fmt "].ResourceData); data = this["data"].ResourceData; hasBeenSet = true; }
public override void Write(double value) { fixed(byte *p = buffer) BigEndian.WriteInt64(p, Reinterpret.DoubleAsInt64(value)); OutStream.Write(buffer, 0, 8); }
public override void Write(float value) { fixed(byte *p = buffer) BigEndian.WriteDecimal(p, Reinterpret.FloatAsInt32(value)); OutStream.Write(buffer, 0, 4); }
public RiffHeader(uint type) { Type = type; HeaderBlockHeader = new RiffBlockHeader(); HeaderBlockHeader.FourCC = Reinterpret.FourCC("RIFF", ByteOrder.BigEndian); HeaderBlockHeader.Length = 4; }
/// <summary> /// A good psuedo-random hash function for Unity's Vector2 class. /// </summary> public static int GetHashCode(Vector2 v) { //Reinterpret the floats as ints and get the hash code for them. int x = new Reinterpret(v.x).Int, y = new Reinterpret(v.y).Int; return(new Vector2i(x, y).GetHashCode()); }
/// <summary> /// Writes this instance to an output stream. /// </summary> /// <param name="output">output stream</param> public void Write(Stream output) { byte[] buffer = Reinterpret.Object(header); output.Write(buffer, 0, buffer.Length); for (int i = 0; i < blocks.Count; i++) { blocks[i].Write(output); } }
/// <summary> /// A good psuedo-random hash function for Unity's Vector3 class. /// </summary> public static int GetHashCode(Vector3 v) { //Reinterpret the floats as ints and get the hash code for them. int x = Reinterpret.Get(v.x), y = Reinterpret.Get(v.y), z = Reinterpret.Get(v.z); return(new Vector3i(x, y, z).GetHashCode()); }
private void FlushIndex(int modOffset) { map.Position = header.IndexOffset + modOffset; writer.Write(Reinterpret.Object <IndexHeader>(index)); map.Position += index.TagTypeCount * 12; for (int i = 0; i < index.TagCount; i++) { writer.Write(Reinterpret.Object <IndexElement>(tags[i])); } }
public static T ReferenceKey <T>(this object referenced) { var keyedReference = referenced as IKeyedReference; if (null != keyedReference) { return(Reinterpret <object> .Cast <T>(keyedReference.ReferenceKey)); } return(default(T)); }
public PCM(short channels, int sampleRate) : base("WAVE") { format = new PCMFormat(); format.ChannelCount = channels; format.SignificantBitsPerSample = 16; format.BlockAlign = (short)(format.SignificantBitsPerSample / 8 * format.ChannelCount); format.SampleRate = sampleRate; format.BytesPerSecond = format.SampleRate * format.BlockAlign; format.CompressionCode = 1; format.ExtraByteCount = 0; AddBlock("fmt ", Reinterpret.Object(format)); }
public XboxADPCM(short channels, int sampleRate) : base("WAVE") { format = new XboxAdpcmFormat(); format.ChannelCount = channels; format.BlockAlign = (short)(format.ChannelCount * 36); format.SampleRate = sampleRate; format.BytesPerSecond = (format.SampleRate * format.BlockAlign) >> 6; format.SignificantBitsPerSample = 4; format.CompressionCode = 105; format.ExtendedByteCount = 2; format.SamplesPerBlock = 64; AddBlock("fmt ", Reinterpret.Object(format)); }
/// <summary> /// Creates a new instance of the Class class using the specified class stream as the source. /// </summary> /// <param name="name">the name of the class definition</param> public Class(Stream source, string name) { this.name = name; BinaryReader reader = new BinaryReader(source); header = Reinterpret.Memory <ClassHeader>(reader.ReadBytes(Marshal.SizeOf(typeof(ClassHeader)))); if (header.Signature != Signature) { throw new InvalidDataException("Class source stream magic identifier did not match."); } for (int i = 0; i < header.ElementCount; i++) { elements.Add(new ElementWrapper(Reinterpret.Memory <Element>(reader.ReadBytes(Marshal.SizeOf(typeof(Element)))))); } }
internal RiffBlock(Stream stream) { int headerLength = Marshal.SizeOf(typeof(RiffBlockHeader)); data = new byte[headerLength]; stream.Read(data, 0, headerLength); header = Reinterpret.Memory <RiffBlockHeader>(data); if (header.Length == 0) { data = new byte[0]; } else { data = new byte[header.Length]; stream.Read(data, 0, header.Length); } }
/// <summary> /// Creates a RIFF object with data from the given RIFF-compatable stream. /// </summary> /// <param name="input">a stream containing RIFF data</param> public RIFF(Stream input) { if (!input.CanRead) { throw new ArgumentException("The RIFF parser requires a readable stream.", "input"); } long initial = input.Position; int headerLength = Marshal.SizeOf(typeof(RiffHeader)); int innerHeaderLength = Marshal.SizeOf(typeof(RiffBlockHeader)); byte[] data = new byte[headerLength]; input.Read(data, 0, headerLength); header = Reinterpret.Memory <RiffHeader>(data); blocks = new List <RiffBlock>(); while (input.Position - initial < header.HeaderBlockHeader.Length + innerHeaderLength) { blocks.Add(new RiffBlock(input)); } }
public void WriteToDataStream(BinaryWriter writer) { int currentEnd = (int)writer.BaseStream.Position + MetaRootSize; int importNameBlockSize = 0; for (int i = 0; i < importNames.Count; i++) { importNameBlockSize += importNames[i].Length; } // tier 0 writer.Write(playbackParameters.Count); writer.Write(currentEnd); currentEnd += playbackParameters.Count * Marshal.SizeOf(typeof(Playback)); writer.Write(scales.Count); writer.Write(currentEnd); currentEnd += scales.Count * Marshal.SizeOf(typeof(Scale)); writer.Write(importNames.Count); writer.Write(currentEnd); currentEnd += importNames.Count * sizeof(byte) + importNameBlockSize; writer.Write(pitchRangeParameters.Count); writer.Write(currentEnd); currentEnd += pitchRangeParameters.Count * Marshal.SizeOf(typeof(PitchRangeParametersBlock)); writer.Write(pitchRanges.Count); writer.Write(currentEnd); currentEnd += pitchRanges.Count * Marshal.SizeOf(typeof(PitchRange)); writer.Write(permutations.Count); writer.Write(currentEnd); currentEnd += permutations.Count * Marshal.SizeOf(typeof(Permutation)); writer.Write(customPlaybacks.Count); writer.Write(currentEnd); currentEnd += customPlaybacks.Count * Marshal.SizeOf(typeof(CustomPlayback)); writer.Write(runtimeFlags.Count); writer.Write(currentEnd); currentEnd += runtimeFlags.Count * Marshal.SizeOf(typeof(RuntimePermutationFlags)); writer.Write(chunks.Count); writer.Write(currentEnd); currentEnd += chunks.Count * Marshal.SizeOf(typeof(Chunk)); writer.Write(promotions.Count); writer.Write(currentEnd); currentEnd += promotions.Count * Marshal.SizeOf(typeof(Promotion)); writer.Write(extraInfos.Count); writer.Write(currentEnd); currentEnd += extraInfos.Count * Marshal.SizeOf(typeof(ExtraInfo)); // tier 1 for (int i = 0; i < playbackParameters.Count; i++) { writer.Write(Reinterpret.Object <Playback>(playbackParameters[i])); } for (int i = 0; i < scales.Count; i++) { writer.Write(Reinterpret.Object <Scale>(scales[i])); } for (int i = 0; i < importNames.Count; i++) { writer.Write((byte)Encoding.ASCII.GetByteCount(importNames[i])); writer.Write(Encoding.ASCII.GetBytes(importNames[i])); } for (int i = 0; i < pitchRangeParameters.Count; i++) { writer.Write(Reinterpret.Object <PitchRangeParametersBlock>(pitchRangeParameters[i])); } for (int i = 0; i < pitchRanges.Count; i++) { writer.Write(Reinterpret.Object <PitchRange>(pitchRanges[i])); } for (int i = 0; i < permutations.Count; i++) { writer.Write(Reinterpret.Object <Permutation>(permutations[i])); } for (int i = 0; i < customPlaybacks.Count; i++) { CustomPlayback customPlayback = customPlaybacks[i]; if (customPlayback.FilterCount > 0) { customPlayback.FilterOffset = currentEnd; currentEnd += customPlayback.FilterCount * Marshal.SizeOf(typeof(CustomPlayback.Filter)); } else { customPlayback.FilterOffset = 0; } if (customPlayback.PitchPlaybackParametersCount > 0) { customPlayback.PitchPlaybackParametersOffset = currentEnd; currentEnd += customPlayback.PitchPlaybackParametersCount * Marshal.SizeOf(typeof(CustomPlayback.PitchPlaybackParameters)); } else { customPlayback.PitchPlaybackParametersOffset = 0; } writer.Write(Reinterpret.Object <CustomPlayback>(customPlayback)); } for (int i = 0; i < runtimeFlags.Count; i++) { writer.Write(Reinterpret.Object <RuntimePermutationFlags>(runtimeFlags[i])); } for (int i = 0; i < chunks.Count; i++) { writer.Write(Reinterpret.Object <Chunk>(chunks[i])); } for (int i = 0; i < promotions.Count; i++) { Promotion promotion = promotions[i]; if (promotion.RuleCount > 0) { promotion.RuleOffset = currentEnd; currentEnd += promotion.RuleCount * Marshal.SizeOf(typeof(Promotion.Rule)); } else { promotion.RuleOffset = 0; } if (promotion.TimerCount > 0) { promotion.TimerOffset = currentEnd; currentEnd += promotion.TimerCount * Marshal.SizeOf(typeof(Promotion.Timer)); } else { promotion.TimerOffset = 0; } writer.Write(Reinterpret.Object <Promotion>(promotion)); } for (int i = 0; i < extraInfos.Count; i++) { ExtraInfo extraInfo = extraInfos[i]; if (extraInfo.ResourceBlock.RawSize > 0) { uint encoded = Conversion.ToUInt(currentEnd) & 0x3fffffff; encoded |= Conversion.ToUInt(extraInfo.ResourceBlock.RawOffset) & 0xc0000000; extraInfo.ResourceBlock.RawOffset = Conversion.ToInt(encoded); currentEnd += extraInfo.ResourceBlock.RawSize * sizeof(byte); } else { extraInfo.ResourceBlock.RawOffset = 0; } if (extraInfo.ResourceBlock.ResourceCount > 0) { extraInfo.ResourceBlock.ResourceOffset = currentEnd; currentEnd += extraInfo.ResourceBlock.ResourceCount * Marshal.SizeOf(typeof(ResourceBlock.Resource)); } else { extraInfo.ResourceBlock.ResourceOffset = 0; } writer.Write(Reinterpret.Object <ExtraInfo>(extraInfo)); } // tier 2 for (int i = 0; i < customPlaybacks.Count; i++) { for (int j = 0; j < customPlaybacks[i].FilterCount; j++) { writer.Write(Reinterpret.Object <CustomPlayback.Filter>(customFilters[i][j])); } for (int j = 0; j < customPlaybacks[i].PitchPlaybackParametersCount; j++) { writer.Write(Reinterpret.Object <CustomPlayback.PitchPlaybackParameters>(customPitchParameters[i][j])); } } for (int i = 0; i < promotions.Count; i++) { for (int j = 0; j < promotions[i].RuleCount; j++) { writer.Write(Reinterpret.Object <Promotion.Rule>(promotionRules[i][j])); } for (int j = 0; j < promotions[i].TimerCount; j++) { writer.Write(Reinterpret.Object <Promotion.Timer>(promotionTimers[i][j])); } } for (int i = 0; i < extraInfos.Count; i++) { for (int j = 0; j < extraInfos[i].ResourceBlock.RawSize; j++) { writer.Write(extraInfoData[i][j]); } for (int j = 0; j < extraInfos[i].ResourceBlock.ResourceCount; j++) { writer.Write(Reinterpret.Object <ResourceBlock.Resource>(extraInfoResources[i][j])); } } }
internal RiffBlock(byte[] resourceData, string fourcc) { data = resourceData; header = new RiffBlockHeader(Reinterpret.FourCC(fourcc, ByteOrder.BigEndian), data.Length); }
internal void Write(Stream stream) { byte[] buffer = Reinterpret.Object(header); stream.Write(buffer, 0, buffer.Length); stream.Write(data, 0, header.Length); }
/// <summary> /// Creates an empty RIFF container file. /// </summary> /// <param name="type">a fourcc typecode to embed in the header</param> public RIFF(string type) { header = new RiffHeader(Reinterpret.FourCC(type, ByteOrder.BigEndian)); blocks = new List <RiffBlock>(); }
private void FlushHeader() { map.Position = 0; writer.Write(Reinterpret.Object <MapHeader>(header)); }
public void Load(string file) { filename = file; string directory = Path.GetDirectoryName(file) + '\\'; #region open maps shared = new SharedMaps(new FileStream(directory + MainMenu, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), new FileStream(directory + Shared, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), new FileStream(directory + SinglePlayerShared, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); map = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); reader = new BinaryReader(map); writer = new BinaryWriter(map); #endregion #region header and index header = Reinterpret.Memory <MapHeader>(reader.ReadBytes(Marshal.SizeOf(typeof(MapHeader)))); map.Position = header.IndexOffset; index = Reinterpret.Memory <IndexHeader>(reader.ReadBytes(Marshal.SizeOf(typeof(IndexHeader)))); magic = (index.MagicConstant - header.IndexOffset - Marshal.SizeOf(typeof(IndexHeader))) + (header.AllExceptRawLength - header.IndexAndMetaLength - header.IndexLength); // each "TagType" is three dwords map.Position += 12 * index.TagTypeCount; tags = new List <IndexElement>(index.TagCount); for (int i = 0; i < index.TagCount; i++) { tags.Add(Reinterpret.Memory <IndexElement>(reader.ReadBytes(Marshal.SizeOf(typeof(IndexElement))))); } #endregion #region bsps int bspCount = 0; int bspOffset = 0; if (header.HeadSignature == HeadSignature) { map.Position = 528 + unchecked (tags[LocateTagByID(index.ScenarioIdentifier)].Offset - magic); bspCount = reader.ReadInt32(); bspOffset = unchecked (reader.ReadInt32() - magic); bsps = new Bsp[bspCount]; for (int i = 0; i < bspCount; i++) { bsps[i] = new Bsp(); map.Position = bsps[i].LocationInScenario = bspOffset + 68 * i; bsps[i].BspHeaderOffset = reader.ReadInt32(); int totalBspSize = reader.ReadInt32(); bsps[i].Magic = reader.ReadInt32(); map.Position += 8; bsps[i].BspID = reader.ReadInt32(); map.Position += 4; bsps[i].LightmapID = reader.ReadInt32(); /* * HEADER FORMAT * total size * pointer to bsp location * pointer to lightmap location * 'sbsp' */ map.Position = bsps[i].BspHeaderOffset; int inHeaderBspSize = reader.ReadInt32(); int inHeaderBspOffset = reader.ReadInt32(); int lightmapOffset = reader.ReadInt32(); bsps[i].BspOffset = (inHeaderBspOffset - bsps[i].Magic) + bsps[i].BspHeaderOffset; if (bsps[i].LightmapID == -1) { bsps[i].BspSize = inHeaderBspSize; } else { bsps[i].LightmapOffset = unchecked (lightmapOffset - bsps[i].Magic) + bsps[i].BspHeaderOffset; bsps[i].BspSize = bsps[i].LightmapOffset - bsps[i].BspOffset; bsps[i].LightmapSize = totalBspSize - bsps[i].BspSize; } } } #endregion #region strings strings = new List <string>(header.StringIdCount); map.Position = header.StringIdTableOffset; for (int i = 0; i < header.StringIdCount; i++) { strings.Add(String.Empty); while (true) { byte character = reader.ReadByte(); if (character == 0) { break; } else { strings[i] += Convert.ToChar(character); } } } string[] stringArray = strings.ToArray(); #endregion #region names map.Position = header.NameTableOffset; names = new List <string>(header.NameTableCount); dictionary = new Dictionary <int, string>(header.NameTableCount); inverseDictionary = new Dictionary <string, int>(header.NameTableCount); for (int i = 0; i < header.NameTableCount; i++) { names.Add(String.Empty); while (true) { byte character = reader.ReadByte(); if (character == 0) { break; } else { names[i] += Convert.ToChar(character); } } string dictionaryName = names[i] + '.' + Singleton <ClassManager> .Instance.GetClassByID(tags[i].Type).Name; dictionary.Add(tags[i].Identifier, dictionaryName); inverseDictionary.Add(dictionaryName, tags[i].Identifier); } #endregion #region globals and coconuts if (header.HeadSignature == HeadSignature) { map.Position = unchecked (tags[LocateTagByID(index.GlobalsIdentifier)].Offset - magic); globals = new Globals(reader); map.Position = unchecked (tags[index.TagCount - 1].Offset - magic); coconuts = new Coconuts(reader, shared, magic, stringArray); } #endregion #region composition if (header.HeadSignature == HeadSignature) { for (int i = 0; i < index.TagCount; i++) { int result; switch (tags[i].Type) { case Animation: map.Position = unchecked (tags[i].Offset - magic); result = Tag.GetFirstInternalResourceOffset(reader, Animation, magic); if (result != -1) { if (result < animationStart || animationStart == -1) { animationStart = result; } } break; case Decorators: map.Position = unchecked (tags[i].Offset - magic); result = Tag.GetFirstInternalResourceOffset(reader, Decorators, magic); if (result != -1) { if (result < decoratorStart || decoratorStart == -1) { decoratorStart = result; } } break; case ParticleModel: map.Position = unchecked (tags[i].Offset - magic); result = Tag.GetFirstInternalResourceOffset(reader, ParticleModel, magic); if (result != -1) { if (result < particleModelStart || particleModelStart == -1) { particleModelStart = result; } } break; case WeatherSystem: map.Position = unchecked (tags[i].Offset - magic); result = Tag.GetFirstInternalResourceOffset(reader, WeatherSystem, magic); if (result != -1) { if (result < weatherStart || weatherStart == -1) { weatherStart = result; } } break; case RenderModel: map.Position = unchecked (tags[i].Offset - magic); result = Tag.GetFirstInternalResourceOffset(reader, RenderModel, magic); if (result != -1) { if (result < modelStart || modelStart == -1) { modelStart = result; } } break; } } // this is (should be anyways) constant soundStart = Marshal.SizeOf(typeof(MapHeader)); // this is a calculated value bitmapStart = header.CrazyDataOffset + header.CrazyDataSize; for (int i = 0; i < bspCount; i++) { Bsp bsp = bsps[i]; if (bsp.BspOffset < bspMetaStart || bspMetaStart == -1) { bspMetaStart = bsp.BspHeaderOffset; } else if (bsp.LightmapOffset < bspMetaStart || bspMetaStart == -1) { bspMetaStart = bsp.BspHeaderOffset; } int result; if (bsp.BspID != -1) { reader.BaseStream.Position = bsp.BspOffset; result = Tag.GetFirstInternalResourceOffset(reader, StructureBsp, bsp.Magic - bsp.BspHeaderOffset); if (result != -1) { if (result < bspRawStart || bspRawStart == -1 && result != -1) { bspRawStart = result; } } } if (bsp.LightmapID != -1) { reader.BaseStream.Position = bsp.LightmapOffset; result = Tag.GetFirstInternalResourceOffset(reader, StructureLightmap, bsp.Magic - bsp.BspHeaderOffset); if (result != -1) { if (result < bspRawStart || bspRawStart == -1) { bspRawStart = result; } } } } foreach (Coconuts.ExtraInfo extraInfo in coconuts.ExtraInfos) { if (extraInfo.ResourceBlock.RawSize > 0) { uint encoded = Conversion.ToUInt(extraInfo.ResourceBlock.RawOffset); if ((encoded & 0xc0000000) == 0) { if (extraInfo.ResourceBlock.RawOffset < coconutsModelStart || coconutsModelStart == -1) { coconutsModelStart = extraInfo.ResourceBlock.RawOffset; } } } } if (bspMetaStart < 0) { bspMetaStart = header.StringIdPaddedOffset; } if (animationStart < 0) { animationStart = bspMetaStart; } if (coconutsModelStart < 0) { coconutsModelStart = animationStart; } if (particleModelStart < 0) { particleModelStart = coconutsModelStart; } if (decoratorStart < 0) { decoratorStart = particleModelStart; } if (weatherStart < 0) { weatherStart = decoratorStart; } if (bspRawStart < 0) { bspRawStart = weatherStart; } if (modelStart < 0) { modelStart = bspRawStart; } // these are all duplicates stringPaddedStart = header.StringIdPaddedOffset; stringIndexStart = header.StringIdIndexOffset; stringTableStart = header.StringIdTableOffset; nameTableStart = header.NameTableOffset; nameIndexStart = header.NameIndexOffset; crazyStart = header.CrazyDataOffset; // this can be calculated a multitude of ways unicodeStart = header.NameIndexOffset + header.NameTableCount * sizeof(int); } #endregion valid = true; }
public static int GetHashCode(float f) { //Reinterpret the floats as ints and get the hash code for them. return(Reinterpret.Get(f)); }
/// <summary> /// Creates a new instance of the Coconuts class and reads its values from a coconuts tag. /// </summary> public Coconuts(BinaryReader reader, SharedMaps maps, int magic, string[] strings) { #region header int playbackCount = reader.ReadInt32(); int playbackOffset = unchecked (reader.ReadInt32() - magic); int scaleCount = reader.ReadInt32(); int scaleOffset = unchecked (reader.ReadInt32() - magic); int nameCount = reader.ReadInt32(); int nameOffset = unchecked (reader.ReadInt32() - magic); int pitchRangeParameterCount = reader.ReadInt32(); int pitchRangeParameterOffset = unchecked (reader.ReadInt32() - magic); int pitchRangeCount = reader.ReadInt32(); int pitchRangeOffset = unchecked (reader.ReadInt32() - magic); int permutationCount = reader.ReadInt32(); int permutationOffset = unchecked (reader.ReadInt32() - magic); int customPlaybackCount = reader.ReadInt32(); int customPlaybackOffset = unchecked (reader.ReadInt32() - magic); int runtimeFlagsCount = reader.ReadInt32(); int runtimeFlagsOffset = unchecked (reader.ReadInt32() - magic); int chunkCount = reader.ReadInt32(); int chunkOffset = unchecked (reader.ReadInt32() - magic); int promotionCount = reader.ReadInt32(); int promotionOffset = unchecked (reader.ReadInt32() - magic); int extraInfoCount = reader.ReadInt32(); int extraInfoOffset = unchecked (reader.ReadInt32() - magic); if (playbackCount > 0) { reader.BaseStream.Position = playbackOffset; } playbackParameters = new List <Playback>(playbackCount); for (int i = 0; i < playbackCount; i++) { playbackParameters.Add(Reinterpret.Memory <Playback>(reader.ReadBytes(Marshal.SizeOf(typeof(Playback))))); } if (scaleCount > 0) { reader.BaseStream.Position = scaleOffset; } scales = new List <Scale>(scaleCount); for (int i = 0; i < scaleCount; i++) { scales.Add(Reinterpret.Memory <Scale>(reader.ReadBytes(Marshal.SizeOf(typeof(Scale))))); } if (nameCount > 0) { reader.BaseStream.Position = nameOffset; } importNames = new List <string>(nameCount); for (int i = 0; i < nameCount; i++) { importNames.Add(strings[reader.ReadInt16()]); reader.BaseStream.Position += 2; } if (pitchRangeParameterCount > 0) { reader.BaseStream.Position = pitchRangeParameterOffset; } pitchRangeParameters = new List <PitchRangeParametersBlock>(pitchRangeParameterCount); for (int i = 0; i < pitchRangeParameterCount; i++) { pitchRangeParameters.Add(Reinterpret.Memory <PitchRangeParametersBlock>(reader.ReadBytes(Marshal.SizeOf(typeof(PitchRangeParametersBlock))))); } if (pitchRangeCount > 0) { reader.BaseStream.Position = pitchRangeOffset; } pitchRanges = new List <PitchRange>(pitchRangeCount); for (int i = 0; i < pitchRangeCount; i++) { pitchRanges.Add(Reinterpret.Memory <PitchRange>(reader.ReadBytes(Marshal.SizeOf(typeof(PitchRange))))); } if (permutationCount > 0) { reader.BaseStream.Position = permutationOffset; } permutations = new List <Permutation>(permutationCount); for (int i = 0; i < permutationCount; i++) { permutations.Add(Reinterpret.Memory <Permutation>(reader.ReadBytes(Marshal.SizeOf(typeof(Permutation))))); } if (customPlaybackCount > 0) { reader.BaseStream.Position = customPlaybackOffset; } customPlaybacks = new List <CustomPlayback>(customPlaybackCount); for (int i = 0; i < customPlaybackCount; i++) { CustomPlayback customPlayback = Reinterpret.Memory <CustomPlayback>(reader.ReadBytes(Marshal.SizeOf(typeof(CustomPlayback)))); unchecked { customPlayback.FilterOffset -= magic; customPlayback.FilterPlaybackParametersOffset -= magic; customPlayback.MixFlagsOffset -= magic; customPlayback.PitchPlaybackParametersOffset -= magic; customPlayback.SoundEffectOffset -= magic; } customPlaybacks.Add(customPlayback); } if (runtimeFlagsCount > 0) { reader.BaseStream.Position = runtimeFlagsOffset; } runtimeFlags = new List <RuntimePermutationFlags>(runtimeFlagsCount); for (int i = 0; i < runtimeFlagsCount; i++) { runtimeFlags.Add(Reinterpret.Memory <RuntimePermutationFlags>(reader.ReadBytes(Marshal.SizeOf(typeof(RuntimePermutationFlags))))); } if (chunkCount > 0) { reader.BaseStream.Position = chunkOffset; } chunks = new List <Chunk>(chunkCount); for (int i = 0; i < chunkCount; i++) { chunks.Add(Reinterpret.Memory <Chunk>(reader.ReadBytes(Marshal.SizeOf(typeof(Chunk))))); } if (promotionCount > 0) { reader.BaseStream.Position = promotionOffset; } promotions = new List <Promotion>(promotionCount); for (int i = 0; i < promotionCount; i++) { Promotion promotion = Reinterpret.Memory <Promotion>(reader.ReadBytes(Marshal.SizeOf(typeof(Promotion)))); unchecked { promotion.RuleOffset -= magic; promotion.TimerOffset -= magic; } promotions.Add(promotion); } if (extraInfoCount > 0) { reader.BaseStream.Position = extraInfoOffset; } extraInfos = new List <ExtraInfo>(extraInfoCount); for (int i = 0; i < extraInfoCount; i++) { ExtraInfo extraInfo = Reinterpret.Memory <ExtraInfo>(reader.ReadBytes(Marshal.SizeOf(typeof(ExtraInfo)))); extraInfo.ResourceBlock.ResourceOffset = unchecked (extraInfo.ResourceBlock.ResourceOffset - magic); extraInfos.Add(extraInfo); } #endregion #region custom playbacks customFilters = new List <List <CustomPlayback.Filter> >(customPlaybackCount); customPitchParameters = new List <List <CustomPlayback.PitchPlaybackParameters> >(customPlaybackCount); for (int i = 0; i < customPlaybackCount; i++) { customFilters.Add(new List <CustomPlayback.Filter>(customPlaybacks[i].FilterCount)); if (customPlaybacks[i].FilterCount > 0) { reader.BaseStream.Position = customPlaybacks[i].FilterOffset; } for (int j = 0; j < customPlaybacks[i].FilterCount; j++) { customFilters[i].Add(Reinterpret.Memory <CustomPlayback.Filter>(reader.ReadBytes(Marshal.SizeOf(typeof(CustomPlayback.Filter))))); } customPitchParameters.Add(new List <CustomPlayback.PitchPlaybackParameters>(customPlaybacks[i].PitchPlaybackParametersCount)); if (customPlaybacks[i].PitchPlaybackParametersCount > 0) { reader.BaseStream.Position = customPlaybacks[i].PitchPlaybackParametersOffset; } for (int j = 0; j < customPlaybacks[i].PitchPlaybackParametersCount; j++) { customPitchParameters[i].Add(Reinterpret.Memory <CustomPlayback.PitchPlaybackParameters>(reader.ReadBytes(Marshal.SizeOf(typeof(CustomPlayback.PitchPlaybackParameters))))); } } #endregion #region promotions promotionRules = new List <List <Promotion.Rule> >(promotionCount); promotionTimers = new List <List <Promotion.Timer> >(promotionCount); for (int i = 0; i < promotionCount; i++) { promotionRules.Add(new List <Promotion.Rule>(promotions[i].RuleCount)); if (promotions[i].RuleCount > 0) { reader.BaseStream.Position = promotions[i].RuleOffset; } for (int j = 0; j < promotions[i].RuleCount; j++) { promotionRules[i].Add(Reinterpret.Memory <Promotion.Rule>(reader.ReadBytes(Marshal.SizeOf(typeof(Promotion.Rule))))); } promotionTimers.Add(new List <Promotion.Timer>(promotions[i].TimerCount)); if (promotions[i].TimerCount > 0) { reader.BaseStream.Position = promotions[i].TimerOffset; } for (int j = 0; j < promotions[i].TimerCount; j++) { promotionTimers[i].Add(Reinterpret.Memory <Promotion.Timer>(reader.ReadBytes(Marshal.SizeOf(typeof(Promotion.Timer))))); } } #endregion #region extra infos extraInfoData = new List <byte[]>(extraInfoCount); extraInfoResources = new List <List <ResourceBlock.Resource> >(extraInfoCount); for (int i = 0; i < extraInfoCount; i++) { extraInfoData.Add(new byte[extraInfos[i].ResourceBlock.RawSize]); if (extraInfos[i].ResourceBlock.RawSize > 0) { BinaryReader rawReader = maps.GetMap(extraInfos[i].ResourceBlock.RawOffset, reader); if (rawReader != null) { for (int j = 0; j < extraInfos[i].ResourceBlock.RawSize; j++) { extraInfoData[i][j] = rawReader.ReadByte(); } } extraInfoResources.Add(new List <ResourceBlock.Resource>(extraInfos[i].ResourceBlock.ResourceCount)); if (extraInfos[i].ResourceBlock.ResourceCount > 0) { reader.BaseStream.Position = extraInfos[i].ResourceBlock.ResourceOffset; } for (int j = 0; j < extraInfos[i].ResourceBlock.ResourceCount; j++) { extraInfoResources[i].Add(Reinterpret.Memory <ResourceBlock.Resource>(reader.ReadBytes(Marshal.SizeOf(typeof(ResourceBlock.Resource))))); } } } #endregion }
public void WriteToMapStream(BinaryWriter writer, IList <string> strings, int magic) { int currentEnd; unchecked { magic += (int)writer.BaseStream.Position; currentEnd = MetaRootSize + magic; } // tier 0 writer.Write(playbackParameters.Count); writer.Write(currentEnd); currentEnd += playbackParameters.Count * Marshal.SizeOf(typeof(Playback)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); writer.Write(scales.Count); writer.Write(currentEnd); currentEnd += scales.Count * Marshal.SizeOf(typeof(Scale)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); writer.Write(importNames.Count); writer.Write(currentEnd); currentEnd += importNames.Count * Marshal.SizeOf(typeof(ImportName)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); writer.Write(pitchRangeParameters.Count); writer.Write(currentEnd); currentEnd += pitchRangeParameters.Count * Marshal.SizeOf(typeof(PitchRangeParametersBlock)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); writer.Write(pitchRanges.Count); writer.Write(currentEnd); currentEnd += pitchRanges.Count * Marshal.SizeOf(typeof(PitchRange)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); writer.Write(permutations.Count); writer.Write(currentEnd); currentEnd += permutations.Count * Marshal.SizeOf(typeof(Permutation)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); writer.Write(customPlaybacks.Count); writer.Write(currentEnd); currentEnd += customPlaybacks.Count * Marshal.SizeOf(typeof(CustomPlayback)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); writer.Write(runtimeFlags.Count); writer.Write(currentEnd); currentEnd += runtimeFlags.Count * Marshal.SizeOf(typeof(RuntimePermutationFlags)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); writer.Write(chunks.Count); writer.Write(currentEnd); currentEnd += chunks.Count * Marshal.SizeOf(typeof(Chunk)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); writer.Write(promotions.Count); writer.Write(currentEnd); currentEnd += promotions.Count * Marshal.SizeOf(typeof(Promotion)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); writer.Write(extraInfos.Count); writer.Write(currentEnd); currentEnd += extraInfos.Count * Marshal.SizeOf(typeof(ExtraInfo)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); // tier 1 for (int i = 0; i < playbackParameters.Count; i++) { writer.Write(Reinterpret.Object <Playback>(playbackParameters[i])); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); for (int i = 0; i < scales.Count; i++) { writer.Write(Reinterpret.Object <Scale>(scales[i])); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); for (int i = 0; i < importNames.Count; i++) { ImportName importName = new ImportName(); short index = (short)strings.IndexOf(importNames[i]); if (index >= 0) { importName.Index = index; importName.Size = (byte)importNames[i].Length; } writer.Write(Reinterpret.Object <ImportName>(importName)); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); for (int i = 0; i < pitchRangeParameters.Count; i++) { writer.Write(Reinterpret.Object <PitchRangeParametersBlock>(pitchRangeParameters[i])); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); for (int i = 0; i < pitchRanges.Count; i++) { writer.Write(Reinterpret.Object <PitchRange>(pitchRanges[i])); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); for (int i = 0; i < permutations.Count; i++) { writer.Write(Reinterpret.Object <Permutation>(permutations[i])); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); for (int i = 0; i < customPlaybacks.Count; i++) { CustomPlayback customPlayback = customPlaybacks[i]; if (customPlayback.FilterCount > 0) { customPlayback.FilterOffset = currentEnd; currentEnd += customPlayback.FilterCount * Marshal.SizeOf(typeof(CustomPlayback.Filter)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); } else { customPlayback.FilterOffset = 0; } if (customPlayback.PitchPlaybackParametersCount > 0) { customPlayback.PitchPlaybackParametersOffset = currentEnd; currentEnd += customPlayback.PitchPlaybackParametersCount * Marshal.SizeOf(typeof(CustomPlayback.PitchPlaybackParameters)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); } else { customPlayback.PitchPlaybackParametersOffset = 0; } writer.Write(Reinterpret.Object <CustomPlayback>(customPlayback)); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); for (int i = 0; i < runtimeFlags.Count; i++) { writer.Write(Reinterpret.Object <RuntimePermutationFlags>(runtimeFlags[i])); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); for (int i = 0; i < chunks.Count; i++) { writer.Write(Reinterpret.Object <Chunk>(chunks[i])); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); for (int i = 0; i < promotions.Count; i++) { Promotion promotion = promotions[i]; if (promotion.RuleCount > 0) { promotion.RuleOffset = currentEnd; currentEnd += promotion.RuleCount * Marshal.SizeOf(typeof(Promotion.Rule)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); } else { promotion.RuleOffset = 0; } if (promotion.TimerCount > 0) { promotion.TimerOffset = currentEnd; currentEnd += promotion.TimerCount * Marshal.SizeOf(typeof(Promotion.Timer)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); } else { promotion.TimerOffset = 0; } writer.Write(Reinterpret.Object <Promotion>(promotion)); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); for (int i = 0; i < extraInfos.Count; i++) { ExtraInfo extraInfo = extraInfos[i]; if (extraInfo.ResourceBlock.ResourceCount > 0) { extraInfo.ResourceBlock.ResourceOffset = currentEnd; currentEnd += extraInfo.ResourceBlock.ResourceCount * Marshal.SizeOf(typeof(ResourceBlock.Resource)); currentEnd = Alignment.Align(currentEnd, AlignmentConstants.BlockAlignment); } else { extraInfo.ResourceBlock.ResourceOffset = 0; } writer.Write(Reinterpret.Object <ExtraInfo>(extraInfo)); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); // tier 2 for (int i = 0; i < customPlaybacks.Count; i++) { for (int j = 0; j < customPlaybacks[i].FilterCount; j++) { writer.Write(Reinterpret.Object <CustomPlayback.Filter>(customFilters[i][j])); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); for (int j = 0; j < customPlaybacks[i].PitchPlaybackParametersCount; j++) { writer.Write(Reinterpret.Object <CustomPlayback.PitchPlaybackParameters>(customPitchParameters[i][j])); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); } for (int i = 0; i < promotions.Count; i++) { for (int j = 0; j < promotions[i].RuleCount; j++) { writer.Write(Reinterpret.Object <Promotion.Rule>(promotionRules[i][j])); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); for (int j = 0; j < promotions[i].TimerCount; j++) { writer.Write(Reinterpret.Object <Promotion.Timer>(promotionTimers[i][j])); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); } for (int i = 0; i < extraInfos.Count; i++) { for (int j = 0; j < extraInfos[i].ResourceBlock.ResourceCount; j++) { writer.Write(Reinterpret.Object <ResourceBlock.Resource>(extraInfoResources[i][j])); } writer.BaseStream.Position = Alignment.Align((int)writer.BaseStream.Position, AlignmentConstants.BlockAlignment); } }