From 778b3c1ee277377c65cf985edc0c047d083edccf Mon Sep 17 00:00:00 2001 From: Glatzemann Date: Mon, 27 Aug 2012 12:19:52 +0000 Subject: [PATCH] extended the XNB file format (without breaking compatibility) for ANX specific extensions --- .../AnxContentImporterContext.cs | 11 +--- .../ContentImporterContext.cs | 16 ++++- .../EffectImporter.cs | 2 +- .../Processors/HLSLCompiler.cs | 2 +- .../Serialization/Compiler/ContentWriter.cs | 5 +- ANX.Framework/Content/ContentReader.cs | 59 +++++++++++-------- Tools/XNBInspector/InspectReader.cs | 20 ++++++- Tools/XNBInspector/Properties/AssemblyInfo.cs | 4 +- 8 files changed, 75 insertions(+), 44 deletions(-) diff --git a/ANX.Framework.Content.Pipeline/AnxContentImporterContext.cs b/ANX.Framework.Content.Pipeline/AnxContentImporterContext.cs index 58396d21..deb4d33f 100644 --- a/ANX.Framework.Content.Pipeline/AnxContentImporterContext.cs +++ b/ANX.Framework.Content.Pipeline/AnxContentImporterContext.cs @@ -16,14 +16,13 @@ namespace ANX.Framework.Content.Pipeline public class AnxContentImporterContext : ContentImporterContext { private string intermediateDirectory; - private ContentBuildLogger logger; private string outputDirectory; public AnxContentImporterContext(BuildContent buildContent, BuildItem buildItem, ContentBuildLogger logger) + : base(logger) { BuildContent = buildContent; BuildItem = buildItem; - this.logger = logger; } public BuildContent BuildContent @@ -46,14 +45,6 @@ namespace ANX.Framework.Content.Pipeline } } - public override ContentBuildLogger Logger - { - get - { - return Logger; - } - } - public override string OutputDirectory { get diff --git a/ANX.Framework.Content.Pipeline/ContentImporterContext.cs b/ANX.Framework.Content.Pipeline/ContentImporterContext.cs index ea76104a..a0e4d5fe 100644 --- a/ANX.Framework.Content.Pipeline/ContentImporterContext.cs +++ b/ANX.Framework.Content.Pipeline/ContentImporterContext.cs @@ -14,14 +14,24 @@ namespace ANX.Framework.Content.Pipeline { public abstract class ContentImporterContext { - public ContentImporterContext() + public ContentImporterContext(ContentBuildLogger logger) { - //TODO: implement + if (logger == null) + { + throw new ArgumentNullException("logger"); + } + + this.Logger = logger; } public abstract string IntermediateDirectory { get; } - public abstract ContentBuildLogger Logger { get; } public abstract string OutputDirectory { get; } public abstract void AddDependency(string filename); + + public ContentBuildLogger Logger + { + get; + protected set; + } } } diff --git a/ANX.Framework.Content.Pipeline/EffectImporter.cs b/ANX.Framework.Content.Pipeline/EffectImporter.cs index d6c135b7..8e8749c4 100644 --- a/ANX.Framework.Content.Pipeline/EffectImporter.cs +++ b/ANX.Framework.Content.Pipeline/EffectImporter.cs @@ -13,7 +13,7 @@ using ANX.Framework.Content.Pipeline.Graphics; namespace ANX.Framework.Content.Pipeline { - [ContentImporter(".fx")] + [ContentImporter(new string[] { ".fx", ".fxg" })] public class EffectImporter : ContentImporter { public EffectImporter() diff --git a/ANX.Framework.Content.Pipeline/Processors/HLSLCompiler.cs b/ANX.Framework.Content.Pipeline/Processors/HLSLCompiler.cs index b4e89866..5d800152 100644 --- a/ANX.Framework.Content.Pipeline/Processors/HLSLCompiler.cs +++ b/ANX.Framework.Content.Pipeline/Processors/HLSLCompiler.cs @@ -121,7 +121,7 @@ namespace ANX.Framework.Content.Pipeline.Processors { if ((debugMode == EffectProcessorDebugMode.Auto && System.Diagnostics.Debugger.IsAttached) || debugMode == EffectProcessorDebugMode.Debug) { - return "/Od /Op /Zi"; + return "/Od /Op"; } else { diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentWriter.cs index a2d65e7e..f7fa1f77 100644 --- a/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentWriter.cs +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentWriter.cs @@ -30,7 +30,7 @@ namespace ANX.Framework.Content.Pipeline.Serialization.Compiler #endregion - const byte xnbFormatVersion = (byte)5; + const byte xnbFormatVersion = (byte)6; char[] xnbMagicWord = new char[] { 'X', 'N', 'B' }; internal ContentWriter(ContentCompiler compiler, Stream output, bool compressContent, string rootDirectory, string referenceRelocationPath) @@ -212,8 +212,9 @@ namespace ANX.Framework.Content.Pipeline.Serialization.Compiler Write(xnbMagicWord); // magic bytes for file recognition - 03 bytes Write((byte)TargetPlatform); // target platform of content file - 01 byte Write((byte)xnbFormatVersion); // version of this file - 01 byte + Write(new byte[] { (byte)'A', (byte)'N', (byte)'X' }); // ANX magic word - 03 byte Write((byte)(TargetProfile == GraphicsProfile.HiDef ? 0x01 : 0x00)); // flags - 01 byte - Write((int)header.Length + (int)content.Length + 10); // size of file - 04 byte + Write((int)header.Length + (int)content.Length + 13); // size of file - 04 byte if (compressContent) { //TODO: write compressed size diff --git a/ANX.Framework/Content/ContentReader.cs b/ANX.Framework/Content/ContentReader.cs index a0ad17e9..b9291dd1 100644 --- a/ANX.Framework/Content/ContentReader.cs +++ b/ANX.Framework/Content/ContentReader.cs @@ -15,7 +15,7 @@ namespace ANX.Framework.Content { public sealed class ContentReader : BinaryReader { - private int graphicsProfile; + private GraphicsProfile graphicsProfile; private List>[] sharedResourceFixups; @@ -23,13 +23,14 @@ namespace ANX.Framework.Content public ContentManager ContentManager { get; private set; } + public bool AnxExtensions { get; private set; } public string AssetName { get; private set; } private string assetDirectory; - private ContentReader( - ContentManager contentManager, Stream input, string assetName, int graphicsProfile) + private ContentReader(ContentManager contentManager, Stream input, string assetName, GraphicsProfile graphicsProfile, bool anxExtensions) : base(input) { + this.AnxExtensions = anxExtensions; this.ContentManager = contentManager; this.AssetName = assetName; this.graphicsProfile = graphicsProfile; @@ -45,20 +46,23 @@ namespace ANX.Framework.Content public static ContentReader Create( ContentManager contentManager, Stream input, string assetName) { - int num; - input = ContentReader.ReadXnbHeader(input, assetName, out num); - return new ContentReader(contentManager, input, assetName, num); + GraphicsProfile profile; + bool anxExtensions; + + input = ContentReader.ReadXnbHeader(input, assetName, out profile, out anxExtensions); + return new ContentReader(contentManager, input, assetName, profile, anxExtensions); } - public static T ReadAsset( - ContentManager contentManager, Stream input, string assetName) + public static T ReadAsset(ContentManager contentManager, Stream input, string assetName) { - int num; - input = ContentReader.ReadXnbHeader(input, assetName, out num); - return new ContentReader(contentManager, input, assetName, num).ReadAsset(); + GraphicsProfile profile; + bool anxExtensions; + + input = ContentReader.ReadXnbHeader(input, assetName, out profile, out anxExtensions); + return new ContentReader(contentManager, input, assetName, profile, anxExtensions).ReadAsset(); } - private static Stream ReadXnbHeader(Stream input, string assetName, out int graphicsProfile) + private static Stream ReadXnbHeader(Stream input, string assetName, out GraphicsProfile graphicsProfile, out bool anxExtensions) { // read the XNB file information // @@ -75,6 +79,8 @@ namespace ANX.Framework.Content // | | | x = Xbox 360 // |--------|----------------------|-------------------------------- // | Byte | XNB format version | 5 = XNA Game Studio 4.0 + // | | | 6 = future XNA version + // | | | OR anx version if the next three bytes are ANX // |--------|----------------------|-------------------------------- // | Byte | Flag bits | Bit 0x01 = content is for HiDef profile (otherwise Reach) // | | | Bit 0x80 = asset data is compressed @@ -83,6 +89,7 @@ namespace ANX.Framework.Content // | | | .xnb file as stored on disk (including this header block) BinaryReader reader = new BinaryReader(input); + anxExtensions = false; byte magicX = reader.ReadByte(); byte magicN = reader.ReadByte(); @@ -109,29 +116,33 @@ namespace ANX.Framework.Content byte formatVersion = reader.ReadByte(); - if (formatVersion != 5) + if (formatVersion == 6) + { + byte magicVA = reader.ReadByte(); // A + byte magicVN = reader.ReadByte(); // N + byte magicVX = reader.ReadByte(); // X + + if (magicVA != 'A' || magicVN != 'N' || magicVX != 'X') + { + throw new ContentLoadException("Not an ANX.Framework version 1.0 XNB file."); + } + + anxExtensions = true; + } + else if (formatVersion != 5) { throw new ContentLoadException("Not an XNA Game Studio version 4.0 XNB file."); } byte flags = reader.ReadByte(); - if ((flags & 0x01) == 0x01) - { - // HiDef Profile - graphicsProfile = 1; - } - else - { - // Reach Profile - graphicsProfile = 0; - } + graphicsProfile = ((flags & 0x01) == 0x01 ? GraphicsProfile.HiDef : GraphicsProfile.Reach); bool isCompressed = (flags & 0x80) != 0; int sizeOnDisk = reader.ReadInt32(); - if (input.CanSeek && ((sizeOnDisk - 10) > (input.Length - input.Position))) + if (input.CanSeek && ((sizeOnDisk - (anxExtensions ? 13 : 10)) > (input.Length - input.Position))) { throw new ContentLoadException("Bad XNB file size."); } diff --git a/Tools/XNBInspector/InspectReader.cs b/Tools/XNBInspector/InspectReader.cs index 0fa797cc..392190c6 100644 --- a/Tools/XNBInspector/InspectReader.cs +++ b/Tools/XNBInspector/InspectReader.cs @@ -45,6 +45,8 @@ namespace ANX.Tools.XNBInspector // | | | x = Xbox 360 // |--------|----------------------|-------------------------------- // | Byte | XNB format version | 5 = XNA Game Studio 4.0 + // | | | 6 = future XNA version + // | | | OR anx version if the next three bytes are ANX // |--------|----------------------|-------------------------------- // | Byte | Flag bits | Bit 0x01 = content is for HiDef profile (otherwise Reach) // | | | Bit 0x80 = asset data is compressed @@ -141,8 +143,24 @@ namespace ANX.Tools.XNBInspector case 5: result.Append(Severity.Success, "5 (XNA Game Studio 4.0)"); break; + case 6: + byte magicVA = reader.ReadByte(); // A + byte magicVN = reader.ReadByte(); // N + byte magicVX = reader.ReadByte(); // X + + if (magicVA == 'A' && magicVN == 'N' && magicVX == 'X') + { + result.Append(Severity.Success, "6 with additional magic bytes (ANX.Framework 1.0)"); + } + else + { + reader.BaseStream.Seek(-3, SeekOrigin.Current); + result.AppendFormat(Severity.Warning, "{0} (Unknown or non XNA/ANX content)", formatVersion); + + } + break; default: - result.AppendFormat(Severity.Warning, "{0} (Unknown or non XNA content)", formatVersion); + result.AppendFormat(Severity.Warning, "{0} (Unknown or non XNA/ANX content)", formatVersion); break; } result.AppendLine(); diff --git a/Tools/XNBInspector/Properties/AssemblyInfo.cs b/Tools/XNBInspector/Properties/AssemblyInfo.cs index d73a14a7..580c317b 100644 --- a/Tools/XNBInspector/Properties/AssemblyInfo.cs +++ b/Tools/XNBInspector/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.3.1.0")] -[assembly: AssemblyFileVersion("0.3.1.0")] +[assembly: AssemblyVersion("0.3.2.0")] +[assembly: AssemblyFileVersion("0.3.2.0")]