示例#1
0
        private void makePatch_Click(object sender, EventArgs e)
        {
            Patch patch = new Patch();
            patch.Name = patchName.Text;
            patch.Description = patchDescription.Text;
            patch.Author = patchAuthor.Text;

            IReader originalReader = new EndianReader(File.OpenRead(unmoddedPath.Text), Endian.BigEndian);
            IReader newReader = new EndianReader(File.OpenRead(moddedPath.Text), Endian.BigEndian);

            ThirdGenVersionInfo version = new ThirdGenVersionInfo(originalReader);
            BuildInfoLoader loader = new BuildInfoLoader(XDocument.Load(@"Formats\SupportedBuilds.xml"), @"Formats\");
            BuildInformation buildInfo = loader.LoadBuild(version.BuildString);
            ThirdGenCacheFile originalFile = new ThirdGenCacheFile(originalReader, buildInfo, version.BuildString);
            ThirdGenCacheFile newFile = new ThirdGenCacheFile(newReader, buildInfo, version.BuildString);

            MetaComparer.CompareMeta(originalFile, originalReader, newFile, newReader, patch);
            LocaleComparer.CompareLocales(originalFile, originalReader, newFile, newReader, patch);

            originalReader.Close();
            newReader.Close();

            IWriter output = new EndianWriter(File.OpenWrite(outPath.Text), Endian.BigEndian);
            AssemblyPatchWriter.WritePatch(patch, output);
            output.Close();

            MessageBox.Show("Done!");
        }
        /// <summary>
        /// Extracts a Wwise OGG and converts it to a "regular" OGG file.
        /// </summary>
        /// <param name="reader">The stream to read from.</param>
        /// <param name="offset">The offset of the data to extract.</param>
        /// <param name="size">The size of the data to extract.</param>
        /// <param name="outPath">The path of the file to save to.</param>
        public static void ExtractWwiseToOGG(EndianReader reader, int offset, int size, string outPath)
        {
            // Just extract the RIFX to a temporary file
            string tempFile = Path.GetTempFileName();

            try
            {
                using (EndianWriter output = new EndianWriter(File.OpenWrite(tempFile), EndianFormat.BigEndian))
                {
                    reader.SeekTo(offset);
                    StreamUtil.Copy(reader, output, size);
                }

                // Run ww2ogg to convert the resulting RIFX to an OGG
                RunProgramSilently("Helpers/ww2ogg.exe",
                    string.Format("\"{0}\" -o \"{1}\" --pcb Helpers/packed_codebooks_aoTuV_603.bin", tempFile, outPath),
                    Directory.GetCurrentDirectory());

                // Run revorb to fix up the OGG
                RunProgramSilently("Helpers/revorb.exe", "\"" + outPath + "\"", Directory.GetCurrentDirectory());
            }
            finally
            {
                // Delete the old RIFX file
                if (File.Exists(tempFile))
                    File.Delete(tempFile);
            }
        }
        public void WriteTo([NotNull] Stream stream)
        {
            if (stream == null) throw new ArgumentNullException(nameof(stream));

            var writer = new EndianWriter(stream, Endianness.BigEndian);
            writer.Write(ChannelIdentifier);
            writer.Write(PaketSequence);
            stream.Write(Data.Array, Data.Offset, Data.Count);
        }
 /// <summary>
 /// Extracts the raw contents of a sound to a file.
 /// </summary>
 /// <param name="reader">The stream to read from.</param>
 /// <param name="offset">The offset of the data to extract.</param>
 /// <param name="size">The size of the data to extract.</param>
 /// <param name="outPath">The path of the file to save to.</param>
 public static void ExtractRaw(EndianReader reader, int offset, int size, string outPath)
 {
     using (EndianWriter output = new EndianWriter(File.OpenWrite(outPath), EndianFormat.BigEndian))
     {
         // Just copy the data over to the output stream
         reader.SeekTo(offset);
         StreamUtil.Copy(reader, output, size);
     }
 }
示例#5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EndianStream"/> class.
        /// </summary>
        /// <param name="stream">The stream to read from and write to.</param>
        /// <param name="endianness">The initial endianness to use when operating on the stream.</param>
        /// <exception cref="System.ArgumentException">Thrown if <paramref name="stream"/> is not both readable and writable.</exception>
        public EndianStream(Stream stream, Endian endianness)
        {
            if (!stream.CanRead || !stream.CanWrite)
                throw new ArgumentException("The input stream must be both readable and writable.");

            _stream = stream;
            _reader = new EndianReader(stream, endianness);
            _writer = new EndianWriter(stream, endianness);
        }
示例#6
0
        public static void Copy(EndianReader input, EndianWriter output)
        {
            const int BufferSize = 0x1000;

            var buffer = new byte[BufferSize];
            int read;

            while ((read = input.ReadBlock(buffer, 0, BufferSize)) > 0)
                output.WriteBlock(buffer, 0, read);
        }
示例#7
0
        /// <summary>
        /// Constructs a new EndianStream based off of a Stream object.
        /// </summary>
        /// <param name="stream">The Stream to use. It must at least be available for reading or writing.</param>
        /// <param name="endianness">The endianness to use when performing I/O operations.</param>
        public EndianStream(Stream stream, Endian endianness)
        {
            _stream = stream;
            if (stream.CanRead)
                _reader = new EndianReader(stream, endianness);
            if (stream.CanWrite)
                _writer = new EndianWriter(stream, endianness);

            if (_reader == null && _writer == null)
                throw new ArgumentException("The input stream cannot be read from or written to.");
        }
示例#8
0
 /// <summary>
 /// Creates a BinaryWriter to write to the stream managed by <paramref name="writer"/>
 /// using the provided Endian setting.  <paramref name="marker"/> is written to the 
 /// stream to mark the Endian setting used.
 /// </summary>
 public static BinaryWriter WriteEndianMarker(this BinaryWriter writer, Endian endian, uint marker)
 {
     BinaryWriter result = writer;
     if (endian != Endian.Native)
     {
         var endianWriter = new EndianWriter(writer) {Endian = endian};
         result = endianWriter;
     }
     writer.Write(marker);
     return result;
 }
        public void WriteTo([NotNull] Stream stream)
        {
            if (stream == null) throw new ArgumentNullException(nameof(stream));

            var writer = new EndianWriter(stream, Endianness.BigEndian);
            writer.Write(ChannelIdentifier);
            writer.Write(CommandIdentifier);
            writer.Write((byte)((PayloadLength >> 8) & 0xFF));
            writer.Write((byte)((PayloadLength >> 0) & 0xFF));
            stream.Write(Data.Array, Data.Offset, Data.Count);
        }
示例#10
0
 /// <exception cref="U2FException"/>
 /// <exception cref="System.IO.IOException"/>
 static void SendResponse(Stream outputStream, byte[] encodedBytes)
 {
     if (encodedBytes.Length > 65535)
     {
         throw new U2FException("Message is too long to be transmitted over this protocol");
     }
     using (var dataOutputStream = new EndianWriter(outputStream, Endianness.BigEndian))
     {
         dataOutputStream.Write((short)encodedBytes.Length);
         dataOutputStream.Write(encodedBytes);
     }
 }
示例#11
0
        public static ArraySegment<byte> EncodeResponse(ApduResponse response)
        {
            var buffer = new byte[response.ResponseData.Count + 2];

            using (var stream = new EndianWriter(new MemoryStream(buffer), Endianness.BigEndian))
            {
                stream.Write(response.ResponseData.Array, response.ResponseData.Offset, response.ResponseData.Count);
                var status = (short)response.Status;
                stream.Write(status);
            }

            return buffer.Segment();
        }
示例#12
0
 public EndianIO(string fileName, EndianType endiantype, bool Open, bool IsNewFile)
 {
     EndianType = endiantype;
     FileName = fileName;
     var mode = IsNewFile ? FileMode.Create : FileMode.Open;
     try
     {
         Stream = new FileStream(FileName, mode);
         Reader = new EndianReader(Stream, EndianType);
         Writer = new EndianWriter(Stream, EndianType);
         if (!Open)
         {
             Close();
         }
     }
     catch
     {
     }
 }
示例#13
0
        public static byte[] BuildBinary(Endianness endianess, params object[] args)
        {
            using (var stream = new MemoryStream(64))
            {
                var writer = new EndianWriter(stream, endianess);

                foreach (var arg in args)
                {
                    var type = arg.GetType();
                    if (type == typeof(uint))
                    {
                        writer.Write((uint)arg);
                    }
                    else if (type == typeof(ushort))
                    {
                        writer.Write((ushort)arg);
                    }
                    else if (type == typeof(byte))
                    {
                        writer.Write((byte)arg);
                    }
                    else if (type == typeof(BytesHolder))
                    {
                        var holder = ((BytesHolder)arg);
                        writer.Write(holder.Bytes);
                    }
                    else if (type == typeof(ArraySegment<byte>))
                    {
                        var segment = (ArraySegment<byte>)arg;
                        writer.Write(segment.Array, segment.Offset, segment.Count);
                    }
                    else if (type == typeof(byte[]))
                    {
                        var array = (byte[])arg;
                        writer.Write(array);
                    }
                }

                return stream.GetBuffer();
            }
        }
示例#14
0
        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                FileStream stream = new FileStream(ofd.FileName, FileMode.Open);
                EndianReader reader = new EndianReader(stream, EndianType.BigEndian);
                EndianWriter writer = new EndianWriter(stream, EndianType.BigEndian);

                int CSum = 0;
                reader.BaseStream.Position = 0xD000;
                for (int i = 0; i < 0x768; i += 4)
                    CSum += reader.ReadInt32();

                writer.Write(CSum);
                writer.Flush();
                writer.Close();
                reader.Close();
                MessageBox.Show("New Checksum: " + CSum.ToString("X2"), "Done!");
            }
        }
示例#15
0
		/// <summary>
		/// Reads a shader from a stream and then serializes it into a byte array which can then be exported.
		/// </summary>
		/// <param name="reader">The stream to read from. It should be positioned at the beginning of the shader pointer.</param>
		/// <param name="type">The type of shader to read.</param>
		/// <returns>
		/// The serialized shader data, or <c>null</c> if reading failed.
		/// </returns>
		public byte[] ExportShader(IReader reader, ShaderType type)
		{
			var info = ReadShaderInfo(reader, type);
			if (info == null)
				return null;

			using (var memStream = new MemoryStream())
			{
				using (var writer = new EndianWriter(memStream, Endian.BigEndian))
				{
					writer.WriteInt32(SerializationMagic);
					writer.WriteByte((byte)type);

					// Write the layout size for compatibility checking when deserializing
					if (type == ShaderType.Pixel)
						writer.WriteInt32(_pixelShaderInfoLayout.Size);
					else
						writer.WriteInt32(_vertexShaderInfoLayout.Size);

					// Write the raw debug info
					reader.SeekTo(info.DebugInfoOffset);
					writer.WriteUInt32(info.DebugInfoSize);
					writer.WriteBlock(reader.ReadBlock((int)info.DebugInfoSize));

					// Write the raw shader data
					var dataOffset = _cacheFile.MetaArea.PointerToOffset(info.DataAddress);
					reader.SeekTo(dataOffset);
					writer.WriteUInt32(info.DataSize);
					writer.WriteBlock(reader.ReadBlock((int)info.DataSize));

					// Create the result from the memory stream's buffer
					var result = new byte[memStream.Length];
					Buffer.BlockCopy(memStream.GetBuffer(), 0, result, 0, (int)memStream.Length);
					return result;
				}
			}
		}
示例#16
0
        public ushort CreateIndexBuffer(RenderGeometryApiResourceDefinition resourceDefinition, Stream outputStream, List <ushort> buffer)
        {
            resourceDefinition.IndexBuffers.Add(new TagStructureReference <IndexBufferDefinition>
            {
                Definition = new IndexBufferDefinition
                {
                    Format = IndexBufferFormat.TriangleStrip,
                    Data   = new TagData
                    {
                        Size     = buffer.Count() * 2,
                        Unused4  = 0,
                        Unused8  = 0,
                        Address  = new CacheAddress(),
                        Unused10 = 0
                    }
                }
            });

            var indexBuffer = resourceDefinition.IndexBuffers.Last().Definition;

            var indexCount = indexBuffer.Data.Size / 2;

            var outIndexStream = new EndianWriter(
                outputStream,
                EndianFormat.LittleEndian);

            StreamUtil.Align(outputStream, 4);
            indexBuffer.Data.Address = new CacheAddress(CacheAddressType.Resource, (int)outputStream.Position);

            for (var j = 0; j < indexCount; j++)
            {
                outIndexStream.Write((short)buffer[j]);
            }

            return((ushort)resourceDefinition.IndexBuffers.IndexOf(resourceDefinition.IndexBuffers.Last()));
        }
        public void SingleMixed(ByteOrder readOrder, ByteOrder writeOrder)
        {
            using (var stream = new MemoryStream())
                using (var reader = new EndianReader(stream, readOrder))
                    using (var writer = new EndianWriter(stream, writeOrder))
                    {
                        var rand = BitConverter.ToSingle(BitConverter.GetBytes(new Random().NextDouble() * uint.MaxValue).Reverse().ToArray(), 0);

                        var bytes = BitConverter.GetBytes((float)rand);
                        Array.Reverse(bytes);

                        writer.Write(float.Epsilon);
                        writer.Write(float.MinValue);
                        writer.Write(float.MaxValue);
                        writer.Write(float.NaN);
                        writer.Write(float.NegativeInfinity);
                        writer.Write(float.PositiveInfinity);
                        writer.Write(rand);

                        Assert.AreEqual(stream.Length, 28);

                        stream.Position = 0;
                        Assert.AreEqual(BitConverter.ToSingle(BitConverter.GetBytes(float.Epsilon).Reverse().ToArray(), 0), reader.PeekSingle());
                        Assert.AreEqual(0, stream.Position);

                        Assert.AreEqual(BitConverter.ToSingle(BitConverter.GetBytes(float.Epsilon).Reverse().ToArray(), 0), reader.ReadSingle());
                        Assert.AreEqual(BitConverter.ToSingle(BitConverter.GetBytes(float.MinValue).Reverse().ToArray(), 0), reader.ReadSingle());
                        Assert.AreEqual(BitConverter.ToSingle(BitConverter.GetBytes(float.MaxValue).Reverse().ToArray(), 0), reader.ReadSingle());
                        Assert.AreEqual(BitConverter.ToSingle(BitConverter.GetBytes(float.NaN).Reverse().ToArray(), 0), reader.ReadSingle());
                        Assert.AreEqual(BitConverter.ToSingle(BitConverter.GetBytes(float.NegativeInfinity).Reverse().ToArray(), 0), reader.ReadSingle());
                        Assert.AreEqual(BitConverter.ToSingle(BitConverter.GetBytes(float.PositiveInfinity).Reverse().ToArray(), 0), reader.ReadSingle());
                        Assert.AreEqual(BitConverter.ToSingle(BitConverter.GetBytes(rand).Reverse().ToArray(), 0), reader.ReadSingle());

                        Assert.AreEqual(reader.BaseStream.Position, stream.Length);
                    }
        }
