protected internal override TextureCube Read(ContentReader reader, TextureCube existingInstance) { TextureCube textureCube = null; SurfaceFormat surfaceFormat = (SurfaceFormat)reader.ReadInt32(); int size = reader.ReadInt32(); int levels = reader.ReadInt32(); if (existingInstance == null) textureCube = new TextureCube(reader.GetGraphicsDevice(), size, levels > 1, surfaceFormat); else textureCube = existingInstance; #if OPENGL Threading.BlockOnUIThread(() => { #endif for (int face = 0; face < 6; face++) { for (int i = 0; i < levels; i++) { int faceSize = reader.ReadInt32(); byte[] faceData = ContentManager.ScratchBufferPool.Get(faceSize); reader.Read(faceData, 0, faceSize); textureCube.SetData<byte>((CubeMapFace)face, i, null, faceData, 0, faceSize); ContentManager.ScratchBufferPool.Return(faceData); } } #if OPENGL }); #endif return textureCube; }
protected internal override Texture3D Read(ContentReader reader, Texture3D existingInstance) { Texture3D texture = null; SurfaceFormat format = (SurfaceFormat)reader.ReadInt32(); int width = reader.ReadInt32(); int height = reader.ReadInt32(); int depth = reader.ReadInt32(); int levelCount = reader.ReadInt32(); if (existingInstance == null) { texture = new Texture3D(reader.GraphicsDevice, width, height, depth, levelCount > 1, format); } else { texture = existingInstance; } for (int i = 0; i < levelCount; i++) { int dataSize = reader.ReadInt32(); byte[] data = reader.ContentManager.GetScratchBuffer(dataSize); reader.Read(data, 0, dataSize); texture.SetData(i, 0, 0, width, height, 0, depth, data, 0, dataSize); // Calculate dimensions of next mip level. width = Math.Max(width >> 1, 1); height = Math.Max(height >> 1, 1); depth = Math.Max(depth >> 1, 1); } return(texture); }
protected internal override TextureCube Read(ContentReader reader, TextureCube existingInstance) { TextureCube textureCube = null; SurfaceFormat surfaceFormat = (SurfaceFormat)reader.ReadInt32(); int size = reader.ReadInt32(); int levels = reader.ReadInt32(); if (existingInstance == null) { textureCube = new TextureCube(reader.GraphicsDevice, size, levels > 1, surfaceFormat); } else { textureCube = existingInstance; } for (int face = 0; face < 6; face++) { for (int i = 0; i < levels; i++) { int faceSize = reader.ReadInt32(); byte[] faceData = reader.ContentManager.GetScratchBuffer(faceSize); reader.Read(faceData, 0, faceSize); textureCube.SetData <byte>((CubeMapFace)face, i, null, faceData, 0, faceSize); } } return(textureCube); }
protected internal override Effect Read(ContentReader input, Effect existingInstance) { int dataSize = input.ReadInt32(); byte[] data = input.ContentManager.GetScratchBuffer(dataSize); input.Read(data, 0, dataSize); var effect = new Effect(input.GraphicsDevice, data, 0, dataSize); effect.Name = input.AssetName; return(effect); }
protected internal override VertexBuffer Read(ContentReader input, VertexBuffer existingInstance) { var declaration = input.ReadRawObject <VertexDeclaration>(); var vertexCount = (int)input.ReadUInt32(); int dataSize = vertexCount * declaration.VertexStride; byte[] data = input.ContentManager.GetScratchBuffer(dataSize); input.Read(data, 0, dataSize); var buffer = new VertexBuffer(input.GraphicsDevice, declaration, vertexCount, BufferUsage.None); buffer.SetData(data, 0, dataSize); return(buffer); }
protected internal override SoundEffect Read(ContentReader input, SoundEffect existingInstance) { // XNB format for SoundEffect... // // Byte [format size] Format WAVEFORMATEX structure // UInt32 Data size // Byte [data size] Data Audio waveform data // Int32 Loop start In bytes (start must be format block aligned) // Int32 Loop length In bytes (length must be format block aligned) // Int32 Duration In milliseconds // The header containss the WAVEFORMATEX header structure // defined as the following... // // WORD wFormatTag; // byte[0] +2 // WORD nChannels; // byte[2] +2 // DWORD nSamplesPerSec; // byte[4] +4 // DWORD nAvgBytesPerSec; // byte[8] +4 // WORD nBlockAlign; // byte[12] +2 // WORD wBitsPerSample; // byte[14] +2 // WORD cbSize; // byte[16] +2 // // We let the sound effect deal with parsing this based // on what format the audio data actually is. var headerSize = input.ReadInt32(); var header = input.ReadBytes(headerSize); // Read the audio data buffer. var dataSize = input.ReadInt32(); var data = ContentManager.ScratchBufferPool.Get(dataSize); input.Read(data, 0, dataSize); var loopStart = input.ReadInt32(); var loopLength = input.ReadInt32(); var durationMs = input.ReadInt32(); // Create the effect. var effect = new SoundEffect(header, data, dataSize, durationMs, loopStart, loopLength); // Store the original asset name for debugging later. effect.Name = input.AssetName; ContentManager.ScratchBufferPool.Return(data); return(effect); }
protected internal override IndexBuffer Read(ContentReader input, IndexBuffer existingInstance) { IndexBuffer indexBuffer = existingInstance; bool sixteenBits = input.ReadBoolean(); int dataSize = input.ReadInt32(); byte[] data = input.ContentManager.GetScratchBuffer(dataSize); input.Read(data, 0, dataSize); if (indexBuffer == null) { indexBuffer = new IndexBuffer(input.GraphicsDevice, sixteenBits ? IndexElementSize.SixteenBits : IndexElementSize.ThirtyTwoBits, dataSize / (sixteenBits ? 2 : 4), BufferUsage.None); } indexBuffer.SetData(data, 0, dataSize); return(indexBuffer); }
protected internal override Texture3D Read(ContentReader reader, Texture3D existingInstance) { Texture3D texture = null; SurfaceFormat format = (SurfaceFormat)reader.ReadInt32(); int width = reader.ReadInt32(); int height = reader.ReadInt32(); int depth = reader.ReadInt32(); int levelCount = reader.ReadInt32(); if (existingInstance == null) texture = new Texture3D(reader.GetGraphicsDevice(), width, height, depth, levelCount > 1, format); else texture = existingInstance; #if OPENGL Threading.BlockOnUIThread(() => { #endif for (int i = 0; i < levelCount; i++) { int dataSize = reader.ReadInt32(); byte[] data = ContentManager.ScratchBufferPool.Get(dataSize); reader.Read(data, 0, dataSize); texture.SetData(i, 0, 0, width, height, 0, depth, data, 0, dataSize); // Calculate dimensions of next mip level. width = Math.Max(width >> 1, 1); height = Math.Max(height >> 1, 1); depth = Math.Max(depth >> 1, 1); ContentManager.ScratchBufferPool.Return(data); } #if OPENGL }); #endif return texture; }
public ContentTypeReader[] LoadAssetReaders(ContentReader reader) { int numberOfReaders; ContentTypeReader[] contentReaders; // The first 4 bytes should be the "XNBw" header. i use that to detect an invalid file byte[] headerBuffer = new byte[4]; reader.Read(headerBuffer, 0, 4); string headerString = Encoding.UTF8.GetString(headerBuffer, 0, 4); if (string.Compare(headerString, "XNBw", StringComparison.InvariantCultureIgnoreCase) != 0) { throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?"); } // I think these two bytes are some kind of version number. Either for the XNB file or the type readers /*byte version =*/ reader.ReadByte(); byte compressed = reader.ReadByte(); // The next int32 is the length of the XNB file /*int xnbLength = */reader.ReadInt32(); if (compressed != 0) { throw new NotImplementedException("MonoGame cannot read compressed XNB files. Please use the XNB files from the Debug build of your XNA game instead. If someone wants to contribute decompression logic, that would be fantastic."); } // The next byte i read tells me the number of content readers in this XNB file numberOfReaders = reader.ReadByte(); contentReaders = new ContentTypeReader[numberOfReaders]; // For each reader in the file, we read out the length of the string which contains the type of the reader, // then we read out the string. Finally we instantiate an instance of that reader using reflection for (int i = 0; i < numberOfReaders; i++) { // This string tells us what reader we need to decode the following data // string readerTypeString = reader.ReadString(); string originalReaderTypeString = reader.ReadString(); // Need to resolve namespace differences string readerTypeString = originalReaderTypeString; readerTypeString = PrepareType(readerTypeString); Type l_readerType = Type.GetType(readerTypeString); if (l_readerType != null) contentReaders[i] = (ContentTypeReader)Activator.CreateInstance(l_readerType, true); else { throw new ContentLoadException("Could not find matching content reader of type " + originalReaderTypeString + " (" + readerTypeString + ")"); } // I think the next 4 bytes refer to the "Version" of the type reader, // although it always seems to be zero /*int typeReaderVersion =*/ reader.ReadInt32(); } return contentReaders; }
public ContentTypeReader[] LoadAssetReaders(ContentReader reader) { // Dummy variables required for it to work on iDevices ** DO NOT DELETE ** // This forces the classes not to be optimized out when deploying to iDevices ListReader <Char> hCharListReader = new ListReader <Char>(); ListReader <Rectangle> hRectangleListReader = new ListReader <Rectangle>(); ListReader <Vector3> hVector3ListReader = new ListReader <Vector3>(); ListReader <StringReader> hStringListReader = new ListReader <StringReader>(); SpriteFontReader hSpriteFontReader = new SpriteFontReader(); Texture2DReader hTexture2DReader = new Texture2DReader(); CharReader hCharReader = new CharReader(); RectangleReader hRectangleReader = new RectangleReader(); StringReader hStringReader = new StringReader(); Vector3Reader hVector3Reader = new Vector3Reader(); int numberOfReaders; ContentTypeReader[] contentReaders; // The first 4 bytes should be the "XNBw" header. i use that to detect an invalid file byte[] headerBuffer = new byte[4]; reader.Read(headerBuffer, 0, 4); string headerString = Encoding.UTF8.GetString(headerBuffer, 0, 4); if (string.Compare(headerString, "XNBw", StringComparison.InvariantCultureIgnoreCase) != 0 && string.Compare(headerString, "XNBx", StringComparison.InvariantCultureIgnoreCase) != 0 && string.Compare(headerString, "XNBm", StringComparison.InvariantCultureIgnoreCase) != 0) { throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?"); } // I think these two bytes are some kind of version number. Either for the XNB file or the type readers byte version = reader.ReadByte(); if (version != 5) { throw new ContentLoadException("Invalid XNB file version."); } byte compressed = reader.ReadByte(); // The next int32 is the length of the XNB file int xnbLength = reader.ReadInt32(); if (compressed != 0) { throw new NotImplementedException("MonoGame cannot read compressed XNB files. Please use the XNB files from the Debug build of your XNA game instead. If someone wants to contribute decompression logic, that would be fantastic."); } // The next byte i read tells me the number of content readers in this XNB file numberOfReaders = reader.ReadByte(); contentReaders = new ContentTypeReader[numberOfReaders]; // For each reader in the file, we read out the length of the string which contains the type of the reader, // then we read out the string. Finally we instantiate an instance of that reader using reflection for (int i = 0; i < numberOfReaders; i++) { // This string tells us what reader we need to decode the following data // string readerTypeString = reader.ReadString(); string originalReaderTypeString = reader.ReadString(); // Need to resolve namespace differences string readerTypeString = originalReaderTypeString; readerTypeString = PrepareType(readerTypeString); Type l_readerType = Type.GetType(readerTypeString); if (l_readerType != null) { contentReaders[i] = (ContentTypeReader)Activator.CreateInstance(l_readerType, true); } else { throw new ContentLoadException("Could not find matching content reader of type " + originalReaderTypeString + " (" + readerTypeString + ")"); } // I think the next 4 bytes refer to the "Version" of the type reader, // although it always seems to be zero int typeReaderVersion = reader.ReadInt32(); } return(contentReaders); }
protected internal override Texture2D Read(ContentReader reader, Texture2D existingInstance) { Texture2D texture = null; var surfaceFormat = (SurfaceFormat)reader.ReadInt32(); int width = reader.ReadInt32(); int height = reader.ReadInt32(); int levelCount = reader.ReadInt32(); int levelCountOutput = levelCount; // If the system does not fully support Power of Two textures, // skip any mip maps supplied with any non PoT textures. if (levelCount > 1 && !reader.GraphicsDevice.GraphicsCapabilities.SupportsNonPowerOfTwo && (!MathHelper.IsPowerOfTwo(width) || !MathHelper.IsPowerOfTwo(height))) { levelCountOutput = 1; System.Diagnostics.Debug.WriteLine( "Device does not support non Power of Two textures. Skipping mipmaps."); } SurfaceFormat convertedFormat = surfaceFormat; switch (surfaceFormat) { case SurfaceFormat.Dxt1: case SurfaceFormat.Dxt1a: if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsDxt1) convertedFormat = SurfaceFormat.Color; break; case SurfaceFormat.Dxt1SRgb: if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsDxt1) convertedFormat = SurfaceFormat.ColorSRgb; break; case SurfaceFormat.Dxt3: case SurfaceFormat.Dxt5: if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsS3tc) convertedFormat = SurfaceFormat.Color; break; case SurfaceFormat.Dxt3SRgb: case SurfaceFormat.Dxt5SRgb: if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsS3tc) convertedFormat = SurfaceFormat.ColorSRgb; break; case SurfaceFormat.NormalizedByte4: convertedFormat = SurfaceFormat.Color; break; } texture = existingInstance ?? new Texture2D(reader.GraphicsDevice, width, height, levelCountOutput > 1, convertedFormat); #if OPENGL Threading.BlockOnUIThread(() => { #endif for (int level = 0; level < levelCount; level++) { var levelDataSizeInBytes = reader.ReadInt32(); var levelData = reader.ContentManager.GetScratchBuffer(levelDataSizeInBytes); reader.Read(levelData, 0, levelDataSizeInBytes); int levelWidth = width >> level; int levelHeight = height >> level; if (level >= levelCountOutput) continue; //Convert the image data if required switch (surfaceFormat) { case SurfaceFormat.Dxt1: case SurfaceFormat.Dxt1SRgb: case SurfaceFormat.Dxt1a: if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsDxt1 && convertedFormat == SurfaceFormat.Color) { levelData = DxtUtil.DecompressDxt1(levelData, levelWidth, levelHeight); levelDataSizeInBytes = levelData.Length; } break; case SurfaceFormat.Dxt3: case SurfaceFormat.Dxt3SRgb: if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsS3tc) if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsS3tc && convertedFormat == SurfaceFormat.Color) { levelData = DxtUtil.DecompressDxt3(levelData, levelWidth, levelHeight); levelDataSizeInBytes = levelData.Length; } break; case SurfaceFormat.Dxt5: case SurfaceFormat.Dxt5SRgb: if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsS3tc) if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsS3tc && convertedFormat == SurfaceFormat.Color) { levelData = DxtUtil.DecompressDxt5(levelData, levelWidth, levelHeight); levelDataSizeInBytes = levelData.Length; } break; case SurfaceFormat.Bgra5551: { #if OPENGL // Shift the channels to suit OpenGL int offset = 0; for (int y = 0; y < levelHeight; y++) { for (int x = 0; x < levelWidth; x++) { ushort pixel = BitConverter.ToUInt16(levelData, offset); pixel = (ushort)(((pixel & 0x7FFF) << 1) | ((pixel & 0x8000) >> 15)); levelData[offset] = (byte)(pixel); levelData[offset + 1] = (byte)(pixel >> 8); offset += 2; } } #endif } break; case SurfaceFormat.Bgra4444: { #if OPENGL // Shift the channels to suit OpenGL int offset = 0; for (int y = 0; y < levelHeight; y++) { for (int x = 0; x < levelWidth; x++) { ushort pixel = BitConverter.ToUInt16(levelData, offset); pixel = (ushort)(((pixel & 0x0FFF) << 4) | ((pixel & 0xF000) >> 12)); levelData[offset] = (byte)(pixel); levelData[offset + 1] = (byte)(pixel >> 8); offset += 2; } } #endif } break; case SurfaceFormat.NormalizedByte4: { int bytesPerPixel = surfaceFormat.GetSize(); int pitch = levelWidth * bytesPerPixel; for (int y = 0; y < levelHeight; y++) { for (int x = 0; x < levelWidth; x++) { int color = BitConverter.ToInt32(levelData, y * pitch + x * bytesPerPixel); levelData[y * pitch + x * 4] = (byte)(((color >> 16) & 0xff)); //R:=W levelData[y * pitch + x * 4 + 1] = (byte)(((color >> 8) & 0xff)); //G:=V levelData[y * pitch + x * 4 + 2] = (byte)(((color) & 0xff)); //B:=U levelData[y * pitch + x * 4 + 3] = (byte)(((color >> 24) & 0xff)); //A:=Q } } } break; } texture.SetData(level, null, levelData, 0, levelDataSizeInBytes); } #if OPENGL }); #endif return texture; }
public ContentTypeReader[] LoadAssetReaders(ContentReader reader) { int numberOfReaders; ContentTypeReader[] contentReaders; // The first 4 bytes should be the "XNBw" header. i use that to detect an invalid file byte[] headerBuffer = new byte[4]; reader.Read(headerBuffer, 0, 4); string headerString = Encoding.UTF8.GetString(headerBuffer, 0, 4); if (string.Compare(headerString, "XNBw", StringComparison.InvariantCultureIgnoreCase) != 0) { throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?"); } // I think these two bytes are some kind of version number. Either for the XNB file or the type readers /*byte version =*/ reader.ReadByte(); byte compressed = reader.ReadByte(); // The next int32 is the length of the XNB file /*int xnbLength = */ reader.ReadInt32(); if (compressed != 0) { throw new NotImplementedException("MonoGame cannot read compressed XNB files. Please use the XNB files from the Debug build of your XNA game instead. If someone wants to contribute decompression logic, that would be fantastic."); } // The next byte i read tells me the number of content readers in this XNB file numberOfReaders = reader.ReadByte(); contentReaders = new ContentTypeReader[numberOfReaders]; // For each reader in the file, we read out the length of the string which contains the type of the reader, // then we read out the string. Finally we instantiate an instance of that reader using reflection for (int i = 0; i < numberOfReaders; i++) { // This string tells us what reader we need to decode the following data // string readerTypeString = reader.ReadString(); string originalReaderTypeString = reader.ReadString(); // Need to resolve namespace differences string readerTypeString = originalReaderTypeString; readerTypeString = PrepareType(readerTypeString); Type l_readerType = Type.GetType(readerTypeString); if (l_readerType != null) { contentReaders[i] = (ContentTypeReader)Activator.CreateInstance(l_readerType, true); } else { throw new ContentLoadException("Could not find matching content reader of type " + originalReaderTypeString + " (" + readerTypeString + ")"); } // I think the next 4 bytes refer to the "Version" of the type reader, // although it always seems to be zero /*int typeReaderVersion =*/ reader.ReadInt32(); } return(contentReaders); }
public ContentTypeReader[] LoadAssetReaders(ContentReader reader) { // Dummy variables required for it to work on iDevices ** DO NOT DELETE ** // This forces the classes not to be optimized out when deploying to iDevices ListReader<Char> hCharListReader = new ListReader<Char>(); ListReader<Rectangle> hRectangleListReader = new ListReader<Rectangle>(); ListReader<Vector3> hVector3ListReader = new ListReader<Vector3>(); ListReader<StringReader> hStringListReader = new ListReader<StringReader>(); SpriteFontReader hSpriteFontReader = new SpriteFontReader(); Texture2DReader hTexture2DReader = new Texture2DReader(); CharReader hCharReader = new CharReader(); RectangleReader hRectangleReader = new RectangleReader(); StringReader hStringReader = new StringReader(); Vector3Reader hVector3Reader = new Vector3Reader(); int numberOfReaders; ContentTypeReader[] contentReaders; // The first 4 bytes should be the "XNBw" header. i use that to detect an invalid file byte[] headerBuffer = new byte[4]; reader.Read(headerBuffer, 0, 4); string headerString = Encoding.UTF8.GetString(headerBuffer, 0, 4); if (string.Compare(headerString, "XNBw", StringComparison.InvariantCultureIgnoreCase) != 0 && string.Compare(headerString, "XNBx", StringComparison.InvariantCultureIgnoreCase) != 0 && string.Compare(headerString, "XNBm", StringComparison.InvariantCultureIgnoreCase) != 0) throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?"); // I think these two bytes are some kind of version number. Either for the XNB file or the type readers byte version = reader.ReadByte(); if(version != 5) throw new ContentLoadException("Invalid XNB file version."); byte compressed = reader.ReadByte(); // The next int32 is the length of the XNB file int xnbLength = reader.ReadInt32(); if (compressed != 0 && compressed != 1) { throw new NotImplementedException("MonoGame cannot read compressed XNB files. Please use the XNB files from the Debug build of your XNA game instead. If someone wants to contribute decompression logic, that would be fantastic."); } // The next byte i read tells me the number of content readers in this XNB file numberOfReaders = reader.ReadByte(); contentReaders = new ContentTypeReader[numberOfReaders]; // For each reader in the file, we read out the length of the string which contains the type of the reader, // then we read out the string. Finally we instantiate an instance of that reader using reflection for (int i = 0; i < numberOfReaders; i++) { // This string tells us what reader we need to decode the following data // string readerTypeString = reader.ReadString(); string originalReaderTypeString = reader.ReadString(); // Need to resolve namespace differences string readerTypeString = originalReaderTypeString; readerTypeString = PrepareType(readerTypeString); Type l_readerType = Type.GetType(readerTypeString); if(l_readerType !=null) contentReaders[i] = (ContentTypeReader)Activator.CreateInstance(l_readerType,true); else throw new ContentLoadException("Could not find matching content reader of type " + originalReaderTypeString + " (" + readerTypeString + ")"); // I think the next 4 bytes refer to the "Version" of the type reader, // although it always seems to be zero int typeReaderVersion = reader.ReadInt32(); } return contentReaders; }
public ContentTypeReader[] LoadAssetReaders(ContentReader reader) { // Dummy variables required for it to work on iDevices ** DO NOT DELETE ** // This forces the classes not to be optimized out when deploying to iDevices ListReader<Char> hCharListReader = new ListReader<Char>(); ListReader<Rectangle> hRectangleListReader = new ListReader<Rectangle>(); ListReader<Vector3> hVector3ListReader = new ListReader<Vector3>(); ListReader<StringReader> hStringListReader = new ListReader<StringReader>(); SpriteFontReader hSpriteFontReader = new SpriteFontReader(); Texture2DReader hTexture2DReader = new Texture2DReader(); CharReader hCharReader = new CharReader(); RectangleReader hRectangleReader = new RectangleReader(); StringReader hStringReader = new StringReader(); Vector3Reader hVector3Reader = new Vector3Reader(); int numberOfReaders; ContentTypeReader[] contentReaders; // The first 4 bytes should be the "XNBw" header. i use that to detect an invalid file byte[] headerBuffer = new byte[4]; reader.Read(headerBuffer, 0, 4); string headerString = Encoding.UTF8.GetString(headerBuffer, 0, 4); if (string.Compare(headerString, "XNBw", StringComparison.InvariantCultureIgnoreCase) != 0) throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?"); // I think these two bytes are some kind of version number. Either for the XNB file or the type readers byte version = reader.ReadByte(); byte compressed = reader.ReadByte(); // The next int32 is the length of the XNB file int xnbLength = reader.ReadInt32(); if (compressed != 0) { throw new NotImplementedException("MonoGame cannot read compressed XNB files. Please use the XNB files from the Debug build of your XNA game instead. If someone wants to contribute decompression logic, that would be fantastic."); } // The next byte i read tells me the number of content readers in this XNB file numberOfReaders = reader.ReadByte(); contentReaders = new ContentTypeReader[numberOfReaders]; // For each reader in the file, we read out the length of the string which contains the type of the reader, // then we read out the string. Finally we instantiate an instance of that reader using reflection for (int i = 0; i < numberOfReaders; i++) { // This string tells us what reader we need to decode the following data // string readerTypeString = reader.ReadString(); string originalReaderTypeString = reader.ReadString(); // Need to resolve namespace differences string readerTypeString = originalReaderTypeString; /*if(readerTypeString.IndexOf(", Microsoft.Xna.Framework") != -1) { string[] tokens = readerTypeString.Split(new char[] { ',' }); readerTypeString = ""; for(int j = 0; j < tokens.Length; j++) { if(j != 0) readerTypeString += ","; if(j == 1) readerTypeString += " Microsoft.Xna.Framework"; else readerTypeString += tokens[j]; } readerTypeString = readerTypeString.Replace(", Microsoft.Xna.Framework", "@"); }*/ if(readerTypeString.Contains("PublicKey")) { //if (readerTypeString.Contains("[[")) { readerTypeString = readerTypeString.Split(new char[] { '[', '[' })[0] + "[" + readerTypeString.Split(new char[] { '[', '[' })[2].Split(',')[0] + "]"; //} //else { // // If the readerTypeString did not contain "[[" to split the // // types then we assume it is XNA 4.0 which splits the types // // by ', ' // readerTypeString = readerTypeString.Split(new char[] { ',', ' '})[0]; // //} } readerTypeString = readerTypeString.Replace("Microsoft.Xna.Framework", "Microsoft.Xna.Framework"); Type l_readerType = Type.GetType(readerTypeString); if(l_readerType !=null) contentReaders[i] = (ContentTypeReader)Activator.CreateInstance(l_readerType,true); else throw new ContentLoadException("Could not find matching content reader of type " + originalReaderTypeString); // I think the next 4 bytes refer to the "Version" of the type reader, // although it always seems to be zero int typeReaderVersion = reader.ReadInt32(); } return contentReaders; }
public ContentTypeReader[] LoadAssetReaders(ContentReader reader) { // Dummy variables required for it to work on iDevices ** DO NOT DELETE ** // This forces the classes not to be optimized out when deploying to iDevices ListReader <Char> hCharListReader = new ListReader <Char>(); ListReader <Rectangle> hRectangleListReader = new ListReader <Rectangle>(); ListReader <Vector3> hVector3ListReader = new ListReader <Vector3>(); ListReader <StringReader> hStringListReader = new ListReader <StringReader>(); SpriteFontReader hSpriteFontReader = new SpriteFontReader(); Texture2DReader hTexture2DReader = new Texture2DReader(); CharReader hCharReader = new CharReader(); RectangleReader hRectangleReader = new RectangleReader(); StringReader hStringReader = new StringReader(); Vector3Reader hVector3Reader = new Vector3Reader(); int numberOfReaders; ContentTypeReader[] contentReaders; // The first 4 bytes should be the "XNBw" header. i use that to detect an invalid file byte[] headerBuffer = new byte[4]; reader.Read(headerBuffer, 0, 4); string headerString = Encoding.UTF8.GetString(headerBuffer, 0, 4); if (string.Compare(headerString, "XNBw", StringComparison.InvariantCultureIgnoreCase) != 0) { throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?"); } // I think these two bytes are some kind of version number. Either for the XNB file or the type readers byte version = reader.ReadByte(); byte compressed = reader.ReadByte(); // The next int32 is the length of the XNB file int xnbLength = reader.ReadInt32(); if (compressed != 0) { throw new NotImplementedException("MonoGame cannot read compressed XNB files. Please use the XNB files from the Debug build of your XNA game instead. If someone wants to contribute decompression logic, that would be fantastic."); } // The next byte i read tells me the number of content readers in this XNB file numberOfReaders = reader.ReadByte(); contentReaders = new ContentTypeReader[numberOfReaders]; // For each reader in the file, we read out the length of the string which contains the type of the reader, // then we read out the string. Finally we instantiate an instance of that reader using reflection for (int i = 0; i < numberOfReaders; i++) { // This string tells us what reader we need to decode the following data // string readerTypeString = reader.ReadString(); string originalReaderTypeString = reader.ReadString(); // Need to resolve namespace differences string readerTypeString = originalReaderTypeString; /*if(readerTypeString.IndexOf(", Microsoft.Xna.Framework") != -1) * { * string[] tokens = readerTypeString.Split(new char[] { ',' }); * readerTypeString = ""; * for(int j = 0; j < tokens.Length; j++) * { * if(j != 0) * readerTypeString += ","; * * if(j == 1) * readerTypeString += " Microsoft.Xna.Framework"; * else * readerTypeString += tokens[j]; * } * readerTypeString = readerTypeString.Replace(", Microsoft.Xna.Framework", "@"); * }*/ if (readerTypeString.Contains("PublicKey")) { //if (readerTypeString.Contains("[[")) { readerTypeString = readerTypeString.Split(new char[] { '[', '[' })[0] + "[" + readerTypeString.Split(new char[] { '[', '[' })[2].Split(',')[0] + "]"; //} //else { // // If the readerTypeString did not contain "[[" to split the // // types then we assume it is XNA 4.0 which splits the types // // by ', ' // readerTypeString = readerTypeString.Split(new char[] { ',', ' '})[0]; // //} } readerTypeString = readerTypeString.Replace("Microsoft.Xna.Framework", "Microsoft.Xna.Framework"); Type l_readerType = Type.GetType(readerTypeString); if (l_readerType != null) { contentReaders[i] = (ContentTypeReader)Activator.CreateInstance(l_readerType, true); } else { throw new ContentLoadException("Could not find matching content reader of type " + originalReaderTypeString); } // I think the next 4 bytes refer to the "Version" of the type reader, // although it always seems to be zero int typeReaderVersion = reader.ReadInt32(); } return(contentReaders); }