Ejemplo n.º 1
0
        private void BitmapTagGroup_CreateResources(ITagGroup guerillaTagGroup, IndexEntry entry, BinaryWriter writer, ref TagGroupHeader header)
        {
            List <long>   addresses = new List <long>();
            List <byte[]> buffers   = new List <byte[]>();

            foreach (ITagBlock bitmapData in ((BlockField)guerillaTagGroup[0][29]).BlockList)
            {
                using (MemoryStream ms = new MemoryStream((byte[])bitmapData[12].Value))
                    using (BinaryReader reader = new BinaryReader(ms))
                    {
                        for (int i = 0; i < 3; i++)
                        {
                            int address = reader.ReadInt32();
                            if (entry.Resources.TryGetResource(address, out var resource))
                            {
                                header.TagResourceCount++;
                                addresses.Add(address);
                                buffers.Add(resource.GetBuffer());
                            }
                        }
                    }
            }

            if (header.TagResourceCount > 0)
            {
                header.RawOffsetsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write((int)addresses[i]);
                }

                header.RawLengthsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i].Length);
                }

                header.RawDataOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i]);
                }
            }
        }
Ejemplo n.º 2
0
        private void Map_Decompile(object state)
        {
            Console.WriteLine($"Decompiling {map.Name}...");
            Group      globalsGroup;
            Group      soundGestaltGroup = null;
            IndexEntry soundGestalt      = null;
            IndexEntry globals           = map.Globals;

            try
            {
                using (var tagReader = globals.Data.GetVirtualStream().CreateReader())
                {
                    tagReader.BaseStream.Seek(globals.Address, SeekOrigin.Begin);
                    globalsGroup = TagLookup.CreateTagGroup(globals.Root);
                    globalsGroup.Read(tagReader);

                    BlockField soundGlobalsTagBlock = (BlockField)globalsGroup.TagBlocks[0].Fields[4];
                    if (soundGlobalsTagBlock.BlockList.Count > 0)
                    {
                        TagId soundGestaltId = (TagId)soundGlobalsTagBlock.BlockList[0].Fields[4].Value;
                        soundGestalt = map.IndexEntries[soundGestaltId];
                        soundGlobalsTagBlock.BlockList[0].Fields[4].Value = (int)TagId.Null;
                    }
                }

                if (soundGestalt != null)
                {
                    using (BinaryReader reader = soundGestalt.Data.GetVirtualStream().CreateReader())
                    {
                        soundGestaltGroup = TagLookup.CreateTagGroup(soundGestalt.Root);
                        reader.BaseStream.Seek(soundGestalt.Address, SeekOrigin.Begin);
                        soundGestaltGroup.Read(reader);
                    }
                }

                int   num    = 0;
                float total  = map.IndexEntries.Count;
                var   result = Parallel.ForEach(map.IndexEntries, entry =>
                {
                    num++;
                    Group guerillaTagGroup;
                    var tagGroup = TagLookup.CreateTagGroup(entry.Root);
                    var reader   = entry.Data.GetVirtualStream().CreateReader();
                    reader.BaseStream.Seek(entry.Address, SeekOrigin.Begin);
                    try { tagGroup.Read(reader); }
                    finally { guerillaTagGroup = Convert.ToGuerilla(tagGroup, soundGestaltGroup, entry, map); }

                    string localFileName    = Path.Combine($"{entry.Filename}.{guerillaTagGroup.GroupName}");
                    string tagGroupFileName = Path.Combine(OutputDirectory, localFileName);

                    if (!Directory.Exists(Path.GetDirectoryName(tagGroupFileName)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(tagGroupFileName));
                    }

                    TagGroupHeader header = new TagGroupHeader();
                    using (FileStream fs = new FileStream(tagGroupFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
                        using (BinaryReader fileReader = new BinaryReader(fs))
                            using (BinaryWriter fileWriter = new BinaryWriter(fs))
                            {
                                fs.Seek(TagGroupHeader.Size, SeekOrigin.Begin);
                                guerillaTagGroup.Write(fileWriter);

                                switch (guerillaTagGroup.GroupTag)
                                {
                                case "snd!":
                                    SoundTagGroup_CreateResources(guerillaTagGroup, soundGestalt, fileWriter, ref header);
                                    break;

                                case "mode":
                                    RenderModelTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header);
                                    break;

                                case "sbsp":
                                    ScenarioStructureBspTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header);
                                    break;

                                case "ltmp":
                                    ScenarioStructureLightmapTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header);
                                    break;

                                case "weat":
                                    WeatherSystemTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header);
                                    break;

                                case "DECR":
                                    DecoratorSetTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header);
                                    break;

                                case "PRTM":
                                    ParticleModelTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header);
                                    break;

                                case "jmad":
                                    AnimationTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header);
                                    break;

                                case "bitm":
                                    BitmapTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header);
                                    break;
                                }

                                header.Checksum = (uint)TagGroup_CalculateChecksum(guerillaTagGroup);
                                header.GroupTag = guerillaTagGroup.GroupTag.FourCc;
                                header.Id       = entry.Id.Dword;
                                header.AbideTag = "atag";

                                fs.Seek(0, SeekOrigin.Begin);
                                fileWriter.Write(header);
                                Host.Report(num / total);
                            }
                });
            }
            catch
            {
#if DEBUG
                throw;
#endif
            }
            finally
            {
                GC.Collect();
            }

            Host.Report(1);
            Thread.Sleep(500);
            Host.Complete();
        }