示例#18
0
        private void WriteTagNamesSection(EndianWriter writer, DataSerializationContext context, TagSerializer serializer)
        {
            //prepare tag names
            var names = new Dictionary <int, string>();

            foreach (var entry in Tags.Index)
            {
                if (entry != null && entry.Name != null)
                {
                    names.Add(entry.Index, entry.Name);
                }
            }

            // create entry and immediatly write the tag names table
            GenericSectionEntry mapEntry = new GenericSectionEntry(names.Count, (int)writer.BaseStream.Position + 0x8);

            mapEntry.Write(writer);

            foreach (var entry in names)
            {
                var tagNameEntry = new ModPackageTagNamesEntry(entry.Key, entry.Value);
                serializer.Serialize(context, tagNameEntry);
            }
        }
示例#19
0
        public override void WriteValue(EndianWriter writer)
        {
            writer.Seek(ValueAddress, SeekOrigin.Begin);

            var parsed = float.Parse(Value.ToString());

            switch (FieldDefinition.ValueType)
            {
            case MetaValueType.SByte: writer.Write((sbyte)parsed); break;

            case MetaValueType.Int16: writer.Write((short)parsed); break;

            case MetaValueType.Int32: writer.Write((int)parsed); break;

            case MetaValueType.Int64: writer.Write((long)parsed); break;

            case MetaValueType.Byte: writer.Write((byte)parsed); break;

            case MetaValueType.UInt16: writer.Write((ushort)parsed); break;

            case MetaValueType.UInt32: writer.Write((uint)parsed); break;

            case MetaValueType.UInt64: writer.Write((ulong)parsed); break;

            case MetaValueType.Angle:
            case MetaValueType.Float32:
                writer.Write((float)parsed); break;

            case MetaValueType.Undefined:
            default:
                writer.Write((int)parsed);
                break;
            }

            IsDirty = false;
        }
示例#20
0
        public void GuidMixed(ByteOrder readOrder, ByteOrder writeOrder)
        {
            using (var stream = new MemoryStream())
                using (var reader = new EndianReader(stream, readOrder))
                    using (var writer = new EndianWriter(stream, writeOrder))
                    {
                        var guidX = new Guid("863b519c-6942-4b65-adfa-55874889fecd");
                        var guidY = new Guid("9c513b86-4269-654b-adfa-55874889fecd");

                        writer.Write(guidX, ByteOrder.LittleEndian);
                        writer.Write(guidY, ByteOrder.LittleEndian);

                        writer.Write(guidX, ByteOrder.BigEndian);
                        writer.Write(guidY, ByteOrder.BigEndian);

                        stream.Position = 0;

                        Assert.AreEqual(guidY, reader.ReadGuid(ByteOrder.BigEndian));
                        Assert.AreEqual(guidX, reader.ReadGuid(ByteOrder.BigEndian));

                        Assert.AreEqual(guidY, reader.ReadGuid(ByteOrder.LittleEndian));
                        Assert.AreEqual(guidX, reader.ReadGuid(ByteOrder.LittleEndian));
                    }
        }
示例#21
0
        public override object Execute(List <string> args)
        {
            string modelFileName;

            if (args.Count == 1)
            {
                modelFileName = args[0];
            }
            else
            {
                return(false);
            }

            if (Definition.Geometry.Resource == null)
            {
                Console.WriteLine("Render model does not have a resource associated with it");
                return(true);
            }

            BlamModelFile geometryFormat = new BlamModelFile();

            using (var stream = Cache.OpenCacheRead())
            {
                var resource = Cache.ResourceCache.GetRenderGeometryApiResourceDefinition(Definition.Geometry.Resource);
                Definition.Geometry.SetResourceBuffers(resource);

                geometryFormat.InitGen3(Cache, Definition);

                using (var modelStream = new FileStream($"{modelFileName}.bmf", FileMode.Create))
                    using (var writer = new EndianWriter(modelStream))
                    {
                        geometryFormat.SerializeToFile(writer);
                    }
            }
            return(true);
        }
示例#22
0
        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                FileStream   stream = new FileStream(ofd.FileName, FileMode.Open);
                EndianReader reader = new EndianReader(stream, EndianType.BigEndian);
                EndianWriter writer = new EndianWriter(stream, EndianType.BigEndian);

                int CSum = 0;
                reader.BaseStream.Position = 0xD000;
                for (int i = 0; i < 0x768; i += 4)
                {
                    CSum += reader.ReadInt32();
                }

                writer.Write(CSum);
                writer.Flush();
                writer.Close();
                reader.Close();
                MessageBox.Show("New Checksum: " + CSum.ToString("X2"), "Done!");
            }
        }
示例#23
0
        public void Enums01(ByteOrder order)
        {
            var rng = new Random();
            var obj = new DataClass12
            {
                Property1 = (Enum01)rng.Next(1, 4),
                Property2 = (Enum02)rng.Next(4, 7),
                Property3 = (Enum03)rng.Next(7, 10),
                Property4 = (Enum04)rng.Next(10, 13),
            };

            using (var stream = new MemoryStream())
                using (var reader = new EndianReader(stream, order))
                    using (var writer = new EndianWriter(stream, order))
                    {
                        writer.WriteObject(obj);

                        stream.Position = 0;
                        Assert.AreEqual((byte)obj.Property1, reader.ReadByte());
                        Assert.AreEqual((short)obj.Property2, reader.ReadInt16());
                        Assert.AreEqual((int)obj.Property3, reader.ReadInt32());
                        Assert.AreEqual((long)obj.Property4, reader.ReadInt64());
                    }
        }
示例#24
0
        /// <summary>
        /// GenerateForBlenderPhmoJson
        /// </summary>
        /// <param name="jsonString">String containing blender exported JSON using the jsonPhmoExporter plugin.</param>
        /// <returns>A memory stream with Havok 6.5.0 moppcode block</returns>
        public static MemoryStream GenerateForBlenderPhmoJson(string jsonString)
        {
            JsonToMopp   jtm        = new JsonToMopp();
            MemoryStream moppStream = jtm.CreateMopp(jsonString);

            moppStream.Position = 0;
            CollisionMoppCode resource = SynthesizeMoppBlock(moppStream);

            MemoryStream outStream = null;

        #if !DEBUG
            try
            {
        #endif
            var resourceWriter = new EndianWriter(new MemoryStream(), EndianFormat.LittleEndian);
            var dataContext    = new DataSerializationContext(null, resourceWriter);
            var block          = dataContext.CreateBlock();
            var info           = TagStructure.GetTagStructureInfo(resource.GetType(), CacheVersion.HaloOnline235640);

            new TagSerializer(CacheVersion.HaloOnline235640).Serialize(dataContext, resource);

            block.Stream.Position = 0;
            outStream             = block.Stream;
        #if !DEBUG
        }
        catch
        {
            return(null);
        }
        #endif

            outStream.Position = 48;      //position of Data member. Data will be inlined
            moppStream.CopyTo(outStream); //remainder of moppStream is mopp program
            outStream.Position = 0;
            return(outStream);            //this is the one with serialized data in it
        }
        public void DataLength01(ByteOrder order)
        {
            var rng = new Random();

            using (var stream = new MemoryStream(new byte[500]))
                using (var reader = new EndianReader(stream, order))
                    using (var writer = new EndianWriter(stream, order))
                    {
                        var obj = new DataClass14
                        {
                            Property1 = 5,
                            Property2 = 100
                        };

                        writer.WriteObject(obj);

                        Assert.AreEqual(100, stream.Position);
                        stream.Position = 0;
                        Assert.AreEqual(5, reader.ReadInt32());
                        Assert.AreEqual(100, reader.ReadInt32());

                        stream.Position = 0;
                        obj             = new DataClass14
                        {
                            Property1 = 7,
                            Property2 = 45
                        };

                        writer.WriteObject(obj);

                        Assert.AreEqual(45, stream.Position);
                        stream.Position = 0;
                        Assert.AreEqual(7, reader.ReadInt32());
                        Assert.AreEqual(45, reader.ReadInt32());
                    }
        }
示例#26
0
		private void WriteDataBlock(DataBlock block, SegmentPointer location, IStream stream, ITag tag = null)
		{
			if (tag == null && _dataBlockAddresses.ContainsKey(block)) // Don't write anything if the block has already been written
				return;

			// Associate the location with the block
			_dataBlockAddresses[block] = location.AsPointer();

			// Create a MemoryStream and write the block data to it (so fixups can be performed before writing it to the file)
			using (var buffer = new MemoryStream(block.Data.Length))
			{
				var bufferWriter = new EndianWriter(buffer, stream.Endianness);
				bufferWriter.WriteBlock(block.Data);

				// Apply fixups
				FixBlockReferences(block, bufferWriter, stream);
				FixTagReferences(block, bufferWriter, stream);
				FixResourceReferences(block, bufferWriter, stream);
				FixStringIdReferences(block, bufferWriter);
				if (tag != null)
					FixUnicListReferences(block, tag, bufferWriter, stream);

				// Write the buffer to the file
				stream.SeekTo(location.AsOffset());
				stream.WriteBlock(buffer.GetBuffer(), 0, (int) buffer.Length);
			}

			// Write shader fixups (they can't be done in-memory because they require cache file expansion)
			FixShaderReferences(block, stream, location);
		}
