protected T ReadAsset <T>(string assetName, Action <IDisposable> recordDisposableObject) { if (string.IsNullOrEmpty(assetName)) { throw new ArgumentNullException("assetName"); } if (disposed) { throw new ObjectDisposedException("ContentManager"); } object result = null; Stream stream = null; string modifiedAssetName = String.Empty; // Will be used if we have to guess a filename try { stream = OpenStream(assetName); } catch (Exception e) { // Okay, so we couldn't open it. Maybe it needs a different extension? // FIXME: This only works for files on the disk, what about custom streams? -flibit modifiedAssetName = MonoGame.Utilities.FileHelpers.NormalizeFilePathSeparators( Path.Combine(RootDirectoryFullPath, assetName) ); if (typeof(T) == typeof(Texture2D) || typeof(T) == typeof(Texture)) { modifiedAssetName = Texture2DReader.Normalize(modifiedAssetName); } else if ((typeof(T) == typeof(SoundEffect))) { modifiedAssetName = SoundEffectReader.Normalize(modifiedAssetName); } else if ((typeof(T) == typeof(Effect))) { modifiedAssetName = EffectReader.Normalize(modifiedAssetName); } else if ((typeof(T) == typeof(Song))) { modifiedAssetName = SongReader.Normalize(modifiedAssetName); } else if ((typeof(T) == typeof(Video))) { modifiedAssetName = VideoReader.Normalize(modifiedAssetName); } else { // No raw format available, disregard! modifiedAssetName = null; } // Did we get anything...? if (String.IsNullOrEmpty(modifiedAssetName)) { // Nope, nothing we're aware of! throw new ContentLoadException( "Could not load asset " + assetName + "! Error: " + e.Message, e ); } stream = TitleContainer.OpenStream(modifiedAssetName); } // Check for XNB header stream.Read(xnbHeader, 0, xnbHeader.Length); if (xnbHeader[0] == 'X' && xnbHeader[1] == 'N' && xnbHeader[2] == 'B' && targetPlatformIdentifiers.Contains((char)xnbHeader[3])) { using (BinaryReader xnbReader = new BinaryReader(stream)) using (ContentReader reader = GetContentReaderFromXnb(assetName, ref stream, xnbReader, (char)xnbHeader[3], recordDisposableObject)) { result = reader.ReadAsset <T>(); GraphicsResource resource = result as GraphicsResource; if (resource != null) { resource.Name = assetName; } } } else { // It's not an XNB file. Try to load as a raw asset instead. // FIXME: Assuming seekable streams! -flibit stream.Seek(0, SeekOrigin.Begin); if (typeof(T) == typeof(Texture2D) || typeof(T) == typeof(Texture)) { Texture2D texture; if (xnbHeader[0] == 'D' && xnbHeader[1] == 'D' && xnbHeader[2] == 'S' && xnbHeader[3] == ' ') { texture = Texture2D.DDSFromStreamEXT( GetGraphicsDevice(), stream ); } else { texture = Texture2D.FromStream( GetGraphicsDevice(), stream ); } texture.Name = assetName; result = texture; } else if ((typeof(T) == typeof(SoundEffect))) { result = SoundEffect.FromStream(stream); } else if ((typeof(T) == typeof(Effect))) { byte[] data = new byte[stream.Length]; stream.Read(data, 0, (int)stream.Length); result = new Effect(GetGraphicsDevice(), data); } else if ((typeof(T) == typeof(Song))) { // FIXME: Not using the stream! -flibit result = new Song(modifiedAssetName); } else if ((typeof(T) == typeof(Video))) { // FIXME: Not using the stream! -flibit result = new Video(modifiedAssetName, GetGraphicsDevice()); FNALoggerEXT.LogWarn( "Video " + modifiedAssetName + " does not have an XNB file! Hacking Duration property!" ); } else { stream.Close(); throw new ContentLoadException("Could not load " + assetName + " asset!"); } /* Because Raw Assets skip the ContentReader step, they need to have their * disposables recorded here. Doing it outside of this catch will * result in disposables being logged twice. */ IDisposable disposableResult = result as IDisposable; if (disposableResult != null) { if (recordDisposableObject != null) { recordDisposableObject(disposableResult); } else { disposableAssets.Add(disposableResult); } } /* Because we're not using a BinaryReader for raw assets, we * need to close the stream ourselves. * -flibit */ stream.Close(); } return((T)result); }
protected void ReloadAsset(string originalAssetName, object currentAsset) { if (string.IsNullOrEmpty(originalAssetName)) { throw new ArgumentNullException("assetName"); } if (disposed) { throw new ObjectDisposedException("ContentManager"); } if (this.graphicsDeviceService == null) { this.graphicsDeviceService = serviceProvider.GetService(typeof(IGraphicsDeviceService)) as IGraphicsDeviceService; if (this.graphicsDeviceService == null) { throw new InvalidOperationException("No Graphics Device Service"); } } // Replace Windows path separators with local path separators var assetName = GetFilename(originalAssetName); // Get the real file name if ((currentAsset is Curve)) { assetName = CurveReader.Normalize(assetName); } else if ((currentAsset is Texture2D)) { assetName = Texture2DReader.Normalize(assetName); } else if ((currentAsset is SpriteFont)) { assetName = SpriteFontReader.Normalize(assetName); } else if ((currentAsset is Effect)) { assetName = Effect.Normalize(assetName); } else if ((currentAsset is Song)) { assetName = SongReader.Normalize(assetName); } else if ((currentAsset is SoundEffect)) { assetName = SoundEffectReader.Normalize(assetName); } else if ((currentAsset is Video)) { assetName = Video.Normalize(assetName); } if (string.IsNullOrEmpty(assetName)) { throw new ContentLoadException("Could not load " + originalAssetName + " asset!"); } if (!Path.HasExtension(assetName)) assetName = string.Format("{0}.xnb", assetName); if (Path.GetExtension(assetName).ToLower() == ".xnb") { } else { if ((currentAsset is Texture2D)) { using (Stream assetStream = OpenStream(assetName)) { var asset = currentAsset as Texture2D; asset.Reload(assetStream); } } else if ((currentAsset is SpriteFont)) { } else if ((currentAsset is Song)) { } else if ((currentAsset is SoundEffect)) { } else if ((currentAsset is Video)) { } else if ((currentAsset is Effect)) { } } }
protected T ReadAsset<T>(string assetName, Action<IDisposable> recordDisposableObject) { if (string.IsNullOrEmpty(assetName)) { throw new ArgumentNullException("assetName"); } if (disposed) { throw new ObjectDisposedException("ContentManager"); } string originalAssetName = assetName; object result = null; if (this.graphicsDeviceService == null) { this.graphicsDeviceService = serviceProvider.GetService(typeof(IGraphicsDeviceService)) as IGraphicsDeviceService; if (this.graphicsDeviceService == null) { throw new InvalidOperationException("No Graphics Device Service"); } } // Replace Windows path separators with local path separators assetName = GetFilename(assetName); // Get the real file name if ((typeof(T) == typeof(Curve))) { assetName = CurveReader.Normalize(assetName); } else if ((typeof(T) == typeof(Texture2D))) { assetName = Texture2DReader.Normalize(assetName); } else if ((typeof(T) == typeof(SpriteFont))) { assetName = SpriteFontReader.Normalize(assetName); } else if ((typeof(T) == typeof(Effect))) { assetName = Effect.Normalize(assetName); } else if ((typeof(T) == typeof(Song))) { assetName = SongReader.Normalize(assetName); } else if ((typeof(T) == typeof(SoundEffect))) { assetName = SoundEffectReader.Normalize(assetName); } else if ((typeof(T) == typeof(Video))) { assetName = Video.Normalize(assetName); } if (string.IsNullOrEmpty(assetName)) { throw new ContentLoadException("Could not load " + originalAssetName + " asset!"); } if (!Path.HasExtension(assetName)) assetName = string.Format("{0}.xnb", assetName); if (Path.GetExtension(assetName).ToLower() == ".xnb") { // Load a XNB file Stream stream = OpenStream(assetName); try { using (BinaryReader xnbReader = new BinaryReader(stream)) { // The first 4 bytes should be the "XNB" header. i use that to detect an invalid file byte x = xnbReader.ReadByte(); byte n = xnbReader.ReadByte(); byte b = xnbReader.ReadByte(); byte platform = xnbReader.ReadByte(); if (x != 'X' || n != 'N' || b != 'B' || !(platform == 'w' || platform == 'x' || platform == 'm')) { throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?"); } byte version = xnbReader.ReadByte(); byte flags = xnbReader.ReadByte(); bool compressed = (flags & 0x80) != 0; if (version != 5 && version != 4) { throw new ContentLoadException("Invalid XNB version"); } // The next int32 is the length of the XNB file int xnbLength = xnbReader.ReadInt32(); ContentReader reader; if (compressed) { LzxDecoder dec = new LzxDecoder(16); //decompress the xnb //thanks to ShinAli (https://bitbucket.org/alisci01/xnbdecompressor) int compressedSize = xnbLength - 14; int decompressedSize = xnbReader.ReadInt32(); int newFileSize = decompressedSize + 10; MemoryStream decompressedStream = new MemoryStream(decompressedSize); int decodedBytes = 0; int pos = 0; #if ANDROID // Android native stream does not support the Position property. LzxDecoder.Decompress also uses // Seek. So we read the entirity of the stream into a memory stream and replace stream with the // memory stream. MemoryStream memStream = new MemoryStream(); stream.CopyTo(memStream); memStream.Seek(0, SeekOrigin.Begin); stream.Dispose(); stream = memStream; pos = -14; #endif while (pos < compressedSize) { // let's seek to the correct position // The stream should already be in the correct position, and seeking can be slow stream.Seek(pos + 14, SeekOrigin.Begin); int hi = stream.ReadByte(); int lo = stream.ReadByte(); int block_size = (hi << 8) | lo; int frame_size = 0x8000; if (hi == 0xFF) { hi = lo; lo = (byte)stream.ReadByte(); frame_size = (hi << 8) | lo; hi = (byte)stream.ReadByte(); lo = (byte)stream.ReadByte(); block_size = (hi << 8) | lo; pos += 5; } else pos += 2; if (block_size == 0 || frame_size == 0) break; int lzxRet = dec.Decompress(stream, block_size, decompressedStream, frame_size); pos += block_size; decodedBytes += frame_size; } if (decompressedStream.Position != decompressedSize) { throw new ContentLoadException("Decompression of " + originalAssetName + "failed. " + " Try decompressing with nativeDecompressXnb first."); } decompressedStream.Seek(0, SeekOrigin.Begin); reader = new ContentReader(this, decompressedStream, this.graphicsDeviceService.GraphicsDevice, originalAssetName); } else { reader = new ContentReader(this, stream, this.graphicsDeviceService.GraphicsDevice, originalAssetName); } using (reader) { result = reader.ReadAsset<T>(); } } } finally { if (stream != null) { stream.Dispose(); } } } else { if ((typeof(T) == typeof(Texture2D))) { #if IPHONE Texture2D texture = Texture2D.FromFile(graphicsDeviceService.GraphicsDevice, assetName); texture.Name = originalAssetName; result = texture; #else using (Stream assetStream = OpenStream(assetName)) { Texture2D texture = Texture2D.FromFile(graphicsDeviceService.GraphicsDevice, assetStream); texture.Name = originalAssetName; result = texture; } #endif } else if ((typeof(T) == typeof(SpriteFont))) { //result = new SpriteFont(Texture2D.FromFile(graphicsDeviceService.GraphicsDevice,assetName), null, null, null, 0, 0.0f, null, null); throw new NotImplementedException(); } else if ((typeof(T) == typeof(Song))) { result = new Song(assetName); } else if ((typeof(T) == typeof(SoundEffect))) { result = new SoundEffect(assetName); } else if ((typeof(T) == typeof(Video))) { result = new Video(assetName); } else if ((typeof(T) == typeof(Effect))) { result = new Effect(graphicsDeviceService.GraphicsDevice, assetName); } } if (result == null) { throw new ContentLoadException("Could not load " + originalAssetName + " asset!"); } if ( recordDisposableObject != null && result is IDisposable ) recordDisposableObject(result as IDisposable); return (T)result; }
public T Load <T>(string assetName) { string originalAssetName = assetName; object result = null; if (this.graphicsDeviceService == null) { this.graphicsDeviceService = serviceProvider.GetService(typeof(IGraphicsDeviceService)) as IGraphicsDeviceService; if (this.graphicsDeviceService == null) { throw new InvalidOperationException("No Graphics Device Service"); } } if (string.IsNullOrEmpty(assetName)) { throw new ArgumentException("assetname"); } if (!string.IsNullOrEmpty(_rootDirectory)) { assetName = _rootDirectory + Path.DirectorySeparatorChar + assetName; } // Check for windows-style directory separator character assetName = assetName.Replace('\\', Path.DirectorySeparatorChar); // Get the real file name if ((typeof(T) == typeof(Texture2D))) { assetName = Texture2DReader.Normalize(assetName); } if ((typeof(T) == typeof(SpriteFont))) { assetName = SpriteFontReader.Normalize(assetName); } if ((typeof(T) == typeof(Song))) { assetName = SongReader.Normalize(assetName); } if ((typeof(T) == typeof(SoundEffect))) { assetName = SoundEffectReader.Normalize(assetName); } if ((typeof(T) == typeof(Video))) { assetName = Video.Normalize(assetName); } if ((typeof(T) == typeof(Effect))) { assetName = Effect.Normalize(assetName); } if (string.IsNullOrEmpty(assetName)) { throw new ContentLoadException("Could not load " + originalAssetName + " asset!"); } if (!Path.HasExtension(assetName)) { assetName = string.Format("{0}.xnb", assetName); } if (Path.GetExtension(assetName).ToUpper() == ".XNB") { // Load a XNB file FileStream stream = new FileStream(assetName, FileMode.Open, FileAccess.Read, FileShare.Read); ContentReader reader = new ContentReader(this, stream, this.graphicsDeviceService.GraphicsDevice); ContentTypeReaderManager typeManager = new ContentTypeReaderManager(reader); reader.TypeReaders = typeManager.LoadAssetReaders(reader); foreach (ContentTypeReader r in reader.TypeReaders) { r.Initialize(typeManager); } // we need to read a byte here for things to work out, not sure why reader.ReadByte(); // Get the 1-based index of the typereader we should use to start decoding with int index = reader.ReadByte(); ContentTypeReader contentReader = reader.TypeReaders[index - 1]; result = reader.ReadObject <T>(contentReader); reader.Close(); stream.Close(); } else { if ((typeof(T) == typeof(Texture2D))) { result = Texture2D.FromFile(graphicsDeviceService.GraphicsDevice, assetName); } if ((typeof(T) == typeof(SpriteFont))) { //result = new SpriteFont(Texture2D.FromFile(graphicsDeviceService.GraphicsDevice,assetName), null, null, null, 0, 0.0f, null, null); throw new NotImplementedException(); } if ((typeof(T) == typeof(Song))) { result = new Song(assetName); } if ((typeof(T) == typeof(SoundEffect))) { result = new SoundEffect(assetName); } if ((typeof(T) == typeof(Video))) { result = new Video(assetName); } } if (result == null) { throw new ContentLoadException("Could not load " + originalAssetName + " asset!"); } return((T)result); }
public T Load <T>(string assetName) { string originalAssetName = assetName; object result = null; if (this.graphicsDeviceService == null) { this.graphicsDeviceService = serviceProvider.GetService(typeof(IGraphicsDeviceService)) as IGraphicsDeviceService; if (this.graphicsDeviceService == null) { throw new InvalidOperationException("No Graphics Device Service"); } } // Check for windows-style directory separator character //Lowercase assetName (monodroid specification all assests are lowercase) assetName = Path.Combine(_rootDirectory, assetName.Replace('\\', Path.DirectorySeparatorChar)).ToLower(); // Get the real file name if ((typeof(T) == typeof(Texture2D))) { assetName = Texture2DReader.Normalize(assetName); } else if ((typeof(T) == typeof(SpriteFont))) { assetName = SpriteFontReader.Normalize(assetName); } else if ((typeof(T) == typeof(Effect))) { assetName = Effect.Normalize(assetName); } else if ((typeof(T) == typeof(Song))) { assetName = SongReader.Normalize(assetName); } else if ((typeof(T) == typeof(SoundEffect))) { assetName = SoundEffectReader.Normalize(assetName); } else if ((typeof(T) == typeof(Video))) { assetName = Video.Normalize(assetName); } else { throw new NotSupportedException("Format not supported"); } if (string.IsNullOrEmpty(assetName)) { throw new ContentLoadException("Could not load " + originalAssetName + " asset!"); } if (!Path.HasExtension(assetName)) { assetName = string.Format("{0}.xnb", assetName); } if (Path.GetExtension(assetName).ToUpper() != ".XNB") { if ((typeof(T) == typeof(Texture2D))) { //Basically the same as Texture2D.FromFile but loading from the assets instead of a filePath using (Stream assetStream = File.Open(assetName, FileMode.Open, FileAccess.Read)) { Bitmap image = (Bitmap)Bitmap.FromStream(assetStream); ESImage theTexture = new ESImage(image, graphicsDeviceService.GraphicsDevice.PreferedFilter); result = new Texture2D(theTexture) { Name = Path.GetFileNameWithoutExtension(assetName) }; } } if ((typeof(T) == typeof(SpriteFont))) { //result = new SpriteFont(Texture2D.FromFile(graphicsDeviceService.GraphicsDevice,assetName), null, null, null, 0, 0.0f, null, null); throw new NotImplementedException(); } if (typeof(T) == typeof(Effect)) { result = new Effect(graphicsDeviceService.GraphicsDevice, assetName); } if ((typeof(T) == typeof(Song))) { result = new Song(assetName); } if ((typeof(T) == typeof(SoundEffect))) { result = new SoundEffect(assetName); } if ((typeof(T) == typeof(Video))) { result = new Video(assetName); } } else { // Load a XNB file //Loads from Assets directory + /assetName Stream assetStream = File.Open(assetName, FileMode.Open, FileAccess.Read); ContentReader reader = new ContentReader(this, assetStream, this.graphicsDeviceService.GraphicsDevice); ContentTypeReaderManager typeManager = new ContentTypeReaderManager(reader); reader.TypeReaders = typeManager.LoadAssetReaders(reader); foreach (ContentTypeReader r in reader.TypeReaders) { r.Initialize(typeManager); } // we need to read a byte here for things to work out, not sure why reader.ReadByte(); // Get the 1-based index of the typereader we should use to start decoding with int index = reader.ReadByte(); ContentTypeReader contentReader = reader.TypeReaders[index - 1]; result = reader.ReadObject <T>(contentReader); reader.Close(); assetStream.Close(); } if (result == null) { throw new ContentLoadException("Could not load " + originalAssetName + " asset!"); } return((T)result); }
protected T ReadAsset <T>(string assetName, Action <IDisposable> recordDisposableObject) { if (string.IsNullOrEmpty(assetName)) { throw new ArgumentNullException("assetName"); } if (disposed) { throw new ObjectDisposedException("ContentManager"); } object result = null; // FIXME: Should this block be here? -flibit if (graphicsDeviceService == null) { graphicsDeviceService = ServiceProvider.GetService(typeof(IGraphicsDeviceService)) as IGraphicsDeviceService; if (graphicsDeviceService == null) { throw new InvalidOperationException("No Graphics Device Service"); } } Stream stream = null; string modifiedAssetName = String.Empty; // Will be used if we have to guess a filename try { stream = OpenStream(assetName); } catch (Exception e) { // Okay, so we couldn’t open it. Maybe it needs a different extension? // FIXME: Normalizing checks for a file on the disk, what about custom streams? -flibit modifiedAssetName = FileHelpers.NormalizeFilePathSeparators( Path.Combine(RootDirectoryFullPath, assetName) ); if (typeof(T) == typeof(Texture2D) || typeof(T) == typeof(Texture)) { modifiedAssetName = Texture2DReader.Normalize(assetName); } else if ((typeof(T) == typeof(SoundEffect))) { modifiedAssetName = SoundEffectReader.Normalize(assetName); } else if ((typeof(T) == typeof(Effect))) { modifiedAssetName = EffectReader.Normalize(assetName); } else if ((typeof(T) == typeof(Song))) { modifiedAssetName = SongReader.Normalize(assetName); } else if ((typeof(T) == typeof(Video))) { modifiedAssetName = VideoReader.Normalize(assetName); } // Did we get anything…? if (String.IsNullOrEmpty(modifiedAssetName)) { // Nope, nothing we’re aware of! throw new ContentLoadException( "Could not load asset " + assetName + "! Error: " + e.Message, e ); } stream = File.OpenRead(modifiedAssetName); } using (BinaryReader xnbReader = new BinaryReader(stream)) { try { // Try to load as XNB file using (ContentReader reader = GetContentReaderFromXnb(assetName, ref stream, xnbReader, recordDisposableObject)) { result = reader.ReadAsset <T>(); GraphicsResource resource = result as GraphicsResource; if (resource != null) { resource.Name = assetName; } } } catch (Exception e) { // FIXME: Assuming seekable streams! -flibit stream.Seek(0, SeekOrigin.Begin); // Try to load as a raw asset if (typeof(T) == typeof(Texture2D) || typeof(T) == typeof(Texture)) { Texture2D texture = Texture2D.FromStream( graphicsDeviceService.GraphicsDevice, stream ); texture.Name = assetName; result = texture; } else if ((typeof(T) == typeof(SoundEffect))) { result = SoundEffect.FromStream(stream); } else if ((typeof(T) == typeof(Effect))) { byte[] data = new byte[stream.Length]; stream.Read(data, 0, (int)stream.Length); result = new Effect(graphicsDeviceService.GraphicsDevice, data); } else if ((typeof(T) == typeof(Song))) { // FIXME: Not using the stream! -flibit result = new Song(modifiedAssetName); } else if ((typeof(T) == typeof(Video))) { // FIXME: Not using the stream! -flibit result = new Video(modifiedAssetName); } else { // We dunno WTF this is, give them the XNB Exception. throw e; } /* Because Raw Assets skip the ContentReader step, they need to have their * disposables recorded here. Doing it outside of this catch will * result in disposables being logged twice. */ IDisposable disposableResult = result as IDisposable; if (disposableResult != null) { if (recordDisposableObject != null) { recordDisposableObject(disposableResult); } else { disposableAssets.Add(disposableResult); } } } } if (result == null) { throw new ContentLoadException("Could not load " + assetName + " asset!"); } return((T)result); }