예제 #1
0
 public static void Write(this BinaryWriter bw, StringId stringreference)
 {
     bw.Write(stringreference);
 }
예제 #2
0
        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
        }