示例#27
0
        internal void Write(EndianWriter writer)
        {
            uint bindPoint = 0;

            foreach (var bufferParam in shaderSubprogram.BufferParameters)
            {
                //Resource bindings
                //nameOffset
                writer.Write(nameLookup[bufferParam.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.Structured);
                //Resource return type
                writer.Write((uint)ResourceReturnType.Mixed);
                //Resource view dimension
                writer.Write((uint)ShaderResourceViewDimension.Buffer);
                //Number of samples
                writer.Write((uint)56);                 //TODO: Check this
                //Bind point
                writer.Write((uint)bufferParam.Index);
                bindPoint += 1;
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                writer.Write((uint)ShaderInputFlags.None);
            }
            bindPoint = 0;
            foreach (var textureParam in shaderSubprogram.TextureParameters)
            {
                //Resource bindings
                //nameOffset
                writer.Write(nameLookup[textureParam.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.Sampler);
                //Resource return type
                writer.Write((uint)ResourceReturnType.NotApplicable);
                //Resource view dimension
                writer.Write((uint)ShaderResourceViewDimension.Unknown);
                //Number of samples
                writer.Write((uint)0);
                //Bind point
                writer.Write((uint)textureParam.Index);
                bindPoint += 1;
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                writer.Write((uint)ShaderInputFlags.None);
            }
            bindPoint = 0;
            foreach (var textureParam in shaderSubprogram.TextureParameters)
            {
                //Resource bindings
                //nameOffset
                writer.Write(nameLookup[textureParam.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.Texture);
                //Resource return type
                writer.Write((uint)ResourceReturnType.NotApplicable);
                //Resource view dimension
                writer.Write((uint)textureParam.Dim);
                //Number of samples
                writer.Write(uint.MaxValue);
                //Bind point
                writer.Write((uint)textureParam.Index);
                bindPoint += 1;
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                writer.Write((uint)ShaderInputFlags.None);
            }
            bindPoint = 0;
            foreach (var constantBuffer in shaderSubprogram.ConstantBufferBindings)
            {
                //Resource bindings
                //nameOffset
                writer.Write(nameLookup[constantBuffer.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.CBuffer);
                //Resource return type
                writer.Write((uint)ResourceReturnType.NotApplicable);
                //Resource view dimension
                writer.Write((uint)ShaderResourceViewDimension.Unknown);
                //Number of samples
                writer.Write((uint)0);
                //Bind point
                writer.Write((uint)constantBuffer.Index);
                bindPoint += 1;
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                writer.Write((uint)ShaderInputFlags.None);
            }

            foreach (var bufferParam in shaderSubprogram.BufferParameters)
            {
                writer.WriteStringZeroTerm(bufferParam.Name);
            }
            foreach (var textureParam in shaderSubprogram.TextureParameters)
            {
                writer.WriteStringZeroTerm(textureParam.Name);
            }
            foreach (var constantBuffer in shaderSubprogram.ConstantBufferBindings)
            {
                writer.WriteStringZeroTerm(constantBuffer.Name);
            }
        }
示例#28
0
 public override void Write(EndianWriter bw)
 {
     bw.Write(X);
     bw.Write(Y);
 }
示例#29
0
        public void SaveStrings(IStream stream, List<LocalizedString> locales)
        {
            var offsetData = new MemoryStream();
            var stringData = new MemoryStream();
            var offsetWriter = new EndianWriter(offsetData, Endian.BigEndian);
            var stringWriter = new EndianWriter(stringData, Endian.BigEndian);

            try
            {
                // Write the string and offset data to buffers
                foreach (LocalizedString locale in locales)
                {
                    WriteLocalePointer(offsetWriter, locale.Key, (int) stringWriter.Position);
                    stringWriter.WriteUTF8(locale.Value);
                }

                // Round the size of the string data up
                var dataSize = (int) ((stringData.Position + _sizeAlign - 1) & ~(_sizeAlign - 1));
                stringData.SetLength(dataSize);

                // Update the two locale data hashes if we need to
                // (the hash arrays are set to null if the build doesn't need them)
                if (IndexTableHash != null)
                    IndexTableHash = SHA1.Transform(offsetData.GetBuffer(), 0, (int) offsetData.Length);
                if (StringDataHash != null)
                    StringDataHash = SHA1.Transform(stringData.GetBuffer(), 0, dataSize);

                // Make sure there's free space for the offset table and then write it to the file
                LocaleIndexTable.Resize((int) offsetData.Length, stream);
                stream.SeekTo(LocaleIndexTableLocation.AsOffset());
                stream.WriteBlock(offsetData.GetBuffer(), 0, (int) offsetData.Length);

                // Encrypt the string data if necessary
                byte[] strings = stringData.GetBuffer();
                if (_encryptionKey != null)
                    strings = AES.Encrypt(strings, 0, dataSize, _encryptionKey.Key, _encryptionKey.IV);

                // Make sure there's free space for the string data and then write it to the file
                LocaleData.Resize(dataSize, stream);
                stream.SeekTo(LocaleDataLocation.AsOffset());
                stream.WriteBlock(strings, 0, dataSize);

                // Update the string count and recalculate the language table offsets
                StringCount = locales.Count;
            }
            finally
            {
                offsetWriter.Close();
                stringWriter.Close();
            }
        }
示例#30
0
 /// <summary>
 /// Write the chunk to a stream
 /// </summary>
 /// <param name="writer">Output stream</param>
 public virtual void Write(EndianWriter writer)
 {
     writer.WriteUInt16((ushort)((byte)Type | (ushort)(Attributes << 8)));
 }
示例#31
0
 public abstract void WriteValue(EndianWriter writer);
示例#32
0
 public void Open()
 {
     try
     {
         Stream = new FileStream(FileName, FileMode.Open);
         Reader = new EndianReader(Stream, EndianType);
         Writer = new EndianWriter(Stream, EndianType);
     }
     catch
     {
     }
 }
        protected override void LoadResourceData(BlamCacheFile cacheFile, ref Resource resourceRef)
        {
            bool[] convertedVertexBuffers = new bool[100];
            bool[] convertedIndexBuffers  = new bool[100];

            using (EndianWriter writer = new EndianWriter(new MemoryStream(resourceRef.Info), Endian.LittleEndian))
            {
                foreach (ResourceFixup fixup in resourceRef.ResourceFixups)
                {
                    BlamCacheAddress address = new BlamCacheAddress(fixup.Address);
                    writer.SeekTo(fixup.Offset);
                    writer.WriteUInt32(address.Value);
                }
            }

            byte[] primaryResource   = ReadResourcePageData(cacheFile, resourceRef.Location.PrimaryPage);
            byte[] secondaryResource = ReadResourcePageData(cacheFile, resourceRef.Location.SecondaryPage);

            //The using keyword will automatically call IDisposable.Dispose at the end of scope
            //Automatically freeing up our resources and closing our file streams

            using (EndianReader definitionReader = new EndianReader(new MemoryStream(resourceRef.Info), Endian.LittleEndian))
                using (EndianReader primaryReader = new EndianReader(new MemoryStream(primaryResource), Endian.LittleEndian))
                    using (EndianReader secondaryReader = new EndianReader(new MemoryStream(secondaryResource), Endian.LittleEndian))
                    {
                        BlamCacheAddress cacheAddress = new BlamCacheAddress((uint)resourceRef.BaseDefinitionAddress);
                        Logger.AssertMsg(cacheAddress.Type == BlamCacheAddressType.Definition, "INVALID CACHE ADDRESS");
                        definitionReader.SeekTo(cacheAddress.Offset);
                        StructureLayout          layout = cacheFile.GetLayout("render geometry api resource definition");
                        StructureValueCollection values = StructureReader.ReadStructure(definitionReader, layout);

                        //Won't be useless eventually
                        ulong            numberOfUselessCrap3 = values.GetInteger("number of useless crap3");
                        ulong            numberOfUselessCrap4 = values.GetInteger("number of useless crap4");
                        BlamCacheAddress uselessCrap3Address  = new BlamCacheAddress((uint)values.GetInteger("address of useless crap3 table"));
                        BlamCacheAddress uselessCrap4Address  = new BlamCacheAddress((uint)values.GetInteger("address of useless crap4 table"));


                        StructureLayout vertexBufferDefinitionLayout = new StructureLayout();
                        vertexBufferDefinitionLayout.AddBasicField("vertex count", StructureValueType.Int32, 0x0);
                        vertexBufferDefinitionLayout.AddBasicField("vertex format", StructureValueType.Int16, 0x4);
                        vertexBufferDefinitionLayout.AddBasicField("vertex byte size", StructureValueType.Int16, 0x6);
                        vertexBufferDefinitionLayout.AddBasicField("vertex buffer size", StructureValueType.Int32, 0x8);
                        vertexBufferDefinitionLayout.AddBasicField("vertex buffer address", StructureValueType.UInt32, 0x14);
                        //Vertex buffer data should be aligned to 0x4
                        StructureLayout indexBufferDefinitionLayout = new StructureLayout();
                        indexBufferDefinitionLayout.AddBasicField("index format", StructureValueType.Int16, 0x0);

                        //Vertex buffer definitions
                        //All of the vertex buffer definitions exist in a table of D3DPointer container structs
                        //Each D3DPointer contains the address of the contained type (this is the only value we care about)
                        //For example D3DPointer<Float> the first value might be 0x20000000 which would be an address containing some float

                        VertexBufferDefinitions = new BlamD3DPointer <VertexBufferDefinition> [numberOfUselessCrap3];
                        StructureLayout d3dStructureLayout = BlamD3DPointer <VertexBufferDefinition> .Layout();

                        for (int i = 0; i < (int)numberOfUselessCrap3; i++)
                        {
                            //Read each D3DPointer struct (Make a class for this too)
                            long offset   = (i * d3dStructureLayout.Size);
                            long readAddr = uselessCrap3Address.Offset + offset;
                            definitionReader.SeekTo(readAddr);
                            StructureValueCollection d3dStructureValues = StructureReader.ReadStructure(definitionReader, d3dStructureLayout);

                            //Grab the pointer to the contained value (in our case it will be a VertexBufferDefinition)
                            BlamCacheAddress vertexBufferDefinitionAddress = new BlamCacheAddress((uint)d3dStructureValues.GetInteger("address"));
                            Logger.AssertMsg(vertexBufferDefinitionAddress.Type == BlamCacheAddressType.Definition, "Invalid vertex buffer definition address!");

                            //Read our vertex buffer definition (Make a class for this)
                            definitionReader.SeekTo(vertexBufferDefinitionAddress.Offset);
                            StructureValueCollection vertexBufferDefinitionValues = StructureReader.ReadStructure(definitionReader, vertexBufferDefinitionLayout);
                            //Grab our vertex buffer address
                            BlamCacheAddress vertexBufferAddress = new BlamCacheAddress((uint)vertexBufferDefinitionValues.GetInteger("vertex buffer address"));
                            EndianReader     vertexBufferReader  = null;
                            //Determine where to read the vertex data from
                            switch (vertexBufferAddress.Type)
                            {
                            case BlamCacheAddressType.Data: vertexBufferReader = primaryReader; break;

                            case BlamCacheAddressType.SecondaryData: vertexBufferReader = secondaryReader; break;

                            case BlamCacheAddressType.Definition: vertexBufferReader = definitionReader; break;
                            }
                            Logger.AssertMsg(vertexBufferReader != null, "INVALID VERTEX BUFFER ADDRESS");
                            //Need to make a class for this too, BUT the layout depends on what type of vertex it is...
                            //See https://github.com/MadJayQ/MCCEditor/blob/master/Blamite/Formats/Reach/Reach_VertexBuffer.xml
                            //This is for Reach but it's the best we got ATM...
                            StructureLayout vertexBufferLayout = new StructureLayout();
                            vertexBufferLayout.AddBasicField("posX", StructureValueType.Float32, 0x0);
                            vertexBufferLayout.AddBasicField("posY", StructureValueType.Float32, 0x4);
                            vertexBufferLayout.AddBasicField("posZ", StructureValueType.Float32, 0x8);
                            vertexBufferLayout.AddBasicField("posW", StructureValueType.Float32, 0x10);

                            //Read our vertex data buffer block
                            long vertexByteSize        = (long)vertexBufferDefinitionValues.GetInteger("vertex byte size");
                            long vertexBufferTotalSize = (long)vertexBufferDefinitionValues.GetInteger("vertex buffer size");
                            long vertexCount           = (long)vertexBufferDefinitionValues.GetInteger("vertex count");

                            Logger.AssertMsgFormat(vertexBufferTotalSize == (vertexByteSize * vertexCount), "Malformed vertex buffer, vertex byte size and vertex count do not add up to the total vertex buffer size! Total: {0}, Vertex Size: {1}, Vertex Count: {2}", vertexBufferTotalSize, vertexByteSize, vertexCount);

                            vertexBufferReader.SeekTo(vertexBufferAddress.Offset);
                            byte[] vertexBlock = vertexBufferReader.ReadBlock((int)vertexBufferDefinitionValues.GetInteger("vertex buffer size"));
                            using (EndianReader vertexBufferStreamReader = new EndianReader(new MemoryStream(vertexBlock), Endian.LittleEndian))
                            {
                                for (int vertexIdx = 0; vertexIdx < vertexCount; vertexIdx++)
                                {
                                    long vertexBlockOffset = (vertexIdx * vertexByteSize);
                                    StructureValueCollection vertexValues = StructureReader.ReadStructure(vertexBufferStreamReader, vertexBufferLayout);
                                }
                            }
                        }
                        //Index buffer definitions
                        for (int i = 0; i < (int)numberOfUselessCrap4; i++)
                        {
                            long offset   = (i * 0xC);
                            long readAddr = uselessCrap4Address.Offset + offset;
                            definitionReader.SeekTo(readAddr);
                            StructureValueCollection d3dStructureValues = StructureReader.ReadStructure(definitionReader, d3dStructureLayout);

                            BlamCacheAddress indexBufferDefinitionAddress = new BlamCacheAddress((uint)d3dStructureValues.GetInteger("address"));
                            Logger.AssertMsg(indexBufferDefinitionAddress.Type == BlamCacheAddressType.Definition, "Invalid index buffer definition address!");

                            definitionReader.SeekTo(indexBufferDefinitionAddress.Offset);
                            StructureValueCollection indexBufferDefinitionValues = StructureReader.ReadStructure(definitionReader, indexBufferDefinitionLayout);
                        }
                    }
        }
示例#34
0
        private void BasicProjectileSwap(string command)
        {
            command = command.ToLowerInvariant();

            var targetWeaponTag = _tagEntries.FirstOrDefault(t => t.TagClass == "weap" && t.TagAliasNames.Contains("assault rifle"));
            if (targetWeaponTag == null) return;

            var newProjectileTag = _tagEntries.FirstOrDefault(t => t.TagClass == "proj" && t.TagAliasNames.Contains(command));
            if (newProjectileTag == null) return;

            const uint baseOffset = 0xbf126690 + 0x98; // Tag Block Address + Initial Projectile Offset Gain
            var writer = new EndianWriter(_xbdm.MemoryStream, Endian.BigEndian);
            writer.SeekTo(baseOffset);
            writer.WriteUInt32((UInt32) newProjectileTag.Tag.Class.Magic);
            writer.WriteBlock(new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF });
            writer.WriteUInt32(newProjectileTag.Tag.Index.Value);
        }
示例#35
0
 public static void InsertBytes(string filePath, int startOffset, int size)
 {
     var input = new FileStream(filePath, FileMode.Open);
     var er = new EndianReader(input)
     {
         BaseStream = { Position = startOffset }
     };
     var buffer = er.ReadBytes(((int)er.BaseStream.Length) - ((int)er.BaseStream.Position));
     er.Close();
     input.Close();
     input = new FileStream(filePath, FileMode.Open);
     var ew = new EndianWriter(input)
     {
         BaseStream = { Position = startOffset }
     };
     ew.Write(new byte[size]);
     ew.Write(buffer);
     input.Close();
     ew.Close();
 }
示例#36
0
        // Patch Creation
        private void btnCreatePatch_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // Check the user isn't completly retarded
                if (!CheckAllCreateMandatoryFields())
                {
                    return;
                }

                // Check the user isn't a skid
                if (!CheckAllCreateMetaFilesExists())
                {
                    return;
                }

                // Paths
                string cleanMapPath  = txtCreatePatchUnModifiedMap.Text;
                string moddedMapPath = txtCreatePatchModifiedMap.Text;
                string outputPath    = txtCreatePatchOutputPatch.Text;
                string previewImage  = txtCreatePatchPreviewImage.Text;

                // Details
                string author     = txtCreatePatchContentAuthor.Text;
                string desc       = txtCreatePatchContentDescription.Text;
                string name       = txtCreatePatchContentName.Text;
                string outputName = txtCreatePatchOutputName.Text;

                // Make dat patch
                var patch = new Patch
                {
                    Author      = author,
                    Description = desc,
                    Name        = name,
                    OutputName  = outputName,
                    Screenshot  = String.IsNullOrEmpty(previewImage)
                                                ? null
                                                : File.ReadAllBytes(previewImage),
                    BuildString = _buildInfo.Version,
                    PC          = String.IsNullOrEmpty(_buildInfo.GameExecutable)
                                                ? false
                                                : true
                };

                EndianReader originalReader = null;
                EndianReader newReader      = null;
                try
                {
                    originalReader = new EndianReader(File.OpenRead(cleanMapPath), Endian.BigEndian);
                    newReader      = new EndianReader(File.OpenRead(moddedMapPath), Endian.BigEndian);

                    ICacheFile originalFile = CacheFileLoader.LoadCacheFile(originalReader, cleanMapPath,
                                                                            App.AssemblyStorage.AssemblySettings.DefaultDatabase);
                    ICacheFile newFile = CacheFileLoader.LoadCacheFile(newReader, moddedMapPath, App.AssemblyStorage.AssemblySettings.DefaultDatabase);

                    if (cbCreatePatchHasCustomMeta.IsChecked != null && (bool)cbCreatePatchHasCustomMeta.IsChecked &&
                        cboxCreatePatchTargetGame.SelectedIndex < 4)
                    {
                        var      targetGame      = (TargetGame)cboxCreatePatchTargetGame.SelectedIndex;
                        byte[]   mapInfo         = File.ReadAllBytes(txtCreatePatchMapInfo.Text);
                        var      mapInfoFileInfo = new FileInfo(txtCreatePatchMapInfo.Text);
                        FileInfo blfFileInfo;

                        patch.CustomBlfContent = new BlfContent(mapInfoFileInfo.FullName, mapInfo, targetGame);

                        #region Blf Data

                        if (PatchCreationBlfOption0.Visibility == Visibility.Visible)
                        {
                            blfFileInfo = new FileInfo(txtCreatePatchblf0.Text);
                            patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
                                                                                                 File.ReadAllBytes(blfFileInfo.FullName)));
                        }
                        if (PatchCreationBlfOption1.Visibility == Visibility.Visible)
                        {
                            blfFileInfo = new FileInfo(txtCreatePatchblf1.Text);
                            patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
                                                                                                 File.ReadAllBytes(blfFileInfo.FullName)));
                        }
                        if (PatchCreationBlfOption2.Visibility == Visibility.Visible)
                        {
                            blfFileInfo = new FileInfo(txtCreatePatchblf2.Text);
                            patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
                                                                                                 File.ReadAllBytes(blfFileInfo.FullName)));
                        }
                        if (PatchCreationBlfOption3.Visibility == Visibility.Visible)
                        {
                            blfFileInfo = new FileInfo(txtCreatePatchblf3.Text);
                            patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
                                                                                                 File.ReadAllBytes(blfFileInfo.FullName)));
                        }

                        #endregion
                    }

                    PatchBuilder.BuildPatch(originalFile, originalReader, newFile, newReader, patch);
                }
                finally
                {
                    if (originalReader != null)
                    {
                        originalReader.Dispose();
                    }
                    if (newReader != null)
                    {
                        newReader.Dispose();
                    }
                }

                IWriter output = new EndianWriter(File.Open(outputPath, FileMode.Create, FileAccess.Write), Endian.BigEndian);
                AssemblyPatchWriter.WritePatch(patch, output);
                output.Dispose();

                MetroMessageBox.Show("Patch Created!",
                                     "Your patch has been created in the designated location. Happy sailing, modder!");
            }
            catch (Exception ex)
            {
                MetroException.Show(ex);
            }
        }