Ejemplo n.º 3
0
        private void ParticleModelTagGroup_CreateResources(ITagGroup guerillaTagGroup, IndexEntry entry, BinaryWriter writer, ref TagGroupHeader header)
        {
            List <long>   addresses = new List <long>();
            List <byte[]> buffers   = new List <byte[]>();

            ITagBlock geometry = (ITagBlock)guerillaTagGroup[0][22].Value;
            int       address  = (int)geometry[1].Value;

            if (entry.Resources.TryGetResource(address, out var resource))
            {
                header.TagResourceCount++;
                addresses.Add(address);
                buffers.Add(resource.GetBuffer());
            }

            if (header.TagResourceCount > 0)
            {
                header.RawOffsetsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write((int)addresses[i]);
                }

                header.RawLengthsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i].Length);
                }

                header.RawDataOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i]);
                }
            }
        }
Ejemplo n.º 4
0
        private void AnimationTagGroup_CreateResources(ITagGroup guerillaTagGroup, IndexEntry entry, BinaryWriter writer, ref TagGroupHeader header)
        {
            List <long>   addresses = new List <long>();
            List <byte[]> buffers   = new List <byte[]>();

            foreach (ITagBlock animationData in ((BlockField)guerillaTagGroup[0][6]).BlockList)
            {
                int address = (int)animationData[2].Value;
                if (entry.Resources.TryGetResource(address, out var resource))
                {
                    header.TagResourceCount++;
                    addresses.Add(address);
                    buffers.Add(resource.GetBuffer());
                }
            }

            if (header.TagResourceCount > 0)
            {
                header.RawOffsetsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write((int)addresses[i]);
                }

                header.RawLengthsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i].Length);
                }

                header.RawDataOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i]);
                }
            }
        }
Ejemplo n.º 5
0
        private void WeatherSystemTagGroup_CreateResources(ITagGroup guerillaTagGroup, IndexEntry entry, BinaryWriter writer, ref TagGroupHeader header)
        {
            List <long>   addresses = new List <long>();
            List <byte[]> buffers   = new List <byte[]>();

            // TODO: get weather system resources
            foreach (ITagBlock lightmapGeometrySectionBlock in ((BlockField)guerillaTagGroup[0][0]).BlockList)
            {
                ITagBlock geometry = (ITagBlock)lightmapGeometrySectionBlock[1].Value;
                int       address  = (int)geometry[1].Value;

                if (entry.Resources.TryGetResource(address, out var resource))
                {
                    header.TagResourceCount++;
                    addresses.Add(address);
                    buffers.Add(resource.GetBuffer());
                }
            }

            if (header.TagResourceCount > 0)
            {
                header.RawOffsetsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write((int)addresses[i]);
                }

                header.RawLengthsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i].Length);
                }

                header.RawDataOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i]);
                }
            }
        }
