public static void Write(this BinaryWriter bw, StringId stringreference) { bw.Write(stringreference); }
public void CreateCaches(Project project) { #region STAGE ONE - Load Data To Caches #region Load Tags Tags = new List<CompilerTag>(project.SourceFiles.Count); Directory.SetCurrentDirectory(project.SourceDirectory); foreach (string filename in project.SourceFiles) Tags.Add(new CompilerTag(filename)); #endregion Header = new Header() { Type = Header.MapType.Multiplayer, Name = project.Name, Scenario = project.Scenario }; foreach (CompilerTag tag in Tags) { #region Cache StringReference Values StringIDsCache.CacheData(tag); #endregion #region Process Unicode Tags if (tag.Type == "utf8") EnglishUnicodeCache.CacheData(tag, StringIDsCache); #endregion #region Initialize Tag in Filetable and Index TagnameCache.CacheData(tag); IndexCache.CacheData(tag); #endregion #region Cache Resource Data switch (tag.Type) { case "ugh!": SoundCache.CacheData(tag); break; case "mode": ModelCache.CacheData(tag); break; case "sbsp": SbspCache.CacheData(tag); break; case "ltmp": LtmpCache.CacheData(tag); break; case "DECR": DECRCache.CacheData(tag); break; case "weat": WeatherCache.CacheData(tag); break; case "jmad": AnimationCache.CacheData(tag); break; case "bitm": BitmapCache.CacheData(tag); break; } #endregion #region Cache Tag Data switch (tag.Type) { case "sbsp": SbspLtmpMetaCache.CacheData(tag); break; case "ltmp": SbspLtmpMetaCache.CacheData(tag); break; default: MetaCache.CacheData(tag); break; } #endregion } #endregion #region STAGE TWO - Setup And Sort Caches SoundCache.Offset = 2048; ModelCache.Offset = SoundCache.NextOffset; SbspCache.Offset = ModelCache.NextOffset; LtmpCache.Offset = SbspCache.NextOffset; DECRCache.Offset = LtmpCache.NextOffset; WeatherCache.Offset = DECRCache.NextOffset; AnimationCache.Offset = WeatherCache.NextOffset; SbspLtmpMetaCache.Offset = AnimationCache.NextOffset; #region Update Scenario Tag SbspLtmpMetaCache.SetVirtualOffset(IndexCache.NextVirtualOffset); SbspLtmpMetaCache.UpdateScenario(Tags[3]); MetaCache[3] = Tags[3].TagStream.ToArray(); #endregion StringIDsCache.Offset = SbspLtmpMetaCache.NextOffset; TagnameCache.Offset = StringIDsCache.NextOffset; EnglishUnicodeCache.Offset = TagnameCache.NextOffset; BitmapCache.Offset = EnglishUnicodeCache.NextOffset; IndexCache.Offset = BitmapCache.NextOffset; MetaCache.Offset = IndexCache.NextOffset; #region Update Globals with Unicode information BinaryWriter bw = new BinaryWriter(Tags[0].TagStream); Tags[0].TagStream.Seek(400, SeekOrigin.Begin); bw.Write(EnglishUnicodeCache.Values.Count); bw.Write(EnglishUnicodeCache.UnicodeTableLength); bw.Write(EnglishUnicodeCache.UnicodeIndexOffset); bw.Write(EnglishUnicodeCache.UnicodeTableOffset); Tags[0].TagStream.Seek(4, SeekOrigin.Current); for (int i = 0; i < 8; i++) { Tags[0].TagStream.Seek(8, SeekOrigin.Current); bw.Write(new byte[8]); bw.Write(BitmapCache.Offset); bw.Write(BitmapCache.Offset); Tags[0].TagStream.Seek(4, SeekOrigin.Current); } MetaCache[0] = Tags[0].TagStream.ToArray(); #endregion #region Set Virtual Addresses MetaCache.VirtualOffset = SbspLtmpMetaCache.NextVirtualOffset; #endregion #region Update IndexCache SbspLtmpMetaCache.UpdateIndexCache(IndexCache); MetaCache.UpdateIndexCache(IndexCache); #endregion #endregion #region STAGE THREE - Update Meta Values foreach (CompilerTag tag in Tags) { BinaryReader br; MetaCache Cache = null; if (SbspLtmpMetaCache.TagIndexers.Contains(tag.ID)) Cache = SbspLtmpMetaCache; else if (MetaCache.TagIndexers.Contains(tag.ID)) Cache = MetaCache; else throw new Exception(); br = new BinaryReader(Cache.Stream); bw = new BinaryWriter(Cache.Stream); int Index = Cache.TagIndexers.IndexOf(tag.ID); RawCache ResourceCache = null; switch (tag.Type) { case "ugh!": ResourceCache = SoundCache; break; case "mode": ResourceCache = ModelCache; break; case "sbsp": ResourceCache = SbspCache; break; case "ltmp": ResourceCache = LtmpCache; break; case "DECR": ResourceCache = DECRCache; break; case "weat": ResourceCache = WeatherCache; break; case "jmad": ResourceCache = AnimationCache; break; case "bitm": ResourceCache = BitmapCache; break; } #region Update Pointers and Other Values valueCache.Clear(); pointerCache.Clear(); Block block = Blocks.Types[tag.Type]; ProcessBlock(block, 1, 0, tag.TagStream); for (int i = 0; i < pointerCache.Count; i++) { Cache.Stream.Position = Cache.Entries[Index].Offset + pointerCache.Values[i].Offset; int address = br.ReadInt32(); if (address != -1) { Cache.Stream.Seek(-4, SeekOrigin.Current); bw.Write(IndexCache.Entries[tag.ID].Address + address); } } for (int i = 0; i < valueCache.Count; i++) { switch (valueCache.Values[i].Type) { case Value.ValueType.StringId: Cache.Stream.Position = Cache.Entries[Index].Offset + valueCache.Values[i].Offset; int index = br.ReadInt32(); Cache.Stream.Seek(-4, SeekOrigin.Current); StringId strRef = new StringId((short)StringIDsCache.Values.IndexOf(tag.Strings[index]), (sbyte)Encoding.UTF8.GetByteCount(tag.Strings[index])); bw.Write(strRef); break; TagIndex tagIndex; case Value.ValueType.TagId: Cache.Stream.Position = Cache.Entries[Index].Offset + valueCache.Values[i].Offset; index = br.ReadInt32(); if (index == -1) continue; Cache.Stream.Seek(-4, SeekOrigin.Current); tagIndex = IndexCache.Entries[TagnameCache.Tagnames.IndexOf(tag.TagReferences[index])].Index; bw.Write(tagIndex); break; case Value.ValueType.TagReference: Cache.Stream.Position = Cache.Entries[Index].Offset + valueCache.Values[i].Offset + 4; index = br.ReadInt32(); if (index == -1) continue; Cache.Stream.Seek(-8, SeekOrigin.Current); byte[] bytes = Encoding.UTF8.GetBytes(Globals.ReverseString(Sunfish.Index.GetDirtyType(Tag.Path.GetTagType(tag.TagReferences[index])))); bw.Write(bytes, 0, 4); tagIndex = IndexCache.Entries[TagnameCache.Tagnames.IndexOf(tag.TagReferences[index])].Index; bw.Write(tagIndex); break; } } #endregion #region Update Resource Values if (tag.ResourceInformation.Length > 0) { rawCache.Clear(); ProcessBlockRaw(block, 1, 0, tag.TagStream); int ResourceCacheIndex = ResourceCache.TagIDs.IndexOf(tag.ID); int ResourceIndex = 0; for (int i = 0; i < rawCache.Count; i++) { Cache.Stream.Position = Cache.Entries[Index].Offset + rawCache.Values[i].Offset1; int address = br.ReadInt32(); if (!(address == -1 || Globals.IsExternalResource(address))) { Cache.Stream.Seek(-4, SeekOrigin.Current); bw.Write(ResourceCache.Offset + ResourceCache.Tags[ResourceCacheIndex].Offset + tag.ResourceInformation[ResourceIndex].Address); Cache.Stream.Position = Cache.Entries[Index].Offset + rawCache.Values[i].Offset0; bw.Write(tag.ResourceInformation[ResourceIndex].Length); ResourceIndex++; } } } #endregion } #endregion #region STAGE FOUR - Save Caches project.CacheCreationDate = DateTime.Now; SoundCache.Save(Path.Combine(project.BinDirectory, "SOUND_RAW_CACHE.BIN"), project.CacheCreationDate); ModelCache.Save(Path.Combine(project.BinDirectory, "MODEL_RAW_CACHE.BIN"), project.CacheCreationDate); SbspCache.Save(Path.Combine(project.BinDirectory, "STRUCTURE_RAW_CACHE.BIN"), project.CacheCreationDate); LtmpCache.Save(Path.Combine(project.BinDirectory, "LIGHTMAP_RAW_CACHE.BIN"), project.CacheCreationDate); DECRCache.Save(Path.Combine(project.BinDirectory, "DECORATER_RAW_CACHE.BIN"), project.CacheCreationDate); WeatherCache.Save(Path.Combine(project.BinDirectory, "WEATHER_RAW_CACHE.BIN"), project.CacheCreationDate); AnimationCache.Save(Path.Combine(project.BinDirectory, "ANIMATION_RAW_CACHE.BIN"), project.CacheCreationDate); BitmapCache.Save(Path.Combine(project.BinDirectory, "TEXTURE_RAW_CACHE.BIN"), project.CacheCreationDate); StringIDsCache.Save(Path.Combine(project.BinDirectory, "STRINGS_CACHE.BIN"), project.CacheCreationDate); IndexCache.Save(Path.Combine(project.BinDirectory, "INDEX.BIN"), project.CacheCreationDate); TagnameCache.Save(Path.Combine(project.BinDirectory, "TAGNAMES.BIN"), project.CacheCreationDate); EnglishUnicodeCache.Save(Path.Combine(project.BinDirectory, "ENGLISH_UNICODE.BIN"), project.CacheCreationDate); MetaCache.Save(Path.Combine(project.BinDirectory, "META.BIN"), project.CacheCreationDate); SbspLtmpMetaCache.Save(Path.Combine(project.BinDirectory, "STRUCTURE_LIGHTMAP_META.BIN"), project.CacheCreationDate); using (FileStream file = new FileStream(Path.Combine(project.BinDirectory, "HEADER.BIN"), FileMode.Create, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete)) { byte[] buffer = Header.ToByteArray(); file.Write(buffer, 0, buffer.Length); } File.SetLastWriteTime(Path.Combine(project.BinDirectory, "HEADER.BIN"), project.CacheCreationDate); project.Save(); #endregion }