示例#37
0
 /// <summary>
 /// Writes the field in a compiled state to the stream specified.
 /// </summary>
 /// <param name="bw">Stream to write the field to.</param>
 /// <param name="magic">Virtual address modifier value for the specified stream.</param>
 public override void Write(EndianWriter bw, int magic)
 {
     Write(bw);
 }
示例#38
0
        private void WriteDataBlock(DataBlock block, SegmentPointer location, IStream stream)
        {
            // Don't write anything if the block has already been written
            if (_dataBlockAddresses.ContainsKey(block))
                return;

            // Associate the location with the block
            _dataBlockAddresses[block] = location.AsPointer();

            // Create a MemoryStream and write the block data to it (so fixups can be performed before writing it to the file)
            using (var buffer = new MemoryStream(block.Data.Length))
            {
                var bufferWriter = new EndianWriter(buffer, stream.Endianness);
                bufferWriter.WriteBlock(block.Data);

                // Apply fixups
                FixBlockReferences(block, bufferWriter, stream);
                FixTagReferences(block, bufferWriter, stream);
                FixResourceReferences(block, bufferWriter, stream);
                FixStringIDReferences(block, bufferWriter);

                // Write the buffer to the file
                stream.SeekTo(location.AsOffset());
                stream.WriteBlock(buffer.GetBuffer(), 0, (int) buffer.Length);
            }
        }
        /// <summary>
        /// Extracts an XMA sound and converts it to a WAV.
        /// </summary>
        /// <param name="reader">The stream to read from.</param>
        /// <param name="offset">The offset of the data to extract.</param>
        /// <param name="rifx">The RIFX data for the sound.</param>
        /// <param name="outPath">The path of the file to save to.</param>
        public static void ExtractXMAToWAV(EndianReader reader, int offset, RIFX rifx, string outPath)
        {
            // Create a temporary file to write an XMA to
            string tempFile = Path.GetTempFileName();

            try
            {
                using (EndianWriter output = new EndianWriter(File.OpenWrite(tempFile), EndianFormat.BigEndian))
                {
                    // Generate an XMA header
                    // ADAPTED FROM wwisexmabank - I DO NOT TAKE ANY CREDIT WHATSOEVER FOR THE FOLLOWING CODE.
                    // See http://hcs64.com/vgm_ripping.html for more information
                    output.Write(0x52494646); // 'RIFF'
                    output.EndianType = EndianFormat.LittleEndian;
                    output.Write(rifx.DataSize + 0x34);
                    output.EndianType = EndianFormat.BigEndian;
                    output.Write(RIFFFormat.WAVE);

                    // Generate the 'fmt ' chunk
                    output.Write(0x666D7420); // 'fmt '
                    output.EndianType = EndianFormat.LittleEndian;
                    output.Write(0x20);
                    output.Write((short)0x165); // WAVE_FORMAT_XMA
                    output.Write((short)16);    // 16 bits per sample
                    output.Write((short)0);     // encode options **
                    output.Write((short)0);     // largest skip
                    output.Write((short)1);     // # streams
                    output.Write((byte)0);      // loops
                    output.Write((byte)3);      // encoder version
                    output.Write(0);            // bytes per second **
                    output.Write(rifx.SampleRate); // sample rate
                    output.Write(0);            // loop start
                    output.Write(0);            // loop end
                    output.Write((byte)0);      // subframe loop data
                    output.Write((byte)rifx.ChannelCount); // channels
                    output.Write((short)0x0002);// channel mask

                    // 'data' chunk
                    output.EndianType = EndianFormat.BigEndian;
                    output.Write(0x64617461); // 'data'
                    output.EndianType = EndianFormat.LittleEndian;
                    output.Write(rifx.DataSize);

                    // Copy the data chunk contents from the original RIFX
                    reader.SeekTo(offset + rifx.DataOffset);
                    StreamUtil.Copy(reader, output, rifx.DataSize);

                    // END ADAPTED CODE
                }

                // Convert it with towav
                RunProgramSilently("Helpers/towav.exe", "\"" + Path.GetFileName(tempFile) + "\"", Path.GetDirectoryName(tempFile));

                // Move the WAV to the destination path
                if (File.Exists(outPath))
                    File.Delete(outPath);
                File.Move(Path.ChangeExtension(tempFile, "wav"), outPath);
            }
            finally
            {
                // Delete the temporary XMA file
                if (File.Exists(tempFile))
                    File.Delete(tempFile);
            }
        }
示例#40
0
 public static void DeleteBytes(string filePath, int startOffset, int size)
 {
     var input = new FileStream(filePath, FileMode.Open);
     var er = new EndianReader(input);
     var buffer = er.ReadBytes(startOffset);
     var baseStream = er.BaseStream;
     baseStream.Position += size;
     var buffer2 = er.ReadBytes(((int)er.BaseStream.Length) - ((int)er.BaseStream.Position));
     er.Close();
     input.Close();
     input = new FileStream(filePath, FileMode.Create);
     var ew = new EndianWriter(input);
     ew.Write(buffer);
     ew.Write(buffer2);
     input.Close();
     ew.Close();
 }
示例#41
0
        public static byte[] GetXMA(byte[] buffer, SampleRate sRate, SoundType sType)
        {
            int rate;

            switch (sRate)
            {
            case SampleRate._22050Hz:
                rate = 22050;
                break;

            case SampleRate._44100Hz:
                rate = 44100;
                break;

            default:
                rate = 44100;
                break;
                //throw new Exception("Check sample rate.");
            }

            int cCount;

            switch (sType)
            {
            case SoundType.Mono:
                cCount = 1;
                break;

            case SoundType.Stereo:
                cCount = 2;
                break;

            //case SoundType.Unknown2:
            //    cCount = 2;
            //    footer = stereoFooter;
            //    break;
            //case SoundType.Unknown3:
            //    cCount = 2;
            //    footer = stereoFooter;
            //    break;
            default:
                throw new NotSupportedException("Unsupported Sound Type.");
            }

            var          ms = new MemoryStream();
            EndianWriter sw = new EndianWriter(ms, EndianFormat.BigEndian);

            sw.Write(0x52494646); // 'RIFF'
            sw.EndianType = EndianFormat.LittleEndian;
            sw.Write(buffer.Length + 0x34);
            sw.EndianType = EndianFormat.BigEndian;
            sw.Write(RIFFFormat.WAVE);

            // Generate the 'fmt ' chunk
            sw.Write(0x666D7420); // 'fmt '
            sw.EndianType = EndianFormat.LittleEndian;
            sw.Write(0x20);
            sw.Write((short)0x165);
            sw.Write((short)16);
            sw.Write((short)0);
            sw.Write((short)0);
            sw.Write((short)1);
            sw.Write((byte)0);
            sw.Write((byte)3);
            sw.Write(0);
            sw.Write(rate);
            sw.Write(0);
            sw.Write(0);
            sw.Write((byte)0);
            sw.Write((byte)cCount);
            sw.Write((short)0x0002);

            // 'data' chunk
            sw.EndianType = EndianFormat.BigEndian;
            sw.Write(0x64617461); // 'data'
            sw.EndianType = EndianFormat.LittleEndian;
            sw.Write(buffer.Length);
            sw.Write(buffer);

            sw.Close();
            sw.Dispose();

            return(ms.ToArray());
        }
示例#42
0
 /// <summary>
 /// Writes the field in a decompiled state to the stream specified.
 /// </summary>
 /// <param name="bw">Stream to write the field to.</param>
 public override void Write(EndianWriter bw)
 {
     bw.Write(To);
     bw.Write(From);
 }
 public override void Serialize(EndianWriter writer)
 {
     throw new NotImplementedException();
 }
示例#44
0
        public void SaveStrings(IStream stream, LocaleTable locales)
        {
            MemoryStream offsetData = new MemoryStream();
            MemoryStream stringData = new MemoryStream();
            IWriter offsetWriter = new EndianWriter(offsetData, Endian.BigEndian);
            IWriter stringWriter = new EndianWriter(stringData, Endian.BigEndian);

            try
            {
                // Write the string and offset data to buffers
                foreach (Locale locale in locales.Strings)
                {
                    WriteLocalePointer(offsetWriter, locale.ID, (int)stringWriter.Position);
                    stringWriter.WriteUTF8(locale.Value);
                }

                // Round the size of the string data up to the nearest multiple of 0x10 (AES block size)
                stringData.SetLength((stringData.Position + 0xF) & ~0xF);

                // Update the two locale data hashes if we need to
                // (the hash arrays are set to null if the build doesn't need them)
                if (IndexTableHash != null)
                    IndexTableHash = SHA1.Transform(offsetData.GetBuffer(), 0, (int)offsetData.Length);
                if (StringDataHash != null)
                    StringDataHash = SHA1.Transform(stringData.GetBuffer(), 0, (int)stringData.Length);

                // Make sure there's free space for the offset table and then write it to the file
                LocaleDataLocation += StreamUtil.MakeFreeSpace(stream, LocaleIndexTableLocation.AsOffset(), LocaleDataLocation.AsOffset(), offsetData.Length, _pageSize);
                stream.SeekTo(LocaleIndexTableLocation.AsOffset());
                stream.WriteBlock(offsetData.GetBuffer(), 0, (int)offsetData.Length);

                // Encrypt the string data if necessary
                byte[] strings = stringData.GetBuffer();
                if (_encryptionKey != null)
                    strings = AES.Encrypt(strings, 0, (int)stringData.Length, _encryptionKey.Key, _encryptionKey.IV);

                // Make free space for the string data
                uint oldDataEnd = (uint)((LocaleDataLocation.AsOffset() + LocaleTableSize + _pageSize - 1) & ~(_pageSize - 1)); // Add the old table size and round it up
                StreamUtil.MakeFreeSpace(stream, LocaleDataLocation.AsOffset(), oldDataEnd, stringData.Length, _pageSize);
                LocaleTableSize = (int)stringData.Length;

                // Write it to the file
                stream.SeekTo(LocaleDataLocation.AsOffset());
                stream.WriteBlock(strings, 0, (int)stringData.Length);

                // Update the string count and recalculate the language table offsets
                StringCount = locales.Strings.Count;

                int localePointerSize = (int)(offsetData.Length / locales.Strings.Count);
                _languageGlobals.RecalculateLanguageOffsets(localePointerSize);
            }
            finally
            {
                offsetWriter.Close();
                stringWriter.Close();
            }
        }
 public override void Serialize(EndianWriter writer)
 {
     writer.WriteBE(TitleId);
 }