Ejemplo n.º 6
0
        private void ScenarioStructureLightmapTagGroup_CreateResources(ITagGroup guerillaTagGroup, IndexEntry entry, BinaryWriter writer, ref TagGroupHeader header)
        {
            List <long>   addresses = new List <long>();
            List <byte[]> buffers   = new List <byte[]>();

            foreach (ITagBlock structureLightmapGroup in ((BlockField)guerillaTagGroup[0][16]).BlockList)
            {
                foreach (ITagBlock cluster in ((BlockField)structureLightmapGroup[6]).BlockList)
                {
                    ITagBlock geometry = (ITagBlock)cluster[1].Value;
                    int       address  = (int)geometry[1].Value;

                    if (entry.Resources.TryGetResource(address, out var resource))
                    {
                        header.TagResourceCount++;
                        addresses.Add(address);
                        buffers.Add(resource.GetBuffer());
                    }
                }

                foreach (ITagBlock lightmapGeometrySectionBlock in ((BlockField)structureLightmapGroup[8]).BlockList)
                {
                    ITagBlock geometry = (ITagBlock)lightmapGeometrySectionBlock[1].Value;
                    int       address  = (int)geometry[1].Value;

                    if (entry.Resources.TryGetResource(address, out var resource))
                    {
                        header.TagResourceCount++;
                        addresses.Add(address);
                        buffers.Add(resource.GetBuffer());
                    }
                }

                foreach (ITagBlock lightmapVertexBufferBucket in ((BlockField)structureLightmapGroup[10]).BlockList)
                {
                    ITagBlock geometry = (ITagBlock)lightmapVertexBufferBucket[3].Value;
                    int       address  = (int)geometry[1].Value;

                    if (entry.Resources.TryGetResource(address, out var resource))
                    {
                        header.TagResourceCount++;
                        addresses.Add(address);
                        buffers.Add(resource.GetBuffer());
                    }
                }
            }

            if (header.TagResourceCount > 0)
            {
                header.RawOffsetsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write((int)addresses[i]);
                }

                header.RawLengthsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i].Length);
                }

                header.RawDataOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i]);
                }
            }
        }
Ejemplo n.º 7
0
        private void ScenarioStructureBspTagGroup_CreateResources(ITagGroup guerillaTagGroup, IndexEntry entry, BinaryWriter writer, ref TagGroupHeader header)
        {
            List <long>   addresses = new List <long>();
            List <byte[]> buffers   = new List <byte[]>();

            foreach (ITagBlock structureBspCluster in ((BlockField)guerillaTagGroup[0][19]).BlockList)
            {
                ITagBlock geometry = (ITagBlock)structureBspCluster[1].Value;
                int       address  = (int)geometry[1].Value;

                if (entry.Resources.TryGetResource(address, out var resource))
                {
                    header.TagResourceCount++;
                    addresses.Add(address);
                    buffers.Add(resource.GetBuffer());
                }
            }

            foreach (ITagBlock structureBspInstancedGeometryDefinition in ((BlockField)guerillaTagGroup[0][39]).BlockList)
            {
                ITagBlock renderInfo = (ITagBlock)structureBspInstancedGeometryDefinition[0].Value;
                ITagBlock geometry   = (ITagBlock)renderInfo[1].Value;
                int       address    = (int)geometry[1].Value;

                if (entry.Resources.TryGetResource(address, out var resource))
                {
                    header.TagResourceCount++;
                    addresses.Add(address);
                    buffers.Add(resource.GetBuffer());
                }
            }

            foreach (ITagBlock structureBspWaterDefinition in ((BlockField)guerillaTagGroup[0][50]).BlockList)
            {
                ITagBlock geometry = (ITagBlock)structureBspWaterDefinition[2].Value;
                int       address  = (int)geometry[1].Value;

                if (entry.Resources.TryGetResource(address, out var resource))
                {
                    header.TagResourceCount++;
                    addresses.Add(address);
                    buffers.Add(resource.GetBuffer());
                }
            }

            foreach (ITagBlock decoratorPlacementDefinition in ((BlockField)guerillaTagGroup[0][54]).BlockList)
            {
                foreach (ITagBlock decoratorCacheBlock in ((BlockField)decoratorPlacementDefinition[2]).BlockList)
                {
                    ITagBlock geometry = (ITagBlock)decoratorCacheBlock[0].Value;
                    int       address  = (int)geometry[1].Value;

                    if (entry.Resources.TryGetResource(address, out var resource))
                    {
                        header.TagResourceCount++;
                        addresses.Add(address);
                        buffers.Add(resource.GetBuffer());
                    }
                }
            }

            if (header.TagResourceCount > 0)
            {
                header.RawOffsetsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write((int)addresses[i]);
                }

                header.RawLengthsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i].Length);
                }

                header.RawDataOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i]);
                }
            }
        }
Ejemplo n.º 8
0
        private void SoundTagGroup_CreateResources(ITagGroup tagGroup, IndexEntry entry, BinaryWriter writer, ref TagGroupHeader header)
        {
            List <long>   addresses = new List <long>();
            List <byte[]> buffers   = new List <byte[]>();

            foreach (ITagBlock pitchRange in ((BlockField)tagGroup[0][13]).BlockList)
            {
                foreach (ITagBlock permutation in ((BlockField)pitchRange[7]).BlockList)
                {
                    foreach (ITagBlock chunk in ((BlockField)permutation[6]).BlockList)
                    {
                        int address = (int)chunk[0].Value;

                        if (entry.Resources.TryGetResource(address, out var resource))
                        {
                            header.TagResourceCount++;
                            addresses.Add(address);
                            buffers.Add(resource.GetBuffer());
                        }
                        else if ((address & 0xC0000000) == 0)
                        {
                            System.Diagnostics.Debugger.Break();
                        }
                    }
                }
            }

            foreach (ITagBlock extraInfo in ((BlockField)tagGroup[0][15]).BlockList)
            {
                ITagBlock geometry = (ITagBlock)extraInfo[2].Value;
                int       address  = (int)geometry[1].Value;

                if (entry.Resources.TryGetResource(address, out var resource))
                {
                    header.TagResourceCount++;
                    addresses.Add(address);
                    buffers.Add(resource.GetBuffer());
                }
            }

            if (header.TagResourceCount > 0)
            {
                header.RawOffsetsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write((int)addresses[i]);
                }

                header.RawLengthsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i].Length);
                }

                header.RawDataOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i]);
                }
            }
        }
Ejemplo n.º 9
0
        private void RenderModelTagGroup_CreateRaws(ITagGroup guerillaTagGroup, IndexEntry entry, BinaryWriter writer, ref TagGroupHeader header)
        {
            List <long>   addresses = new List <long>();
            List <byte[]> buffers   = new List <byte[]>();

            foreach (ITagBlock section in ((BlockField)guerillaTagGroup[0][7]).BlockList)
            {
                ITagBlock geometry = (ITagBlock)section[6].Value;
                int       address  = (int)geometry[1].Value;

                if (entry.Resources.TryGetResource(address, out var resource))
                {
                    header.TagResourceCount++;
                    addresses.Add(address);
                    buffers.Add(resource.GetBuffer());
                }
            }

            foreach (ITagBlock prtInfo in ((BlockField)guerillaTagGroup[0][24]).BlockList)
            {
                ITagBlock geometry = (ITagBlock)prtInfo[13].Value;
                int       address  = (int)geometry[1].Value;

                if (entry.Resources.TryGetResource(address, out var resource))
                {
                    header.TagResourceCount++;
                    addresses.Add(address);
                    buffers.Add(resource.GetBuffer());
                }
            }

            if (header.TagResourceCount > 0)
            {
                header.RawOffsetsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write((int)addresses[i]);
                }

                header.RawLengthsOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i].Length);
                }

                header.RawDataOffset = (uint)writer.BaseStream.Position;
                for (int i = 0; i < header.TagResourceCount; i++)
                {
                    writer.Write(buffers[i]);
                }
            }
        }