示例#46
0
        private void contextExtract_Click(object sender, RoutedEventArgs e)
        {
            // Get the menu item and the tag
            var item = e.Source as MenuItem;
            if (item == null)
                return;

            var tag = item.DataContext as TagEntry;
            if (tag == null)
                return;

            // Ask where to save the extracted tag collection
            var sfd = new SaveFileDialog
            {
                Title = "Save Tag Set",
                Filter = "Tag Container Files|*.tagc"
            };
            bool? result = sfd.ShowDialog();
            if (!result.Value)
                return;

            // Make a tag container
            var container = new TagContainer();

            // Recursively extract tags
            var tagsToProcess = new Queue<ITag>();
            var tagsProcessed = new HashSet<ITag>();
            var resourcesToProcess = new Queue<DatumIndex>();
            var resourcesProcessed = new HashSet<DatumIndex>();
            var resourcePagesProcessed = new HashSet<ResourcePage>();
            tagsToProcess.Enqueue(tag.RawTag);

            ResourceTable resources = null;
            using (IReader reader = _mapManager.OpenRead())
            {
                while (tagsToProcess.Count > 0)
                {
                    ITag currentTag = tagsToProcess.Dequeue();
                    if (tagsProcessed.Contains(currentTag))
                        continue;

                    // Get the plugin path
                    string className = VariousFunctions.SterilizeTagClassName(CharConstant.ToString(currentTag.Class.Magic)).Trim();
                    string pluginPath = string.Format("{0}\\{1}\\{2}.xml", VariousFunctions.GetApplicationLocation() + @"Plugins",
                        _buildInfo.Settings.GetSetting<string>("plugins"), className);

                    // Extract dem data blocks
                    var blockBuilder = new DataBlockBuilder(reader, currentTag.MetaLocation, _cacheFile, _buildInfo);
                    using (XmlReader pluginReader = XmlReader.Create(pluginPath))
                        AssemblyPluginLoader.LoadPlugin(pluginReader, blockBuilder);

                    foreach (DataBlock block in blockBuilder.DataBlocks)
                        container.AddDataBlock(block);

                    // Add data for the tag that was extracted
                    string tagName = _cacheFile.FileNames.GetTagName(currentTag) ?? currentTag.Index.ToString();
                    var extractedTag = new ExtractedTag(currentTag.Index, currentTag.MetaLocation.AsPointer(), currentTag.Class.Magic,
                        tagName);
                    container.AddTag(extractedTag);

                    // Mark the tag as processed and then enqueue all of its child tags and resources
                    tagsProcessed.Add(currentTag);
                    foreach (DatumIndex tagRef in blockBuilder.ReferencedTags)
                        tagsToProcess.Enqueue(_cacheFile.Tags[tagRef]);
                    foreach (DatumIndex resource in blockBuilder.ReferencedResources)
                        resourcesToProcess.Enqueue(resource);
                }

                // Load the resource table in if necessary
                if (resourcesToProcess.Count > 0)
                    resources = _cacheFile.Resources.LoadResourceTable(reader);
            }

            // Extract resource info
            if (resources != null)
            {
                while (resourcesToProcess.Count > 0)
                {
                    DatumIndex index = resourcesToProcess.Dequeue();
                    if (resourcesProcessed.Contains(index))
                        continue;

                    // Add the resource
                    Resource resource = resources.Resources[index.Index];
                    container.AddResource(new ExtractedResourceInfo(resource));

                    // Add data for its pages
                    if (resource.Location == null)
                        continue;
                    if (resource.Location.PrimaryPage != null && !resourcePagesProcessed.Contains(resource.Location.PrimaryPage))
                    {
                        container.AddResourcePage(resource.Location.PrimaryPage);
                        resourcePagesProcessed.Add(resource.Location.PrimaryPage);
                    }
                    if (resource.Location.SecondaryPage == null || resourcePagesProcessed.Contains(resource.Location.SecondaryPage))
                        continue;
                    container.AddResourcePage(resource.Location.SecondaryPage);
                    resourcePagesProcessed.Add(resource.Location.SecondaryPage);
                }
            }

            // Write it to a file
            using (var writer = new EndianWriter(File.Open(sfd.FileName, FileMode.Create, FileAccess.Write), Endian.BigEndian))
                TagContainerWriter.WriteTagContainer(container, writer);

            // YAY!
            MetroMessageBox.Show("Extraction Successful",
                "Extracted " + container.Tags.Count + " tag(s), " + container.DataBlocks.Count + " data block(s), " +
                container.ResourcePages.Count + " resource page pointer(s), and " + container.Resources.Count +
                " resource pointer(s).");
        }
        public override object Execute(List <string> args)
        {
            if (args.Count < 1 || args.Count > 2)
            {
                return(false);
            }

            if (args.Count == 2 && (args[0].ToLower() != "raw"))
            {
                return(false);
            }

            var file = "";

            if (args.Count == 1)
            {
                file = args[0];
            }
            else
            {
                file = args[1];
            }

            var resourceContext = new ResourceSerializationContext(CacheContext, Geometry.Resource);
            var definition      = CacheContext.Deserializer.Deserialize <RenderGeometryApiResourceDefinition>(resourceContext);

            if (args.Count == 2)
            {
                using (var edResourceStream = new MemoryStream())
                    using (var edResourceReader = new EndianReader(edResourceStream, EndianFormat.LittleEndian))
                    {
                        var directory = args[1];
                        if (!Directory.Exists(directory))
                        {
                            Directory.CreateDirectory(directory);
                        }

                        var dataOutDir = directory;

                        for (var i = 0; i < definition.VertexBuffers.Count; i++)
                        {
                            edResourceStream.Position = definition.VertexBuffers[i].Definition.Data.Address.Offset;

                            var vertexBuffer = definition.VertexBuffers[i].Definition;

                            dataOutDir = Path.Combine(directory, $"{i}_{vertexBuffer.Format}_{vertexBuffer.Count}");

                            using (EndianWriter output = new EndianWriter(File.OpenWrite(dataOutDir), EndianFormat.LittleEndian))
                            {
                                byte[] data = edResourceReader.ReadBytes((int)vertexBuffer.Data.Size);
                                output.WriteBlock(data);
                            }
                        }
                    }
            }
            else
            {
                //
                // Convert Blam data to ElDorado data
                //

                using (var fileStream = File.Create(file))
                    using (var fileWriter = new StreamWriter(fileStream))
                    {
                        using (var edResourceStream = new MemoryStream())
                            using (var edResourceReader = new EndianReader(edResourceStream, EndianFormat.LittleEndian))
                            {
                                //
                                // Convert Blam vertex buffers
                                //

                                Console.Write("Converting vertex buffers...");
                                CacheContext.ExtractResource(Geometry.Resource, edResourceStream);

                                for (var i = 0; i < definition.VertexBuffers.Count; i++)
                                {
                                    edResourceStream.Position = definition.VertexBuffers[i].Definition.Data.Address.Offset;

                                    var vertexBuffer = definition.VertexBuffers[i].Definition;

                                    //fileWriter.WriteLine($"Offset = {vertexBuffer.Data.Address.Offset.ToString("X8")} Count = {vertexBuffer.Count} Size = {vertexBuffer.VertexSize}, Format = {vertexBuffer.Format.ToString()}");
                                    //fileWriter.WriteLine(Environment.NewLine);

                                    //fileWriter.WriteLine($"Vertex buffer index: {i}");

                                    switch (vertexBuffer.Format)
                                    {
                                    case VertexBufferFormat.TinyPosition:
                                        for (var j = 0; j < vertexBuffer.Count; j++)
                                        {
                                            fileWriter.WriteLine($"Position = ({edResourceReader.ReadUInt16().ToString("X4")},{edResourceReader.ReadUInt16().ToString("X4")},{edResourceReader.ReadUInt16().ToString("X4")},{edResourceReader.ReadUInt16().ToString("X4")})");
                                            fileWriter.WriteLine($"Normal   = ({edResourceReader.ReadByte().ToString("X2")},{edResourceReader.ReadByte().ToString("X2")},{edResourceReader.ReadByte().ToString("X2")},{edResourceReader.ReadByte().ToString("X2")})");
                                            fileWriter.WriteLine($"Color    = {edResourceReader.ReadUInt32().ToString("X8")}");
                                        }
                                        break;

                                    case VertexBufferFormat.StaticPerVertex:
                                        for (var j = 0; j < vertexBuffer.Count; j++)
                                        {
                                            fileWriter.WriteLine($"{vertexBuffer.Format} index: {j}:");
                                            fileWriter.WriteLine($"Texcoord = " + edResourceReader.ReadUInt32().ToString("X8"));
                                            fileWriter.WriteLine($"Texcoord = " + edResourceReader.ReadUInt32().ToString("X8"));
                                            fileWriter.WriteLine($"Texcoord = " + edResourceReader.ReadUInt32().ToString("X8"));
                                            fileWriter.WriteLine($"Texcoord = " + edResourceReader.ReadUInt32().ToString("X8"));
                                            fileWriter.WriteLine($"Texcoord = " + edResourceReader.ReadUInt32().ToString("X8"));
                                            fileWriter.WriteLine($"End of {vertexBuffer.Format} index: {j}");
                                            fileWriter.WriteLine(Environment.NewLine);
                                        }
                                        break;

                                    case VertexBufferFormat.Skinned:
                                        for (var j = 0; j < vertexBuffer.Count; j++)
                                        {
                                            fileWriter.WriteLine($"{j}:");
                                            fileWriter.WriteLine($"Position X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                            fileWriter.WriteLine($"Texcoord U = " + edResourceReader.ReadSingle() + " V = " + edResourceReader.ReadSingle());
                                            fileWriter.WriteLine($"Normal   X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                            fileWriter.WriteLine($"Tangent  X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                            fileWriter.WriteLine($"Binormal X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                            edResourceReader.ReadUInt32();
                                            edResourceReader.ReadUInt32();
                                        }
                                        break;

                                        /*
                                         * case VertexBufferFormat.Unknown1B:
                                         *  var goodCount = 0;
                                         *  for (var j = 0; j < vertexBuffer.Count; j++)
                                         *  {
                                         *      //fileWriter.WriteLine($"Index: {j}:");
                                         *      string values = $"({ edResourceReader.ReadSingle()},{ edResourceReader.ReadSingle()}," +
                                         *          $"{edResourceReader.ReadSingle()},{edResourceReader.ReadSingle()},{edResourceReader.ReadSingle()},{edResourceReader.ReadSingle()}" +
                                         *          $",{edResourceReader.ReadSingle()},{edResourceReader.ReadSingle()},{edResourceReader.ReadSingle()})";
                                         *      if(values != "(0,0,0,0,0,0,0,0,0)")
                                         *      {
                                         *          goodCount++;
                                         *          //fileWriter.WriteLine($"(1,2,3,4,5,6,7,8,9) = "+values);
                                         *      }
                                         *
                                         *
                                         *      /*
                                         *      fileWriter.WriteLine($"Unknown 1 = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Unknown 2 = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Unknown 3 = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Unknown 4 = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Unknown 5 = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Unknown 6 = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Unknown 7 = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Unknown 8 = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Unknown 9 = " + edResourceReader.ReadSingle());
                                         *
                                         *  }
                                         *  //fileWriter.WriteLine($"Valid Unknown1B count = {goodCount}");
                                         *  break;
                                         *
                                         * case VertexBufferFormat.Unknown1A:
                                         *  for (var j = 0; j < vertexBuffer.Count; j++)
                                         *  {
                                         *      //fileWriter.WriteLine($"Index: {j}:");
                                         *      //fileWriter.WriteLine($"Unknown 1 = " + edResourceReader.ReadUInt32().ToString("X8"));
                                         *      fileWriter.WriteLine($"(1,2,3) = ({edResourceReader.ReadUInt32().ToString("X8")},{edResourceReader.ReadUInt32().ToString("X8")},{edResourceReader.ReadUInt32().ToString("X8")})");
                                         *  }
                                         *  break;
                                         *
                                         * case VertexBufferFormat.Rigid:
                                         *  for (var j = 0; j < vertexBuffer.Count; j++)
                                         *  {
                                         *      fileWriter.WriteLine($"{j}:");
                                         *      fileWriter.WriteLine($"Position X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Texcoord U = " + edResourceReader.ReadSingle() + " V = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Normal   X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Tangent  X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Binormal X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                         *  }
                                         *  break;
                                         *
                                         * case VertexBufferFormat.StaticPerPixel:
                                         *  for (var j = 0; j < vertexBuffer.Count; j++)
                                         *  {
                                         *      fileWriter.WriteLine($"{j} U = " + edResourceReader.ReadSingle() + " V = " + edResourceReader.ReadSingle());
                                         *      //fileWriter.WriteLine(Environment.NewLine);
                                         *  }
                                         *  break;
                                         *
                                         * case VertexBufferFormat.AmbientPrt:
                                         *  for (var j = 0; j < vertexBuffer.Count; j++)
                                         *  {
                                         *      fileWriter.WriteLine($"{j} Blend weight = " + edResourceReader.ReadSingle());
                                         *      //fileWriter.WriteLine(Environment.NewLine);
                                         *  }
                                         *  break;
                                         *
                                         *
                                         * case VertexBufferFormat.World:
                                         *  for (var j = 0; j < vertexBuffer.Count; j++)
                                         *  {
                                         *      fileWriter.WriteLine($"{j}:");
                                         *      fileWriter.WriteLine($"Position X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Texcoord U = " + edResourceReader.ReadSingle() + " V = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Normal   X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Tangent  X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                         *      fileWriter.WriteLine($"Binormal X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                         *  }
                                         *  break;
                                         *
                                         *
                                         *
                                         */
                                        /*
                                         *  case VertexBufferFormat.QuadraticPrt:
                                         *      for (var j = 0; j < vertexBuffer.Count; j++)
                                         *      {
                                         *          fileWriter.WriteLine($"{vertexBuffer.Format} index: {j}:");
                                         *          fileWriter.WriteLine($"A X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                         *          fileWriter.WriteLine($"B X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                         *          fileWriter.WriteLine($"C X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                         *          fileWriter.WriteLine($"End of {vertexBuffer.Format} index: {j}");
                                         *          fileWriter.WriteLine(Environment.NewLine);
                                         *      }
                                         *      break;
                                         *
                                         *
                                         *
                                         *  case VertexBufferFormat.Unknown1B:
                                         *      for (var j = 0; j < vertexBuffer.Count; j++)
                                         *      {
                                         *          fileWriter.WriteLine($"{vertexBuffer.Format} index: {j}:");
                                         *          fileWriter.WriteLine($"Unknown 1 = " + edResourceReader.ReadSingle());
                                         *          fileWriter.WriteLine($"Unknown 2 = " + edResourceReader.ReadSingle());
                                         *          fileWriter.WriteLine($"Unknown 3 = " + edResourceReader.ReadSingle());
                                         *          fileWriter.WriteLine($"Unknown 4 = " + edResourceReader.ReadSingle());
                                         *          fileWriter.WriteLine($"Unknown 5 = " + edResourceReader.ReadSingle());
                                         *          fileWriter.WriteLine($"Unknown 6 = " + edResourceReader.ReadSingle());
                                         *          fileWriter.WriteLine($"Unknown 7 = " + edResourceReader.ReadSingle());
                                         *          fileWriter.WriteLine($"Unknown 8 = " + edResourceReader.ReadSingle());
                                         *          fileWriter.WriteLine($"Unknown 9 = " + edResourceReader.ReadSingle());
                                         *          fileWriter.WriteLine($"End of {vertexBuffer.Format} index: {j}");
                                         *          fileWriter.WriteLine(Environment.NewLine);
                                         *      }
                                         *      break;
                                         *
                                         *  case VertexBufferFormat.Decorator:
                                         *      for (var j = 0; j < vertexBuffer.Count; j++)
                                         *      {
                                         *          fileWriter.WriteLine($"{vertexBuffer.Format} index: {j}:");
                                         *          fileWriter.WriteLine($"Position X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                         *          fileWriter.WriteLine($"Texcoord U = " + edResourceReader.ReadSingle() + " V = " + edResourceReader.ReadSingle());
                                         *          fileWriter.WriteLine($"Normal   X = " + edResourceReader.ReadSingle() + " Y = " + edResourceReader.ReadSingle() + " Z = " + edResourceReader.ReadSingle());
                                         *          fileWriter.WriteLine($"End of {vertexBuffer.Format} index: {j}");
                                         *          fileWriter.WriteLine(Environment.NewLine);
                                         *      }
                                         *      break;
                                         *
                                         *  case VertexBufferFormat.LinearPrt:
                                         *      for (var j = 0; j < vertexBuffer.Count; j++)
                                         *      {
                                         *          fileWriter.WriteLine($"{vertexBuffer.Format} index: {j}:");
                                         *          fileWriter.WriteLine($"Hex : " + edResourceReader.ReadUInt32().ToString("X8"));
                                         *          fileWriter.WriteLine($"End of {vertexBuffer.Format} index: {j}");
                                         *          fileWriter.WriteLine(Environment.NewLine);
                                         *      }
                                         *      break;
                                         */
                                    }

                                    //fileWriter.WriteLine($"End of Vertex Buffer index: {i}");

                                    //fileWriter.WriteLine(Environment.NewLine);
                                }
                            }
                    }
            }



            return(true);
        }
示例#48
0
 internal override void SerializeStreamer(EndianWriter writer)
 {
     throw new NotImplementedException();
 }
示例#49
0
        private void WriteDataBlock(DataBlock block, SegmentPointer location, IStream stream, ITag tag = null)
        {
            if (tag == null && _dataBlockAddresses.ContainsKey(block))             // Don't write anything if the block has already been written
            {
                return;
            }

            // Associate the location with the block
            _dataBlockAddresses[block] = location.AsPointer();

            // Create a MemoryStream and write the block data to it (so fixups can be performed before writing it to the file)
            using (var buffer = new MemoryStream(block.Data.Length))
            {
                var bufferWriter = new EndianWriter(buffer, stream.Endianness);
                bufferWriter.WriteBlock(block.Data);

                // Apply fixups
                FixBlockReferences(block, bufferWriter, stream);
                FixTagReferences(block, bufferWriter, stream);
                FixResourceReferences(block, bufferWriter, stream);
                FixStringIdReferences(block, bufferWriter);
                if (tag != null)
                {
                    FixUnicListReferences(block, tag, bufferWriter, stream);
                }
                FixInteropReferences(block, bufferWriter, stream, location);
                FixEffectReferences(block, bufferWriter);
                if (!_dupeReuseSoundGestalt)
                {
                    FixSoundReferences(block, bufferWriter, stream);
                }

                // sort after fixups
                if (block.Sortable && block.EntrySize >= 4)
                {
                    var entries      = new List <Tuple <uint, byte[]> >();
                    var bufferReader = new EndianReader(buffer, stream.Endianness);

                    for (int i = 0; i < block.EntryCount; i++)
                    {
                        buffer.Position = i * block.EntrySize;
                        uint   sid  = bufferReader.ReadUInt32();
                        byte[] rest = bufferReader.ReadBlock(block.EntrySize - 4);
                        entries.Add(new Tuple <uint, byte[]>(sid, rest));
                    }
                    buffer.Position = 0;
                    foreach (var entry in entries.OrderBy(e => e.Item1))
                    {
                        bufferWriter.WriteUInt32(entry.Item1);
                        bufferWriter.WriteBlock(entry.Item2);
                    }
                }

                // Write the buffer to the file
                stream.SeekTo(location.AsOffset());
                stream.WriteBlock(buffer.ToArray(), 0, (int)buffer.Length);
            }

            // Write shader fixups (they can't be done in-memory because they require cache file expansion)
            FixShaderReferences(block, stream, location);
        }
示例#50
0
 public override void WriteValue(EndianWriter writer)
 {
 }
示例#51
0
        private Sound ConvertSound(Stream cacheStream, Dictionary <ResourceLocation, Stream> resourceStreams, Sound sound, string blamTag_Name)
        {
            if (BlamSoundGestalt == null)
            {
                BlamSoundGestalt = PortingContextFactory.LoadSoundGestalt(CacheContext, ref BlamCache);
            }

            if (!File.Exists(@"Tools\ffmpeg.exe") || !File.Exists(@"Tools\towav.exe"))
            {
                Console.WriteLine("Failed to locate sound conversion tools, please install ffmpeg and towav in the Tools folder");
                return(null);
            }

            //
            // Convert Sound Tag Data
            //

            var platformCodec      = BlamSoundGestalt.PlatformCodecs[sound.SoundReference.PlatformCodecIndex];
            var playbackParameters = BlamSoundGestalt.PlaybackParameters[sound.SoundReference.PlaybackParameterIndex];
            var scale          = BlamSoundGestalt.Scales[sound.SoundReference.ScaleIndex];
            var promotion      = sound.SoundReference.PromotionIndex != -1 ? BlamSoundGestalt.Promotions[sound.SoundReference.PromotionIndex] : new Promotion();
            var customPlayBack = sound.SoundReference.CustomPlaybackIndex != -1 ? new List <CustomPlayback> {
                BlamSoundGestalt.CustomPlaybacks[sound.SoundReference.CustomPlaybackIndex]
            } : new List <CustomPlayback>();
            var loop = sound.Flags.HasFlag(Sound.FlagsValue.LoopingSound);

            sound.PlaybackParameters = playbackParameters;
            sound.Scale           = scale;
            sound.PlatformCodec   = platformCodec.DeepClone();
            sound.Promotion       = promotion;
            sound.CustomPlayBacks = customPlayBack;

            //
            // Tag fixes
            //

            sound.SampleRate = platformCodec.SampleRate;
            sound.ImportType = ImportType.SingleLayer;
            // helps looping sound? there is another value, 10 for Unknown2 but I don't know when to activate it.
            if (sound.SoundReference.PitchRangeCount > 1)
            {
                sound.ImportType = ImportType.MultiLayer;
            }

            sound.PlatformCodec.LoadMode = 0;

            //
            // Process all the pitch ranges
            //

            var xmaFileSize = BlamSoundGestalt.GetFileSize(sound.SoundReference.PitchRangeIndex, sound.SoundReference.PitchRangeCount);

            if (xmaFileSize < 0)
            {
                return(null);
            }

            var xmaData = BlamCache.GetSoundRaw(sound.SoundReference.ZoneAssetHandle, xmaFileSize);

            if (xmaData == null)
            {
                return(null);
            }

            sound.PitchRanges = new List <PitchRange>(sound.SoundReference.PitchRangeCount);

            var soundDataAggregate     = new byte[0].AsEnumerable();
            var currentSoundDataOffset = 0;
            var totalSampleCount       = (uint)0;

            for (int pitchRangeIndex = sound.SoundReference.PitchRangeIndex; pitchRangeIndex < sound.SoundReference.PitchRangeIndex + sound.SoundReference.PitchRangeCount; pitchRangeIndex++)
            {
                totalSampleCount += BlamSoundGestalt.GetSamplesPerPitchRange(pitchRangeIndex);

                //
                // Convert Blam pitch range to ElDorado format
                //

                var pitchRange = BlamSoundGestalt.PitchRanges[pitchRangeIndex];
                pitchRange.ImportName           = ConvertStringId(BlamSoundGestalt.ImportNames[pitchRange.ImportNameIndex].Name);
                pitchRange.PitchRangeParameters = BlamSoundGestalt.PitchRangeParameters[pitchRange.PitchRangeParametersIndex];
                pitchRange.Unknown1             = 0;
                pitchRange.Unknown2             = 0;
                pitchRange.Unknown3             = 0;
                pitchRange.Unknown4             = 0;
                pitchRange.Unknown5             = -1;
                pitchRange.Unknown6             = -1;
                //I suspect this unknown7 to be a flag to tell if there is a Unknownblock in extrainfo. (See a sound in udlg for example)
                pitchRange.Unknown7         = 0;
                pitchRange.PermutationCount = (byte)BlamSoundGestalt.GetPermutationCount(pitchRangeIndex);
                pitchRange.Unknown8         = -1;

                // Add pitch range to ED sound
                sound.PitchRanges.Add(pitchRange);
                var newPitchRangeIndex = pitchRangeIndex - sound.SoundReference.PitchRangeIndex;
                sound.PitchRanges[newPitchRangeIndex].Permutations = new List <Permutation>();

                //
                // Determine the audio channel count
                //

                var channelCount = Encoding.GetChannelCount(sound.PlatformCodec.Encoding);

                //
                // Set compression format
                //

                sound.PlatformCodec.Compression = Compression.MP3;

                //
                // Convert Blam permutations to ElDorado format
                //

                var useCache = Sounds.UseAudioCacheCommand.AudioCacheDirectory != null;

                var basePermutationCacheName = Path.Combine(
                    useCache ? Sounds.UseAudioCacheCommand.AudioCacheDirectory.FullName : TempDirectory.FullName,
                    GetTagFileFriendlyName(blamTag_Name));

                var permutationCount        = BlamSoundGestalt.GetPermutationCount(pitchRangeIndex);
                var permutationOrder        = BlamSoundGestalt.GetPermutationOrder(pitchRangeIndex);
                var relativePitchRangeIndex = pitchRangeIndex - sound.SoundReference.PitchRangeIndex;

                for (int i = 0; i < permutationCount; i++)
                {
                    var permutationIndex  = pitchRange.FirstPermutationIndex + i;
                    var permutationSize   = BlamSoundGestalt.GetPermutationSize(permutationIndex);
                    var permutationOffset = BlamSoundGestalt.GetPermutationOffset(permutationIndex);

                    var permutation = BlamSoundGestalt.GetPermutation(permutationIndex).DeepClone();

                    permutation.ImportName            = ConvertStringId(BlamSoundGestalt.ImportNames[permutation.ImportNameIndex].Name);
                    permutation.SkipFraction          = new Bounds <float>(0.0f, permutation.Gain);
                    permutation.PermutationChunks     = new List <PermutationChunk>();
                    permutation.PermutationNumber     = (uint)permutationOrder[i];
                    permutation.IsNotFirstPermutation = (uint)(permutation.PermutationNumber == 0 ? 0 : 1);

                    string permutationName = $"{basePermutationCacheName}_{relativePitchRangeIndex}_{i}";

                    string extension = "mp3";

                    var cacheFileName = $"{permutationName}.{extension}";

                    bool exists = File.Exists(cacheFileName);

                    byte[] permutationData = null;

                    if (!exists || !useCache)
                    {
                        BlamSound blamSound = SoundConverter.ConvertGen3Sound(BlamCache, BlamSoundGestalt, sound, relativePitchRangeIndex, i, xmaData);
                        permutationData = blamSound.Data;
                        if (useCache)
                        {
                            using (EndianWriter output = new EndianWriter(new FileStream(cacheFileName, FileMode.Create, FileAccess.Write, FileShare.None), EndianFormat.BigEndian))
                            {
                                output.WriteBlock(blamSound.Data);
                            }
                        }
                    }
                    else
                    {
                        permutationData = File.ReadAllBytes(cacheFileName);
                    }

                    permutation.PermutationChunks.Add(new PermutationChunk(currentSoundDataOffset, permutationData.Length));
                    currentSoundDataOffset += permutationData.Length;
                    pitchRange.Permutations.Add(permutation);

                    soundDataAggregate = soundDataAggregate.Concat(permutationData);
                }
            }

            sound.Promotion.LongestPermutationDuration = (uint)sound.SoundReference.MaximumPlayTime;
            sound.Promotion.TotalSampleSize            = totalSampleCount;

            //
            // Convert Blam extra info to ElDorado format
            //

            var extraInfo = new ExtraInfo()
            {
                LanguagePermutations       = new List <ExtraInfo.LanguagePermutation>(),
                EncodedPermutationSections = new List <ExtraInfo.EncodedPermutationSection>()
            };

            for (int u = 0; u < sound.SoundReference.PitchRangeCount; u++)
            {
                var pitchRange = BlamSoundGestalt.PitchRanges[sound.SoundReference.PitchRangeIndex + u];

                for (int i = 0; i < pitchRange.PermutationCount; i++)
                {
                    var permutation      = BlamSoundGestalt.GetPermutation(pitchRange.FirstPermutationIndex + i);
                    var permutationChunk = BlamSoundGestalt.GetPermutationChunk(permutation.FirstPermutationChunkIndex);

                    extraInfo.LanguagePermutations.Add(new ExtraInfo.LanguagePermutation
                    {
                        RawInfo = new List <ExtraInfo.LanguagePermutation.RawInfoBlock>
                        {
                            new ExtraInfo.LanguagePermutation.RawInfoBlock
                            {
                                SkipFractionName = StringId.Invalid,
                                UnknownList      = new List <ExtraInfo.LanguagePermutation.RawInfoBlock.Unknown>
                                {
                                    new ExtraInfo.LanguagePermutation.RawInfoBlock.Unknown
                                    {
                                        Unknown1 = permutationChunk.UnknownA,
                                        Unknown2 = permutationChunk.UnknownSize,
                                        Unknown3 = 0,
                                        Unknown4 = permutation.SampleSize,
                                        Unknown5 = 0,
                                        Unknown6 = permutationChunk.EncodedSize & 0xFFFF
                                    }
                                },
                                Compression          = 8,
                                ResourceSampleSize   = pitchRange.Permutations[i].SampleSize,
                                ResourceSampleOffset = (uint)pitchRange.Permutations[i].PermutationChunks[0].Offset,
                                SampleCount          = (uint)pitchRange.Permutations[i].PermutationChunks[0].EncodedSize & 0x3FFFFFF,
                                //SampleCount = (uint)Math.Floor(pitchRange.Permutations[i].SampleSize * 128000.0 / (8 * sound.SampleRate.GetSampleRateHz())),
                                Unknown24 = 480
                            }
                        }
                    });
                }
            }

            if (sound.SoundReference.ExtraInfoIndex != -1)
            {
                foreach (var section in BlamSoundGestalt.ExtraInfo[sound.SoundReference.ExtraInfoIndex].EncodedPermutationSections)
                {
                    var newSection = section.DeepClone();

                    foreach (var info in newSection.SoundDialogueInfo)
                    {
                        for (var i = ((info.MouthDataLength % 2) == 0 ? 0 : 1); (i + 1) < info.MouthDataLength; i += 2)
                        {
                            Array.Reverse(newSection.EncodedData, (int)(info.MouthDataOffset + i), 2);
                        }

                        for (var i = ((info.LipsyncDataLength % 2) == 0 ? 0 : 1); (i + 1) < info.LipsyncDataLength; i += 2)
                        {
                            Array.Reverse(newSection.EncodedData, (int)(info.LipsyncDataOffset + i), 2);
                        }
                    }

                    extraInfo.EncodedPermutationSections.Add(newSection);
                }
            }

            sound.ExtraInfo = new List <ExtraInfo> {
                extraInfo
            };

            //
            // Convert Blam languages to ElDorado format
            //

            if (sound.SoundReference.LanguageIndex != -1)
            {
                sound.Languages = new List <LanguageBlock>();

                foreach (var language in BlamSoundGestalt.Languages)
                {
                    sound.Languages.Add(new LanguageBlock
                    {
                        Language             = language.Language,
                        PermutationDurations = new List <LanguageBlock.PermutationDurationBlock>(),
                        PitchRangeDurations  = new List <LanguageBlock.PitchRangeDurationBlock>(),
                    });

                    //Add all the  Pitch Range Duration block (pitch range count dependent)

                    var curLanguage = sound.Languages.Last();

                    for (int i = 0; i < sound.SoundReference.PitchRangeCount; i++)
                    {
                        curLanguage.PitchRangeDurations.Add(language.PitchRangeDurations[sound.SoundReference.LanguageIndex + i]);
                    }

                    //Add all the Permutation Duration Block and adjust offsets

                    for (int i = 0; i < curLanguage.PitchRangeDurations.Count; i++)
                    {
                        var curPRD = curLanguage.PitchRangeDurations[i];

                        //Get current block count for new index
                        short newPermutationIndex = (short)curLanguage.PermutationDurations.Count();

                        for (int j = curPRD.PermutationStartIndex; j < curPRD.PermutationStartIndex + curPRD.PermutationCount; j++)
                        {
                            curLanguage.PermutationDurations.Add(language.PermutationDurations[j]);
                        }

                        //apply new index
                        curPRD.PermutationStartIndex = newPermutationIndex;
                    }
                }
            }

            //
            // Prepare resource
            //

            sound.Unused    = new byte[] { 0, 0, 0, 0 };
            sound.Unknown12 = 0;

            sound.Resource = new PageableResource
            {
                Page = new RawPage
                {
                    Index = -1,
                },
                Resource = new TagResourceGen3
                {
                    ResourceType             = TagResourceTypeGen3.Sound,
                    DefinitionData           = new byte[20],
                    DefinitionAddress        = new CacheResourceAddress(CacheResourceAddressType.Definition, 536870912),
                    ResourceFixups           = new List <TagResourceGen3.ResourceFixup>(),
                    ResourceDefinitionFixups = new List <TagResourceGen3.ResourceDefinitionFixup>(),
                    Unknown2 = 1
                }
            };

            var data = soundDataAggregate.ToArray();

            var resourceContext = new ResourceSerializationContext(CacheContext, sound.Resource);

            CacheContext.Serializer.Serialize(resourceContext,
                                              new SoundResourceDefinition
            {
                Data = new TagData(data.Length, new CacheResourceAddress(CacheResourceAddressType.Resource, 0))
            });

            var definitionFixup = new TagResourceGen3.ResourceFixup()
            {
                BlockOffset = 12,
                Address     = new CacheResourceAddress(CacheResourceAddressType.Resource, 1073741824)
            };

            sound.Resource.Resource.ResourceFixups.Add(definitionFixup);

            sound.Resource.ChangeLocation(ResourceLocation.Audio);
            var resource = sound.Resource;

            if (resource == null)
            {
                throw new ArgumentNullException("resource");
            }

            var cache = CacheContext.GetResourceCache(ResourceLocation.Audio);

            if (!resourceStreams.ContainsKey(ResourceLocation.Audio))
            {
                resourceStreams[ResourceLocation.Audio] = FlagIsSet(PortingFlags.Memory) ?
                                                          new MemoryStream() :
                                                          (Stream)CacheContext.OpenResourceCacheReadWrite(ResourceLocation.Audio);

                if (FlagIsSet(PortingFlags.Memory))
                {
                    using (var resourceStream = CacheContext.OpenResourceCacheRead(ResourceLocation.Audio))
                        resourceStream.CopyTo(resourceStreams[ResourceLocation.Audio]);
                }
            }

            resource.Page.Index = cache.Add(resourceStreams[ResourceLocation.Audio], data, out uint compressedSize);
            resource.Page.CompressedBlockSize   = compressedSize;
            resource.Page.UncompressedBlockSize = (uint)data.Length;
            resource.DisableChecksum();

            for (int i = 0; i < 4; i++)
            {
                sound.Resource.Resource.DefinitionData[i] = (byte)(sound.Resource.Page.UncompressedBlockSize >> (i * 8));
            }

            return(sound);
        }
示例#52
0
        /// <summary>
        /// Saves selected permutations of a sound tag.
        /// </summary>
        /// <param name="Folder">The folder to save all files in. Each file will be named as the permutation name.</param>
        /// <param name="Cache">The CacheFile containing the tag.</param>
        /// <param name="Tag">The sound tag.</param>
        /// <param name="Format">The format in which to save the data.</param>
        /// <param name="Indices">The indices of the permutations to extract.</param>
        public static void SaveSelected(string Folder, CacheBase Cache, CacheBase.IndexItem Tag, SoundFormat Format, List <int> Indices, bool Overwrite)
        {
            var           snd_  = DefinitionsManager.snd_(Cache, Tag);
            List <byte[]> perms = new List <byte[]>();

            var ugh_     = Cache.ugh_;
            var playback = ugh_.PlayBacks[snd_.PlaybackIndex];
            var data     = Cache.GetSoundRaw(snd_.RawID, GetTotalSize(ugh_, playback));

            if (playback.PermutationCount == 1)
            {
                perms.Add(data);
            }
            else
            {
                Folder = Directory.GetParent(Folder) + "\\" + Path.GetFileNameWithoutExtension(Folder);

                for (int i = 0; i < playback.PermutationCount; i++)
                {
                    var perm = Cache.ugh_.SoundPermutations[playback.FirstPermutation + i];
                    perms.Add(GetPermData(data, ugh_, perm));
                }
            }

            #region XMA
            if (Format == SoundFormat.XMA)
            {
                foreach (int index in Indices)
                {
                    string Filename = (playback.PermutationCount == 1) ? Folder : Folder + "\\" + ugh_.SoundNames[ugh_.SoundPermutations[playback.FirstPermutation + index].NameIndex].Name + ".xma";
                    if (!Filename.EndsWith(".xma"))
                    {
                        Filename += ".xma";
                    }

                    if (File.Exists(Filename) && !Overwrite)
                    {
                        continue;
                    }

                    byte[] buffer = perms[index];
                    var    codec  = Cache.ugh_.Codecs[snd_.CodecIndex];
                    var    xma    = GetXMA(buffer, snd_.SampleRate, codec.Type);

                    if (!Directory.GetParent(Filename).Exists)
                    {
                        Directory.GetParent(Filename).Create();
                    }

                    var          fs = new FileStream(Filename, FileMode.Create);
                    EndianWriter sw = new EndianWriter(fs, EndianFormat.BigEndian);
                    sw.Write(xma);

                    sw.Close();
                    sw.Dispose();
                }
            }
            #endregion
            #region WAV
            else if (Format == SoundFormat.WAV)
            {
                foreach (int index in Indices)
                {
                    string Filename = (playback.PermutationCount == 1) ? Folder : Folder + "\\" + ugh_.SoundNames[ugh_.SoundPermutations[playback.FirstPermutation + index].NameIndex].Name + ".wav";
                    if (!Filename.EndsWith(".wav"))
                    {
                        Filename += ".wav";
                    }

                    if (File.Exists(Filename) && !Overwrite)
                    {
                        continue;
                    }

                    var tempName = Path.GetTempFileName();

                    #region Write XMA
                    var buffer = perms[index];
                    var codec  = Cache.ugh_.Codecs[snd_.CodecIndex];
                    var xma    = GetXMA(buffer, snd_.SampleRate, codec.Type);

                    var          fs = File.OpenWrite(tempName);
                    EndianWriter sw = new EndianWriter(fs, EndianFormat.BigEndian);
                    sw.Write(xma);

                    sw.Close();
                    sw.Dispose();
                    #endregion

                    var info = new ProcessStartInfo(towav, tempName)
                    {
                        CreateNoWindow   = true,
                        UseShellExecute  = false,
                        WorkingDirectory = Directory.GetParent(tempName).FullName
                    };

                    Process.Start(info).WaitForExit();

                    if (File.Exists(Filename))
                    {
                        File.Delete(Filename);
                    }
                    if (!Directory.GetParent(Filename).Exists)
                    {
                        Directory.GetParent(Filename).Create();
                    }
                    File.Move(Path.ChangeExtension(tempName, "wav"), Filename);
                    if (File.Exists(tempName))
                    {
                        File.Delete(tempName);
                    }
                }
            }
            #endregion
            #region RAW
            else if (Format == SoundFormat.RAW)
            {
                foreach (int index in Indices)
                {
                    string Filename = (playback.PermutationCount == 1) ? Folder : Folder + "\\" + ugh_.SoundNames[ugh_.SoundPermutations[playback.FirstPermutation + index].NameIndex].Name + ".bin";
                    if (!Filename.EndsWith(".bin"))
                    {
                        Filename += ".bin";
                    }

                    if (File.Exists(Filename) && !Overwrite)
                    {
                        continue;
                    }

                    byte[] buffer = perms[index];

                    if (!Directory.GetParent(Filename).Exists)
                    {
                        Directory.GetParent(Filename).Create();
                    }

                    var          fs = new FileStream(Filename, FileMode.Create);
                    BinaryWriter sw = new BinaryWriter(fs);

                    sw.Write(buffer);
                    sw.Close();
                    sw.Dispose();
                }
            }
            #endregion
        }
示例#53
0
        private void UpdateMeta(MetaWriter.SaveType type, bool onlyUpdateChanged, bool showActionDialog = true)
        {
            if (type == MetaWriter.SaveType.File)
            {
                using (EndianWriter writer = new EndianWriter(_streamManager.OpenWrite(), Endian.BigEndian))
                {
                    MetaWriter metaUpdate = new MetaWriter(writer, _tag.RawTag.MetaLocation.AsOffset(), _cache, type, _fileChanges);
                    metaUpdate.WriteFields(_pluginVisitor.Values);
                    _fileChanges.MarkAllUnchanged();
                }

                if (showActionDialog)
                    MetroMessageBox.Show("Meta Saved", "The metadata has been saved back to the original file.");
            }
            else
            {
                if (Settings.xbdm.Connect())
                {
                    FieldChangeSet changes = onlyUpdateChanged ? _memoryChanges : null;
                    MetaWriter metaUpdate = new MetaWriter(Settings.xbdm.MemoryStream, _tag.RawTag.MetaLocation.AsAddress(), _cache, type, changes);
                    metaUpdate.WriteFields(_pluginVisitor.Values);
                    _memoryChanges.MarkAllUnchanged();

                    if (showActionDialog)
                    {
                        if (onlyUpdateChanged)
                            MetroMessageBox.Show("Meta Poked", "All changed metadata has been poked to your Xbox 360 console.");
                        else
                            MetroMessageBox.Show("Meta Poked", "The metadata has been poked to your Xbox 360 console.");
                    }
                }
                else
                {
                    MetroMessageBox.Show("Connection Error", "Unable to connect to your Xbox 360 console. Make sure that XBDM is enabled, you have the Xbox 360 SDK installed, and that your console's IP has been set correctly.");
                }
            }
        }
示例#54
0
        /// <summary>
        /// Saves all permutations of a sound tag concatenated as a single sound file.
        /// </summary>
        /// <param name="Filename">The file to save the data to.</param>
        /// <param name="Cache">The CacheFile containing the tag.</param>
        /// <param name="Tag">The sound tag.</param>
        /// <param name="Format">The format in which to save the data.</param>
        public static void SaveAllAsSingle(string Filename, CacheBase Cache, CacheBase.IndexItem Tag, SoundFormat Format)
        {
            var snd_ = DefinitionsManager.snd_(Cache, Tag);

            #region XMA
            if (Format == SoundFormat.XMA)
            {
                var total = GetTotalSize(Cache.ugh_, Cache.ugh_.PlayBacks[snd_.PlaybackIndex]);

                byte[] buffer = Cache.GetSoundRaw(snd_.RawID, total);

                if (buffer.Length == 0)
                {
                    throw new Exception("Empty raw data.");
                }
                var codec = Cache.ugh_.Codecs[snd_.CodecIndex];
                var xma   = GetXMA(buffer, snd_.SampleRate, codec.Type);

                if (!Directory.GetParent(Filename).Exists)
                {
                    Directory.GetParent(Filename).Create();
                }

                var          fs = File.OpenWrite(Filename);
                EndianWriter sw = new EndianWriter(fs, EndianFormat.BigEndian);
                sw.Write(xma);

                sw.Close();
                sw.Dispose();
            }
            #endregion
            #region WAV
            else if (Format == SoundFormat.WAV)
            {
                var tempName = Path.GetTempFileName();

                SaveAllAsSingle(tempName, Cache, Tag, SoundFormat.XMA);

                var info = new ProcessStartInfo(towav, tempName)
                {
                    CreateNoWindow   = true,
                    UseShellExecute  = false,
                    WorkingDirectory = Directory.GetParent(tempName).FullName
                };

                Process.Start(info).WaitForExit();

                if (File.Exists(Filename))
                {
                    File.Delete(Filename);
                }
                if (!Directory.GetParent(Filename).Exists)
                {
                    Directory.GetParent(Filename).Create();
                }
                File.Move(Path.ChangeExtension(tempName, "wav"), Filename);
                if (File.Exists(tempName))
                {
                    File.Delete(tempName);
                }
            }
            #endregion
            #region RAW
            else if (Format == SoundFormat.RAW)
            {
                byte[] buffer = Cache.GetSoundRaw(snd_.RawID, GetTotalSize(Cache.ugh_, Cache.ugh_.PlayBacks[snd_.PlaybackIndex]));

                if (!Directory.GetParent(Filename).Exists)
                {
                    Directory.GetParent(Filename).Create();
                }

                var          fs = new FileStream(Filename, FileMode.Create);
                BinaryWriter sw = new BinaryWriter(fs);

                sw.Write(buffer);
                sw.Close();
                sw.Dispose();
            }
            #endregion
            #region Other
            else
            {
                throw new InvalidOperationException("Invalid sound format received.");
            }
            #endregion
        }
示例#55
0
 public abstract void Serialize(EndianWriter writer);
        /// <summary>
        /// Extracts an xWMA sound and converts it to WAV.
        /// </summary>
        /// <param name="reader">The stream to read from.</param>
        /// <param name="offset">The offset of the data to extract.</param>
        /// <param name="rifx">The RIFX data for the sound.</param>
        /// <param name="outPath">The path of the file to save to.</param>
        public static void ExtractXWMAToWAV(EndianReader reader, int offset, RIFX rifx, string outPath)
        {
            // Create a temporary file to write an XWMA to
            string tempFile = Path.GetTempFileName();

            try
            {
                using (EndianWriter output = new EndianWriter(File.OpenWrite(tempFile), EndianFormat.BigEndian))
                {
                    // Generate a little-endian XWMA header
                    // TODO: move this into a class?
                    output.Write(0x52494646); // 'RIFF'

                    // Recompute the file size because the one Wwise gives us is trash
                    // fileSize = header size (always 0x2C) + dpds data size + data header size (always 0x8) + data size
                    int fileSize = 0x2C + rifx.SeekOffsets.Length * 0x4 + 0x8 + rifx.DataSize;
                    output.EndianType = EndianFormat.LittleEndian;
                    output.Write(fileSize);

                    output.EndianType = EndianFormat.BigEndian;
                    output.Write(RIFFFormat.XWMA);

                    // Generate the 'fmt ' chunk
                    output.Write(0x666D7420); // 'fmt '
                    output.EndianType = EndianFormat.LittleEndian;
                    output.Write(0x18); // Chunk size
                    output.Write(rifx.Codec);
                    output.Write(rifx.ChannelCount);
                    output.Write(rifx.SampleRate);
                    output.Write(rifx.BytesPerSecond);
                    output.Write(rifx.BlockAlign);
                    output.Write(rifx.BitsPerSample);

                    // Write the extradata
                    // Bytes 4 and 5 have to be flipped because they make up an int16
                    // TODO: add error checking to make sure the extradata is the correct size (0x6)
                    output.Write((short)0x6);
                    output.WriteBlock(rifx.ExtraData, 0, 4);
                    output.Write(rifx.ExtraData[5]);
                    output.Write(rifx.ExtraData[4]);

                    // Generate the 'dpds' chunk
                    // It's really just the 'seek' chunk from the original data but renamed
                    output.EndianType = EndianFormat.BigEndian;
                    output.Write(0x64706473); // 'dpds'

                    output.EndianType = EndianFormat.LittleEndian;
                    output.Write(rifx.SeekOffsets.Length * 4); // One uint32 per offset
                    foreach (int seek in rifx.SeekOffsets)
                        output.Write(seek);

                    // 'data' chunk
                    output.EndianType = EndianFormat.BigEndian;
                    output.Write(0x64617461); // 'data'
                    output.EndianType = EndianFormat.LittleEndian;
                    output.Write(rifx.DataSize);

                    // Copy the data chunk contents from the original RIFX
                    reader.SeekTo(offset + rifx.DataOffset);
                    StreamUtil.Copy(reader, output, rifx.DataSize);
                }

                // Convert it with xWMAEncode
                RunProgramSilently("Helpers/xWMAEncode.exe", "\"" + tempFile + "\" \"" + outPath + "\"", Directory.GetCurrentDirectory());
            }
            finally
            {
                // Delete the temporary XWMA file
                if (File.Exists(tempFile))
                    File.Delete(tempFile);
            }
        }
示例#57
0
		// Patch Creation
		private void btnCreatePatch_Click(object sender, RoutedEventArgs e)
		{
			try
			{
				// Check the user isn't completly retarded
				if (!CheckAllCreateMandatoryFields())
					return;

				// Check the user isn't a skid
				if (!CheckAllCreateMetaFilesExists())
					return;

				// Paths
				string cleanMapPath = txtCreatePatchUnModifiedMap.Text;
				string moddedMapPath = txtCreatePatchModifiedMap.Text;
				string outputPath = txtCreatePatchOutputPatch.Text;
				string previewImage = txtCreatePatchPreviewImage.Text;

				// Details
				string author = txtCreatePatchContentAuthor.Text;
				string desc = txtCreatePatchContentDescription.Text;
				string name = txtCreatePatchContentName.Text;
				string outputName = txtCreatePatchOutputName.Text;

				// Make dat patch
				var patch = new Patch
				{
					Author = author,
					Description = desc,
					Name = name,
					OutputName = outputName,
					Screenshot = String.IsNullOrEmpty(previewImage)
						? null
						: File.ReadAllBytes(previewImage)
				};

				EndianReader originalReader = null;
				EndianReader newReader = null;
				try
				{
					originalReader = new EndianReader(File.OpenRead(cleanMapPath), Endian.BigEndian);
					newReader = new EndianReader(File.OpenRead(moddedMapPath), Endian.BigEndian);

					ICacheFile originalFile = CacheFileLoader.LoadCacheFile(originalReader,
						App.AssemblyStorage.AssemblySettings.DefaultDatabase);
					ICacheFile newFile = CacheFileLoader.LoadCacheFile(newReader, App.AssemblyStorage.AssemblySettings.DefaultDatabase);

					if (cbCreatePatchHasCustomMeta.IsChecked != null && (bool) cbCreatePatchHasCustomMeta.IsChecked &&
					    cboxCreatePatchTargetGame.SelectedIndex < 4)
					{
						var targetGame = (TargetGame) cboxCreatePatchTargetGame.SelectedIndex;
						byte[] mapInfo = File.ReadAllBytes(txtCreatePatchMapInfo.Text);
						var mapInfoFileInfo = new FileInfo(txtCreatePatchMapInfo.Text);
						FileInfo blfFileInfo;

						patch.CustomBlfContent = new BlfContent(mapInfoFileInfo.FullName, mapInfo, targetGame);

						#region Blf Data

						if (PatchCreationBlfOption0.Visibility == Visibility.Visible)
						{
							blfFileInfo = new FileInfo(txtCreatePatchblf0.Text);
							patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
								File.ReadAllBytes(blfFileInfo.FullName)));
						}
						if (PatchCreationBlfOption1.Visibility == Visibility.Visible)
						{
							blfFileInfo = new FileInfo(txtCreatePatchblf1.Text);
							patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
								File.ReadAllBytes(blfFileInfo.FullName)));
						}
						if (PatchCreationBlfOption2.Visibility == Visibility.Visible)
						{
							blfFileInfo = new FileInfo(txtCreatePatchblf2.Text);
							patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
								File.ReadAllBytes(blfFileInfo.FullName)));
						}
						if (PatchCreationBlfOption3.Visibility == Visibility.Visible)
						{
							blfFileInfo = new FileInfo(txtCreatePatchblf3.Text);
							patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name,
								File.ReadAllBytes(blfFileInfo.FullName)));
						}

						#endregion
					}

					PatchBuilder.BuildPatch(originalFile, originalReader, newFile, newReader, patch);
				}
				finally
				{
					if (originalReader != null)
						originalReader.Close();
					if (newReader != null)
						newReader.Close();
				}

				IWriter output = new EndianWriter(File.Open(outputPath, FileMode.Create, FileAccess.Write), Endian.BigEndian);
				AssemblyPatchWriter.WritePatch(patch, output);
				output.Close();

				MetroMessageBox.Show("Patch Created!",
					"Your patch has been created in the designated location. Happy sailing, modder!");
			}
			catch (Exception ex)
			{
				MetroException.Show(ex);
			}
		}
示例#58
0
		public override void Write(EndianWriter s)
		{
			s.Write(Directory);
			s.Write(Files.Count);
			foreach (string str in Files.Keys)
			{
				List<string> files = Files[str];
				s.Write(str);
				s.Write(files.Count);
				foreach (string file in files)
					s.Write(file);
			}
		}
示例#59
0
 public void Write(EndianWriter writer, double?version) => writer.Write(Value);
示例#60
0
        private void extractTags(bool withRaw, TagEntry tag)
        {
            // Ask where to save the extracted tag collection
            var sfd = new SaveFileDialog
            {
                Title = "Save Tag Set",
                Filter = "Tag Container Files|*.tagc"
            };
            bool? result = sfd.ShowDialog();
            if (!result.Value)
                return;

            // Make a tag container
            var container = new TagContainer();

            // Recursively extract tags
            var tagsToProcess = new Queue<ITag>();
            var tagsProcessed = new HashSet<ITag>();
            var resourcesToProcess = new Queue<DatumIndex>();
            var resourcesProcessed = new HashSet<DatumIndex>();
            var resourcePagesProcessed = new HashSet<ResourcePage>();
            tagsToProcess.Enqueue(tag.RawTag);

            ResourceTable resources = null;
            using (var reader = _mapManager.OpenRead())
            {
                while (tagsToProcess.Count > 0)
                {
                    var currentTag = tagsToProcess.Dequeue();
                    if (tagsProcessed.Contains(currentTag))
                        continue;

                    // Get the plugin path
                    var className = VariousFunctions.SterilizeTagClassName(CharConstant.ToString(currentTag.Class.Magic)).Trim();
                    var pluginPath = string.Format("{0}\\{1}\\{2}.xml", VariousFunctions.GetApplicationLocation() + @"Plugins",
                        _buildInfo.Settings.GetSetting<string>("plugins"), className);

                    // Extract dem data blocks
                    var blockBuilder = new DataBlockBuilder(reader, currentTag, _cacheFile, _buildInfo);
                    using (var pluginReader = XmlReader.Create(pluginPath))
                        AssemblyPluginLoader.LoadPlugin(pluginReader, blockBuilder);

                    foreach (var block in blockBuilder.DataBlocks)
                        container.AddDataBlock(block);

                    // Add data for the tag that was extracted
                    var tagName = _cacheFile.FileNames.GetTagName(currentTag) ?? currentTag.Index.ToString();
                    var extractedTag = new ExtractedTag(currentTag.Index, currentTag.MetaLocation.AsPointer(), currentTag.Class.Magic,
                        tagName);
                    container.AddTag(extractedTag);

                    // Mark the tag as processed and then enqueue all of its child tags and resources
                    tagsProcessed.Add(currentTag);
                    foreach (var tagRef in blockBuilder.ReferencedTags)
                        tagsToProcess.Enqueue(_cacheFile.Tags[tagRef]);
                    foreach (var resource in blockBuilder.ReferencedResources)
                        resourcesToProcess.Enqueue(resource);
                }

                // Load the resource table in if necessary
                if (resourcesToProcess.Count > 0)
                    resources = _cacheFile.Resources.LoadResourceTable(reader);
            }

            // Extract resource info
            if (resources != null)
            {
                while (resourcesToProcess.Count > 0)
                {
                    var index = resourcesToProcess.Dequeue();
                    if (resourcesProcessed.Contains(index))
                        continue;

                    // Add the resource
                    var resource = resources.Resources[index.Index];
                    container.AddResource(new ExtractedResourceInfo(index, resource));

                    // Add data for its pages
                    if (resource.Location == null) continue;

                    if (resource.Location.PrimaryPage != null &&
                        !resourcePagesProcessed.Contains(resource.Location.PrimaryPage))
                    {
                        container.AddResourcePage(resource.Location.PrimaryPage);
                        resourcePagesProcessed.Add(resource.Location.PrimaryPage);

                        if (withRaw)
                        {
                            using (var fileStream = File.OpenRead(_cacheLocation))
                            {
                                var resourceFile = _cacheFile;
                                Stream resourceStream = fileStream;
                                if (resource.Location.PrimaryPage.FilePath != null)
                                {
                                    var resourceCacheInfo =
                                    App.AssemblyStorage.AssemblySettings.HalomapResourceCachePaths.FirstOrDefault(
                                        r => r.EngineName == _buildInfo.Name);

                                    var resourceCachePath = (resourceCacheInfo != null)
                                        ? resourceCacheInfo.ResourceCachePath
                                        : Path.GetDirectoryName(_cacheLocation);

                                    resourceCachePath = Path.Combine(resourceCachePath ?? "", Path.GetFileName(resource.Location.PrimaryPage.FilePath));

                                    if (!File.Exists(resourceCachePath))
                                    {
                                        MetroMessageBox.Show("Unable to extract tag",
                                            "Unable to extract tag, because a resource it relies on is in a external cache '{0}' that could not be found. Check Assembly's settings and set the file path to resource caches.");
                                        return;
                                    }

                                    resourceStream =
                                        File.OpenRead(resourceCachePath);
                                    resourceFile = new ThirdGenCacheFile(new EndianReader(resourceStream, Endian.BigEndian), _buildInfo,
                                        _cacheFile.BuildString);
                                }

                                var extractor = new ResourcePageExtractor(resourceFile);
                                byte[] pageData;
                                using (var pageStream = new MemoryStream())
                                {
                                    extractor.ExtractPage(resource.Location.PrimaryPage, resourceStream, pageStream);
                                    pageData = new byte[pageStream.Length];
                                    Buffer.BlockCopy(pageStream.GetBuffer(), 0, pageData, 0, (int) pageStream.Length);
                                }
                                container.AddExtractedResourcePage(new ExtractedPage(pageData, resource.Location.PrimaryPage.Index));
                            }
                        }
                    }
                    if (resource.Location.SecondaryPage == null || resourcePagesProcessed.Contains(resource.Location.SecondaryPage))
                        continue;

                    container.AddResourcePage(resource.Location.SecondaryPage);
                    resourcePagesProcessed.Add(resource.Location.SecondaryPage);

                    if (withRaw)
                    {
                        using (var fileStream = File.OpenRead(_cacheLocation))
                        {
                            var resourceFile = _cacheFile;
                            Stream resourceStream = fileStream;
                            if (resource.Location.SecondaryPage.FilePath != null)
                            {
                                var resourceCacheInfo =
                                    App.AssemblyStorage.AssemblySettings.HalomapResourceCachePaths.FirstOrDefault(
                                        r => r.EngineName == _buildInfo.Name);

                                var resourceCachePath = (resourceCacheInfo != null)
                                    ? resourceCacheInfo.ResourceCachePath
                                    : Path.GetDirectoryName(_cacheLocation);

                                resourceCachePath = Path.Combine(resourceCachePath ?? "", Path.GetFileName(resource.Location.SecondaryPage.FilePath));

                                if (!File.Exists(resourceCachePath))
                                {
                                    MetroMessageBox.Show("Unable to extract tag",
                                        "Unable to extract tag, because a resource it relies on is in a external cache '{0}' that could not be found. Check Assembly's settings and set the file path to resource caches.");
                                    return;
                                }

                                resourceStream =
                                    File.OpenRead(resourceCachePath);
                                resourceFile = new ThirdGenCacheFile(new EndianReader(resourceStream, Endian.BigEndian), _buildInfo,
                                    _cacheFile.BuildString);
                            }

                            var extractor = new ResourcePageExtractor(resourceFile);
                            byte[] pageData;
                            using (var pageStream = new MemoryStream())
                            {
                                extractor.ExtractPage(resource.Location.SecondaryPage, resourceStream, pageStream);
                                pageData = new byte[pageStream.Length];
                                Buffer.BlockCopy(pageStream.GetBuffer(), 0, pageData, 0, (int)pageStream.Length);
                            }
                            container.AddExtractedResourcePage(new ExtractedPage(pageData, resource.Location.SecondaryPage.Index));
                        }
                    }
                }
            }

            // Write it to a file
            using (var writer = new EndianWriter(File.Open(sfd.FileName, FileMode.Create, FileAccess.Write), Endian.BigEndian))
                TagContainerWriter.WriteTagContainer(container, writer);

            // YAY!
            MetroMessageBox.Show("Extraction Successful",
                "Extracted " +
                container.Tags.Count + " tag(s), " +
                container.DataBlocks.Count + " data block(s), " +
                container.ResourcePages.Count + " resource page pointer(s), " +
                container.ExtractedResourcePages.Count + " extracted resource page(s), and " +
                container.Resources.Count + " resource pointer(s).");
        }