(ded4a3e0a) v0.9.0.7

This commit is contained in:
Joonas Rikkonen
2019-06-25 16:00:44 +03:00
parent e5ae622c77
commit 4a51db77b5
1777 changed files with 421528 additions and 917 deletions
@@ -0,0 +1,68 @@
using System;
using System.Reflection;
using System.Linq;
namespace Microsoft.Xna.Framework.Content
{
internal static class ContentExtensions
{
public static ConstructorInfo GetDefaultConstructor(this Type type)
{
#if NET45
var typeInfo = type.GetTypeInfo();
var ctor = typeInfo.DeclaredConstructors.FirstOrDefault(c => !c.IsStatic && c.GetParameters().Length == 0);
return ctor;
#else
var attrs = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
return type.GetConstructor(attrs, null, new Type[0], null);
#endif
}
public static PropertyInfo[] GetAllProperties(this Type type)
{
// Sometimes, overridden properties of abstract classes can show up even with
// BindingFlags.DeclaredOnly is passed to GetProperties. Make sure that
// all properties in this list are defined in this class by comparing
// its get method with that of it's base class. If they're the same
// Then it's an overridden property.
#if NET45
PropertyInfo[] infos= type.GetTypeInfo().DeclaredProperties.ToArray();
var nonStaticPropertyInfos = from p in infos
where (p.GetMethod != null) && (!p.GetMethod.IsStatic) &&
(p.GetMethod == p.GetMethod.GetRuntimeBaseDefinition())
select p;
return nonStaticPropertyInfos.ToArray();
#else
const BindingFlags attrs = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
var allProps = type.GetProperties(attrs).ToList();
var props = allProps.FindAll(p => p.GetGetMethod(true) != null && p.GetGetMethod(true) == p.GetGetMethod(true).GetBaseDefinition()).ToArray();
return props;
#endif
}
public static FieldInfo[] GetAllFields(this Type type)
{
#if NET45
FieldInfo[] fields= type.GetTypeInfo().DeclaredFields.ToArray();
var nonStaticFields = from field in fields
where !field.IsStatic
select field;
return nonStaticFields.ToArray();
#else
var attrs = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
return type.GetFields(attrs);
#endif
}
public static bool IsClass(this Type type)
{
#if NET45
return type.GetTypeInfo().IsClass;
#else
return type.IsClass;
#endif
}
}
}
@@ -0,0 +1,60 @@
#region License
/*
Microsoft Public License (Ms-PL)
MonoGame - Copyright © 2009 The MonoGame Team
All rights reserved.
This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
accept the license, do not use the software.
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
3. Conditions and Limitations
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
your patent license from such contributor to the software ends automatically.
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
notices that are present in the software.
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including
a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
code form, you may only do so under a license that complies with this license.
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
purpose and non-infringement.
*/
#endregion License
using System;
namespace Microsoft.Xna.Framework.Content
{
public class ContentLoadException : Exception
{
public ContentLoadException() : base()
{
}
public ContentLoadException(string message) : base(message)
{
}
public ContentLoadException(string message, Exception innerException) : base(message,innerException)
{
}
}
}
@@ -0,0 +1,505 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using MonoGame.Utilities;
using Microsoft.Xna.Framework.Graphics;
using System.Globalization;
namespace Microsoft.Xna.Framework.Content
{
public partial class ContentManager : IDisposable
{
const byte ContentCompressedLzx = 0x80;
const byte ContentCompressedLz4 = 0x40;
private string _rootDirectory = string.Empty;
private IServiceProvider serviceProvider;
private IGraphicsDeviceService graphicsDeviceService;
private Dictionary<string, object> loadedAssets = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
private List<IDisposable> disposableAssets = new List<IDisposable>();
private bool disposed;
private byte[] scratchBuffer;
private static object ContentManagerLock = new object();
private static List<WeakReference> ContentManagers = new List<WeakReference>();
private static readonly List<char> targetPlatformIdentifiers = new List<char>()
{
'w', // Windows (XNA & DirectX)
'x', // Xbox360 (XNA)
'm', // WindowsPhone7.0 (XNA)
'i', // iOS
'a', // Android
'd', // DesktopGL
'X', // MacOSX
'W', // WindowsStoreApp
'n', // NativeClient
'M', // WindowsPhone8
'r', // RaspberryPi
'P', // PlayStation4
'v', // PSVita
'O', // XboxOne
'S', // Nintendo Switch
// NOTE: There are additional idenfiers for consoles that
// are not defined in this repository. Be sure to ask the
// console port maintainers to ensure no collisions occur.
// Legacy identifiers... these could be reused in the
// future if we feel enough time has passed.
'p', // PlayStationMobile
'g', // Windows (OpenGL)
'l', // Linux
};
static partial void PlatformStaticInit();
static ContentManager()
{
// Allow any per-platform static initialization to occur.
PlatformStaticInit();
}
private static void AddContentManager(ContentManager contentManager)
{
lock (ContentManagerLock)
{
// Check if the list contains this content manager already. Also take
// the opportunity to prune the list of any finalized content managers.
bool contains = false;
for (int i = ContentManagers.Count - 1; i >= 0; --i)
{
var contentRef = ContentManagers[i];
if (ReferenceEquals(contentRef.Target, contentManager))
contains = true;
if (!contentRef.IsAlive)
ContentManagers.RemoveAt(i);
}
if (!contains)
ContentManagers.Add(new WeakReference(contentManager));
}
}
private static void RemoveContentManager(ContentManager contentManager)
{
lock (ContentManagerLock)
{
// Check if the list contains this content manager and remove it. Also
// take the opportunity to prune the list of any finalized content managers.
for (int i = ContentManagers.Count - 1; i >= 0; --i)
{
var contentRef = ContentManagers[i];
if (!contentRef.IsAlive || ReferenceEquals(contentRef.Target, contentManager))
ContentManagers.RemoveAt(i);
}
}
}
internal static void ReloadGraphicsContent()
{
lock (ContentManagerLock)
{
// Reload the graphic assets of each content manager. Also take the
// opportunity to prune the list of any finalized content managers.
for (int i = ContentManagers.Count - 1; i >= 0; --i)
{
var contentRef = ContentManagers[i];
if (contentRef.IsAlive)
{
var contentManager = (ContentManager)contentRef.Target;
if (contentManager != null)
contentManager.ReloadGraphicsAssets();
}
else
{
ContentManagers.RemoveAt(i);
}
}
}
}
// Use C# destructor syntax for finalization code.
// This destructor will run only if the Dispose method
// does not get called.
// It gives your base class the opportunity to finalize.
// Do not provide destructors in types derived from this class.
~ContentManager()
{
// Do not re-create Dispose clean-up code here.
// Calling Dispose(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
public ContentManager(IServiceProvider serviceProvider)
{
if (serviceProvider == null)
{
throw new ArgumentNullException("serviceProvider");
}
this.serviceProvider = serviceProvider;
AddContentManager(this);
}
public ContentManager(IServiceProvider serviceProvider, string rootDirectory)
{
if (serviceProvider == null)
{
throw new ArgumentNullException("serviceProvider");
}
if (rootDirectory == null)
{
throw new ArgumentNullException("rootDirectory");
}
this.RootDirectory = rootDirectory;
this.serviceProvider = serviceProvider;
AddContentManager(this);
}
public void Dispose()
{
Dispose(true);
// Tell the garbage collector not to call the finalizer
// since all the cleanup will already be done.
GC.SuppressFinalize(this);
// Once disposed, content manager wont be used again
RemoveContentManager(this);
}
// If disposing is true, it was called explicitly and we should dispose managed objects.
// If disposing is false, it was called by the finalizer and managed objects should not be disposed.
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
Unload();
}
scratchBuffer = null;
disposed = true;
}
}
public virtual T LoadLocalized<T> (string assetName)
{
string [] cultureNames =
{
CultureInfo.CurrentCulture.Name, // eg. "en-US"
CultureInfo.CurrentCulture.TwoLetterISOLanguageName // eg. "en"
};
// Look first for a specialized language-country version of the asset,
// then if that fails, loop back around to see if we can find one that
// specifies just the language without the country part.
foreach (string cultureName in cultureNames) {
string localizedAssetName = assetName + '.' + cultureName;
try {
return Load<T> (localizedAssetName);
} catch (ContentLoadException) { }
}
// If we didn't find any localized asset, fall back to the default name.
return Load<T> (assetName);
}
public virtual T Load<T>(string assetName)
{
if (string.IsNullOrEmpty(assetName))
{
throw new ArgumentNullException("assetName");
}
if (disposed)
{
throw new ObjectDisposedException("ContentManager");
}
T result = default(T);
// On some platforms, name and slash direction matter.
// We store the asset by a /-seperating key rather than how the
// path to the file was passed to us to avoid
// loading "content/asset1.xnb" and "content\\ASSET1.xnb" as if they were two
// different files. This matches stock XNA behavior.
// The dictionary will ignore case differences
var key = assetName.Replace('\\', '/');
// Check for a previously loaded asset first
object asset = null;
if (loadedAssets.TryGetValue(key, out asset))
{
if (asset is T)
{
return (T)asset;
}
}
// Load the asset.
result = ReadAsset<T>(assetName, null);
loadedAssets[key] = result;
return result;
}
protected virtual Stream OpenStream(string assetName)
{
Stream stream;
try
{
var assetPath = Path.Combine(RootDirectory, assetName) + ".xnb";
// This is primarily for editor support.
// Setting the RootDirectory to an absolute path is useful in editor
// situations, but TitleContainer can ONLY be passed relative paths.
#if DESKTOPGL || WINDOWS
if (Path.IsPathRooted(assetPath))
stream = File.OpenRead(assetPath);
else
#endif
stream = TitleContainer.OpenStream(assetPath);
#if ANDROID
// Read the asset into memory in one go. This results in a ~50% reduction
// in load times on Android due to slow Android asset streams.
MemoryStream memStream = new MemoryStream();
stream.CopyTo(memStream);
memStream.Seek(0, SeekOrigin.Begin);
stream.Close();
stream = memStream;
#endif
}
catch (FileNotFoundException fileNotFound)
{
throw new ContentLoadException("The content file was not found.", fileNotFound);
}
#if !WINDOWS_UAP
catch (DirectoryNotFoundException directoryNotFound)
{
throw new ContentLoadException("The directory was not found.", directoryNotFound);
}
#endif
catch (Exception exception)
{
throw new ContentLoadException("Opening stream error.", exception);
}
return stream;
}
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");
}
}
// Try to load as XNB file
var stream = OpenStream(assetName);
using (var xnbReader = new BinaryReader(stream))
{
using (var reader = GetContentReaderFromXnb(assetName, stream, xnbReader, recordDisposableObject))
{
result = reader.ReadAsset<T>();
if (result is GraphicsResource)
((GraphicsResource)result).Name = originalAssetName;
}
}
if (result == null)
throw new ContentLoadException("Could not load " + originalAssetName + " asset!");
return (T)result;
}
private ContentReader GetContentReaderFromXnb(string originalAssetName, Stream stream, BinaryReader xnbReader, Action<IDisposable> recordDisposableObject)
{
// 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' ||
!(targetPlatformIdentifiers.Contains((char)platform)))
{
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 compressedLzx = (flags & ContentCompressedLzx) != 0;
bool compressedLz4 = (flags & ContentCompressedLz4) != 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();
Stream decompressedStream = null;
if (compressedLzx || compressedLz4)
{
// Decompress the xnb
int decompressedSize = xnbReader.ReadInt32();
if (compressedLzx)
{
int compressedSize = xnbLength - 14;
decompressedStream = new LzxDecoderStream(stream, decompressedSize, compressedSize);
}
else if (compressedLz4)
{
decompressedStream = new Lz4DecoderStream(stream);
}
}
else
{
decompressedStream = stream;
}
var reader = new ContentReader(this, decompressedStream, this.graphicsDeviceService.GraphicsDevice,
originalAssetName, version, recordDisposableObject);
return reader;
}
internal void RecordDisposable(IDisposable disposable)
{
Debug.Assert(disposable != null, "The disposable is null!");
// Avoid recording disposable objects twice. ReloadAsset will try to record the disposables again.
// We don't know which asset recorded which disposable so just guard against storing multiple of the same instance.
if (!disposableAssets.Contains(disposable))
disposableAssets.Add(disposable);
}
/// <summary>
/// Virtual property to allow a derived ContentManager to have it's assets reloaded
/// </summary>
protected virtual Dictionary<string, object> LoadedAssets
{
get { return loadedAssets; }
}
protected virtual void ReloadGraphicsAssets()
{
foreach (var asset in LoadedAssets)
{
// This never executes as asset.Key is never null. This just forces the
// linker to include the ReloadAsset function when AOT compiled.
if (asset.Key == null)
ReloadAsset(asset.Key, Convert.ChangeType(asset.Value, asset.Value.GetType()));
var methodInfo = ReflectionHelpers.GetMethodInfo(typeof(ContentManager), "ReloadAsset");
var genericMethod = methodInfo.MakeGenericMethod(asset.Value.GetType());
genericMethod.Invoke(this, new object[] { asset.Key, Convert.ChangeType(asset.Value, asset.Value.GetType()) });
}
}
protected virtual void ReloadAsset<T>(string originalAssetName, T currentAsset)
{
string assetName = originalAssetName;
if (string.IsNullOrEmpty(assetName))
{
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");
}
}
var stream = OpenStream(assetName);
using (var xnbReader = new BinaryReader(stream))
{
using (var reader = GetContentReaderFromXnb(assetName, stream, xnbReader, null))
{
reader.ReadAsset<T>(currentAsset);
}
}
}
public virtual void Unload()
{
// Look for disposable assets.
foreach (var disposable in disposableAssets)
{
if (disposable != null)
disposable.Dispose();
}
disposableAssets.Clear();
loadedAssets.Clear();
}
public string RootDirectory
{
get
{
return _rootDirectory;
}
set
{
_rootDirectory = value;
}
}
internal string RootDirectoryFullPath
{
get
{
return Path.Combine(TitleContainer.Location, RootDirectory);
}
}
public IServiceProvider ServiceProvider
{
get
{
return this.serviceProvider;
}
}
internal byte[] GetScratchBuffer(int size)
{
size = Math.Max(size, 1024 * 1024);
if (scratchBuffer == null || scratchBuffer.Length < size)
scratchBuffer = new byte[size];
return scratchBuffer;
}
}
}
@@ -0,0 +1,308 @@
// MIT License - Copyright (C) The Mono.Xna Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Xna.Framework.Graphics;
using MonoGame.Utilities;
namespace Microsoft.Xna.Framework.Content
{
public sealed class ContentReader : BinaryReader
{
private ContentManager contentManager;
private Action<IDisposable> recordDisposableObject;
private ContentTypeReaderManager typeReaderManager;
private GraphicsDevice graphicsDevice;
private string assetName;
private List<KeyValuePair<int, Action<object>>> sharedResourceFixups;
private ContentTypeReader[] typeReaders;
internal int version;
internal int sharedResourceCount;
internal ContentTypeReader[] TypeReaders
{
get
{
return typeReaders;
}
}
internal GraphicsDevice GraphicsDevice
{
get
{
return this.graphicsDevice;
}
}
internal ContentReader(ContentManager manager, Stream stream, GraphicsDevice graphicsDevice, string assetName, int version, Action<IDisposable> recordDisposableObject)
: base(stream)
{
this.graphicsDevice = graphicsDevice;
this.recordDisposableObject = recordDisposableObject;
this.contentManager = manager;
this.assetName = assetName;
this.version = version;
}
public ContentManager ContentManager
{
get
{
return contentManager;
}
}
public string AssetName
{
get
{
return assetName;
}
}
internal object ReadAsset<T>()
{
InitializeTypeReaders();
// Read primary object
object result = ReadObject<T>();
// Read shared resources
ReadSharedResources();
return result;
}
internal object ReadAsset<T>(T existingInstance)
{
InitializeTypeReaders();
// Read primary object
object result = ReadObject<T>(existingInstance);
// Read shared resources
ReadSharedResources();
return result;
}
internal void InitializeTypeReaders()
{
typeReaderManager = new ContentTypeReaderManager();
typeReaders = typeReaderManager.LoadAssetReaders(this);
sharedResourceCount = Read7BitEncodedInt();
sharedResourceFixups = new List<KeyValuePair<int, Action<object>>>();
}
internal void ReadSharedResources()
{
if (sharedResourceCount <= 0)
return;
var sharedResources = new object[sharedResourceCount];
for (var i = 0; i < sharedResourceCount; ++i)
sharedResources[i] = InnerReadObject<object>(null);
// Fixup shared resources by calling each registered action
foreach (var fixup in sharedResourceFixups)
fixup.Value(sharedResources[fixup.Key]);
}
public T ReadExternalReference<T>()
{
var externalReference = ReadString();
if (!String.IsNullOrEmpty(externalReference))
{
return contentManager.Load<T>(FileHelpers.ResolveRelativePath(assetName, externalReference));
}
return default(T);
}
public Matrix ReadMatrix()
{
Matrix result = new Matrix();
result.M11 = ReadSingle();
result.M12 = ReadSingle();
result.M13 = ReadSingle();
result.M14 = ReadSingle();
result.M21 = ReadSingle();
result.M22 = ReadSingle();
result.M23 = ReadSingle();
result.M24 = ReadSingle();
result.M31 = ReadSingle();
result.M32 = ReadSingle();
result.M33 = ReadSingle();
result.M34 = ReadSingle();
result.M41 = ReadSingle();
result.M42 = ReadSingle();
result.M43 = ReadSingle();
result.M44 = ReadSingle();
return result;
}
private void RecordDisposable<T>(T result)
{
var disposable = result as IDisposable;
if (disposable == null)
return;
if (recordDisposableObject != null)
recordDisposableObject(disposable);
else
contentManager.RecordDisposable(disposable);
}
public T ReadObject<T>()
{
return InnerReadObject(default(T));
}
public T ReadObject<T>(ContentTypeReader typeReader)
{
var result = (T)typeReader.Read(this, default(T));
RecordDisposable(result);
return result;
}
public T ReadObject<T>(T existingInstance)
{
return InnerReadObject(existingInstance);
}
private T InnerReadObject<T>(T existingInstance)
{
var typeReaderIndex = Read7BitEncodedInt();
if (typeReaderIndex == 0)
return existingInstance;
if (typeReaderIndex > typeReaders.Length)
throw new ContentLoadException("Incorrect type reader index found!");
var typeReader = typeReaders[typeReaderIndex - 1];
var result = (T)typeReader.Read(this, existingInstance);
RecordDisposable(result);
return result;
}
public T ReadObject<T>(ContentTypeReader typeReader, T existingInstance)
{
if (!ReflectionHelpers.IsValueType(typeReader.TargetType))
return ReadObject(existingInstance);
var result = (T)typeReader.Read(this, existingInstance);
RecordDisposable(result);
return result;
}
public Quaternion ReadQuaternion()
{
Quaternion result = new Quaternion();
result.X = ReadSingle();
result.Y = ReadSingle();
result.Z = ReadSingle();
result.W = ReadSingle();
return result;
}
public T ReadRawObject<T>()
{
return (T)ReadRawObject<T> (default(T));
}
public T ReadRawObject<T>(ContentTypeReader typeReader)
{
return (T)ReadRawObject<T>(typeReader, default(T));
}
public T ReadRawObject<T>(T existingInstance)
{
Type objectType = typeof(T);
foreach(ContentTypeReader typeReader in typeReaders)
{
if(typeReader.TargetType == objectType)
return (T)ReadRawObject<T>(typeReader,existingInstance);
}
throw new NotSupportedException();
}
public T ReadRawObject<T>(ContentTypeReader typeReader, T existingInstance)
{
return (T)typeReader.Read(this, existingInstance);
}
public void ReadSharedResource<T>(Action<T> fixup)
{
int index = Read7BitEncodedInt();
if (index > 0)
{
sharedResourceFixups.Add(new KeyValuePair<int, Action<object>>(index - 1, delegate(object v)
{
if (!(v is T))
{
throw new ContentLoadException(String.Format("Error loading shared resource. Expected type {0}, received type {1}", typeof(T).Name, v.GetType().Name));
}
fixup((T)v);
}));
}
}
public Vector2 ReadVector2()
{
Vector2 result = new Vector2();
result.X = ReadSingle();
result.Y = ReadSingle();
return result;
}
public Vector3 ReadVector3()
{
Vector3 result = new Vector3();
result.X = ReadSingle();
result.Y = ReadSingle();
result.Z = ReadSingle();
return result;
}
public Vector4 ReadVector4()
{
Vector4 result = new Vector4();
result.X = ReadSingle();
result.Y = ReadSingle();
result.Z = ReadSingle();
result.W = ReadSingle();
return result;
}
public Color ReadColor()
{
Color result = new Color();
result.R = ReadByte();
result.G = ReadByte();
result.B = ReadByte();
result.A = ReadByte();
return result;
}
internal new int Read7BitEncodedInt()
{
return base.Read7BitEncodedInt();
}
internal BoundingSphere ReadBoundingSphere()
{
var position = ReadVector3();
var radius = ReadSingle();
return new BoundingSphere(position, radius);
}
}
}
@@ -0,0 +1,24 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
class AlphaTestEffectReader : ContentTypeReader<AlphaTestEffect>
{
protected internal override AlphaTestEffect Read(ContentReader input, AlphaTestEffect existingInstance)
{
var effect = new AlphaTestEffect(input.GraphicsDevice);
effect.Texture = input.ReadExternalReference<Texture>() as Texture2D;
effect.AlphaFunction = (CompareFunction)input.ReadInt32();
effect.ReferenceAlpha = (int)input.ReadUInt32();
effect.DiffuseColor = input.ReadVector3();
effect.Alpha = input.ReadSingle();
effect.VertexColorEnabled = input.ReadBoolean();
return effect;
}
}
}
@@ -0,0 +1,49 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using MonoGame.Utilities;
namespace Microsoft.Xna.Framework.Content
{
internal class ArrayReader<T> : ContentTypeReader<T[]>
{
ContentTypeReader elementReader;
public ArrayReader()
{
}
protected internal override void Initialize(ContentTypeReaderManager manager)
{
Type readerType = typeof(T);
elementReader = manager.GetTypeReader(readerType);
}
protected internal override T[] Read(ContentReader input, T[] existingInstance)
{
uint count = input.ReadUInt32();
T[] array = existingInstance;
if (array == null)
array = new T[count];
if (ReflectionHelpers.IsValueType(typeof(T)))
{
for (uint i = 0; i < count; i++)
{
array[i] = input.ReadObject<T>(elementReader);
}
}
else
{
for (uint i = 0; i < count; i++)
{
var readerType = input.Read7BitEncodedInt();
array[i] = readerType > 0 ? input.ReadObject<T>(input.TypeReaders[readerType - 1]) : default(T);
}
}
return array;
}
}
}
@@ -0,0 +1,30 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
internal class BasicEffectReader : ContentTypeReader<BasicEffect>
{
protected internal override BasicEffect Read(ContentReader input, BasicEffect existingInstance)
{
var effect = new BasicEffect(input.GraphicsDevice);
var texture = input.ReadExternalReference<Texture>() as Texture2D;
if (texture != null)
{
effect.Texture = texture;
effect.TextureEnabled = true;
}
effect.DiffuseColor = input.ReadVector3();
effect.EmissiveColor = input.ReadVector3();
effect.SpecularColor = input.ReadVector3();
effect.SpecularPower = input.ReadSingle();
effect.Alpha = input.ReadSingle();
effect.VertexColorEnabled = input.ReadBoolean();
return effect;
}
}
}
@@ -0,0 +1,25 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
internal class BooleanReader : ContentTypeReader<bool>
{
public BooleanReader()
{
}
protected internal override bool Read(ContentReader input, bool existingInstance)
{
return input.ReadBoolean();
}
}
}
@@ -0,0 +1,17 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Content
{
class BoundingBoxReader : ContentTypeReader<BoundingBox>
{
protected internal override BoundingBox Read(ContentReader input, BoundingBox existingInstance)
{
var min = input.ReadVector3();
var max = input.ReadVector3();
var result = new BoundingBox(min, max);
return result;
}
}
}
@@ -0,0 +1,21 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework;
namespace Microsoft.Xna.Framework.Content
{
internal class BoundingFrustumReader : ContentTypeReader<BoundingFrustum>
{
public BoundingFrustumReader()
{
}
protected internal override BoundingFrustum Read(ContentReader input, BoundingFrustum existingInstance)
{
return new BoundingFrustum(input.ReadMatrix());
}
}
}
@@ -0,0 +1,23 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework;
namespace Microsoft.Xna.Framework.Content
{
internal class BoundingSphereReader : ContentTypeReader<BoundingSphere>
{
public BoundingSphereReader()
{
}
protected internal override BoundingSphere Read(ContentReader input, BoundingSphere existingInstance)
{
Vector3 center = input.ReadVector3();
float radius = input.ReadSingle();
return new BoundingSphere(center, radius);
}
}
}
@@ -0,0 +1,20 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class ByteReader : ContentTypeReader<byte>
{
public ByteReader()
{
}
protected internal override byte Read(ContentReader input, byte existingInstance)
{
return input.ReadByte();
}
}
}
@@ -0,0 +1,25 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
internal class CharReader : ContentTypeReader<char>
{
public CharReader()
{
}
protected internal override char Read(ContentReader input, char existingInstance)
{
return input.ReadChar();
}
}
}
@@ -0,0 +1,28 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
namespace Microsoft.Xna.Framework.Content
{
internal class ColorReader : ContentTypeReader<Color>
{
public ColorReader ()
{
}
protected internal override Color Read (ContentReader input, Color existingInstance)
{
// Read RGBA as four separate bytes to make sure we comply with XNB format document
byte r = input.ReadByte();
byte g = input.ReadByte();
byte b = input.ReadByte();
byte a = input.ReadByte();
return new Color(r, g, b, a);
}
}
}
@@ -0,0 +1,36 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class CurveReader : ContentTypeReader<Curve>
{
protected internal override Curve Read(ContentReader input, Curve existingInstance)
{
Curve curve = existingInstance;
if (curve == null)
{
curve = new Curve();
}
curve.PreLoop = (CurveLoopType)input.ReadInt32();
curve.PostLoop = (CurveLoopType)input.ReadInt32();
int num6 = input.ReadInt32();
for (int i = 0; i < num6; i++)
{
float position = input.ReadSingle();
float num4 = input.ReadSingle();
float tangentIn = input.ReadSingle();
float tangentOut = input.ReadSingle();
CurveContinuity continuity = (CurveContinuity)input.ReadInt32();
curve.Keys.Add(new CurveKey(position, num4, tangentIn, tangentOut, continuity));
}
return curve;
}
}
}
@@ -0,0 +1,24 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class DateTimeReader : ContentTypeReader<DateTime>
{
public DateTimeReader()
{
}
protected internal override DateTime Read(ContentReader input, DateTime existingInstance)
{
UInt64 value = input.ReadUInt64();
UInt64 mask = (UInt64)3 << 62;
long ticks = (long)(value & ~mask);
DateTimeKind kind = (DateTimeKind)((value >> 62) & 3);
return new DateTime(ticks, kind);
}
}
}
@@ -0,0 +1,20 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class DecimalReader : ContentTypeReader<decimal>
{
public DecimalReader()
{
}
protected internal override decimal Read(ContentReader input, decimal existingInstance)
{
return input.ReadDecimal();
}
}
}
@@ -0,0 +1,78 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using MonoGame.Utilities;
namespace Microsoft.Xna.Framework.Content
{
internal class DictionaryReader<TKey, TValue> : ContentTypeReader<Dictionary<TKey, TValue>>
{
ContentTypeReader keyReader;
ContentTypeReader valueReader;
Type keyType;
Type valueType;
public DictionaryReader()
{
}
protected internal override void Initialize(ContentTypeReaderManager manager)
{
keyType = typeof(TKey);
valueType = typeof(TValue);
keyReader = manager.GetTypeReader(keyType);
valueReader = manager.GetTypeReader(valueType);
}
public override bool CanDeserializeIntoExistingObject
{
get { return true; }
}
protected internal override Dictionary<TKey, TValue> Read(ContentReader input, Dictionary<TKey, TValue> existingInstance)
{
int count = input.ReadInt32();
Dictionary<TKey, TValue> dictionary = existingInstance;
if (dictionary == null)
dictionary = new Dictionary<TKey, TValue>(count);
else
dictionary.Clear();
for (int i = 0; i < count; i++)
{
TKey key;
TValue value;
if (ReflectionHelpers.IsValueType(keyType))
{
key = input.ReadObject<TKey>(keyReader);
}
else
{
var readerType = input.Read7BitEncodedInt();
key = readerType > 0 ? input.ReadObject<TKey>(input.TypeReaders[readerType - 1]) : default(TKey);
}
if (ReflectionHelpers.IsValueType(valueType))
{
value = input.ReadObject<TValue>(valueReader);
}
else
{
var readerType = input.Read7BitEncodedInt();
value = readerType > 0 ? input.ReadObject<TValue>(input.TypeReaders[readerType - 1]) : default(TValue);
}
dictionary.Add(key, value);
}
return dictionary;
}
}
}
@@ -0,0 +1,21 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class DoubleReader : ContentTypeReader<double>
{
public DoubleReader()
{
}
protected internal override double Read(ContentReader input, double existingInstance)
{
return input.ReadDouble();
}
}
}
@@ -0,0 +1,25 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
class DualTextureEffectReader : ContentTypeReader<DualTextureEffect>
{
protected internal override DualTextureEffect Read(ContentReader input, DualTextureEffect existingInstance)
{
DualTextureEffect effect = new DualTextureEffect(input.GraphicsDevice);
effect.Texture = input.ReadExternalReference<Texture>() as Texture2D;
effect.Texture2 = input.ReadExternalReference<Texture>() as Texture2D;
effect.DiffuseColor = input.ReadVector3 ();
effect.Alpha = input.ReadSingle ();
effect.VertexColorEnabled = input.ReadBoolean ();
return effect;
}
}
}
@@ -0,0 +1,81 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Xna.Framework.Graphics;
using MonoGame.Utilities;
namespace Microsoft.Xna.Framework.Content
{
internal class EffectMaterialReader : ContentTypeReader<EffectMaterial>
{
protected internal override EffectMaterial Read (ContentReader input, EffectMaterial existingInstance)
{
var effect = input.ReadExternalReference<Effect> ();
var effectMaterial = new EffectMaterial (effect);
var dict = input.ReadObject<Dictionary<string, object>> ();
foreach (KeyValuePair<string, object> item in dict) {
var parameter = effectMaterial.Parameters [item.Key];
if (parameter != null) {
Type itemType = item.Value.GetType();
if (ReflectionHelpers.IsAssignableFromType(typeof(Texture), itemType)) {
parameter.SetValue ((Texture)item.Value);
}
else if (ReflectionHelpers.IsAssignableFromType(typeof(int), itemType)) {
parameter.SetValue((int) item.Value);
}
else if (ReflectionHelpers.IsAssignableFromType(typeof(bool), itemType)) {
parameter.SetValue((bool) item.Value);
}
else if (ReflectionHelpers.IsAssignableFromType(typeof(float), itemType)) {
parameter.SetValue((float) item.Value);
}
else if (ReflectionHelpers.IsAssignableFromType(typeof(float []), itemType)) {
parameter.SetValue((float[]) item.Value);
}
else if (ReflectionHelpers.IsAssignableFromType(typeof(Vector2), itemType)) {
parameter.SetValue((Vector2) item.Value);
}
else if (ReflectionHelpers.IsAssignableFromType(typeof(Vector2 []), itemType)) {
parameter.SetValue((Vector2 []) item.Value);
}
else if (ReflectionHelpers.IsAssignableFromType(typeof(Vector3), itemType)) {
parameter.SetValue((Vector3) item.Value);
}
else if (ReflectionHelpers.IsAssignableFromType(typeof(Vector3 []), itemType)) {
parameter.SetValue((Vector3 []) item.Value);
}
else if (ReflectionHelpers.IsAssignableFromType(typeof(Vector4), itemType)) {
parameter.SetValue((Vector4) item.Value);
}
else if (ReflectionHelpers.IsAssignableFromType(typeof(Vector4 []), itemType)) {
parameter.SetValue((Vector4 []) item.Value);
}
else if (ReflectionHelpers.IsAssignableFromType(typeof(Matrix), itemType)) {
parameter.SetValue((Matrix) item.Value);
}
else if (ReflectionHelpers.IsAssignableFromType(typeof(Matrix []), itemType)) {
parameter.SetValue((Matrix[]) item.Value);
}
else if (ReflectionHelpers.IsAssignableFromType(typeof(Quaternion), itemType)) {
parameter.SetValue((Quaternion) item.Value);
}
else {
throw new NotSupportedException ("Parameter type is not supported");
}
} else {
Debug.WriteLine ("No parameter " + item.Key);
}
}
return effectMaterial;
}
}
}
@@ -0,0 +1,25 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
internal class EffectReader : ContentTypeReader<Effect>
{
public EffectReader()
{
}
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;
}
}
}
@@ -0,0 +1,29 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class EnumReader<T> : ContentTypeReader<T>
{
ContentTypeReader elementReader;
public EnumReader()
{
}
protected internal override void Initialize(ContentTypeReaderManager manager)
{
Type readerType = Enum.GetUnderlyingType(typeof(T));
elementReader = manager.GetTypeReader(readerType);
}
protected internal override T Read(ContentReader input, T existingInstance)
{
return input.ReadRawObject<T>(elementReader);
}
}
}
@@ -0,0 +1,26 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
class EnvironmentMapEffectReader : ContentTypeReader<EnvironmentMapEffect>
{
protected internal override EnvironmentMapEffect Read(ContentReader input, EnvironmentMapEffect existingInstance)
{
var effect = new EnvironmentMapEffect(input.GraphicsDevice);
effect.Texture = input.ReadExternalReference<Texture>() as Texture2D;
effect.EnvironmentMap = input.ReadExternalReference<TextureCube>() as TextureCube;
effect.EnvironmentMapAmount = input.ReadSingle ();
effect.EnvironmentMapSpecular = input.ReadVector3 ();
effect.FresnelFactor = input.ReadSingle ();
effect.DiffuseColor = input.ReadVector3 ();
effect.EmissiveColor = input.ReadVector3 ();
effect.Alpha = input.ReadSingle ();
return effect;
}
}
}
@@ -0,0 +1,23 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Content
{
/// <summary>
/// External reference reader, provided for compatibility with XNA Framework built content
/// </summary>
internal class ExternalReferenceReader : ContentTypeReader
{
public ExternalReferenceReader()
: base(null)
{
}
protected internal override object Read(ContentReader input, object existingInstance)
{
return input.ReadExternalReference<object>();
}
}
}
@@ -0,0 +1,31 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
class IndexBufferReader : ContentTypeReader<IndexBuffer>
{
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;
}
}
}
@@ -0,0 +1,22 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework.Content;
namespace Microsoft.Xna.Framework.Content
{
internal class Int16Reader : ContentTypeReader<short>
{
public Int16Reader ()
{
}
protected internal override short Read (ContentReader input, short existingInstance)
{
return input.ReadInt16 ();
}
}
}
@@ -0,0 +1,20 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class Int32Reader : ContentTypeReader<int>
{
public Int32Reader()
{
}
protected internal override int Read(ContentReader input, int existingInstance)
{
return input.ReadInt32();
}
}
}
@@ -0,0 +1,22 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework.Content;
namespace Microsoft.Xna.Framework.Content
{
internal class Int64Reader : ContentTypeReader<long>
{
public Int64Reader ()
{
}
protected internal override long Read (ContentReader input, long existingInstance)
{
return input.ReadInt64 ();
}
}
}
@@ -0,0 +1,51 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Content;
using MonoGame.Utilities;
namespace Microsoft.Xna.Framework.Content
{
internal class ListReader<T> : ContentTypeReader<List<T>>
{
ContentTypeReader elementReader;
public ListReader()
{
}
protected internal override void Initialize(ContentTypeReaderManager manager)
{
Type readerType = typeof(T);
elementReader = manager.GetTypeReader(readerType);
}
public override bool CanDeserializeIntoExistingObject
{
get { return true; }
}
protected internal override List<T> Read(ContentReader input, List<T> existingInstance)
{
int count = input.ReadInt32();
List<T> list = existingInstance;
if (list == null) list = new List<T>(count);
for (int i = 0; i < count; i++)
{
if (ReflectionHelpers.IsValueType(typeof(T)))
{
list.Add(input.ReadObject<T>(elementReader));
}
else
{
var readerType = input.Read7BitEncodedInt();
list.Add(readerType > 0 ? input.ReadObject<T>(input.TypeReaders[readerType - 1]) : default(T));
}
}
return list;
}
}
}
@@ -0,0 +1,30 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Content
{
class MatrixReader : ContentTypeReader<Matrix>
{
protected internal override Matrix Read(ContentReader input, Matrix existingInstance)
{
var m11 = input.ReadSingle();
var m12 = input.ReadSingle();
var m13 = input.ReadSingle();
var m14 = input.ReadSingle();
var m21 = input.ReadSingle();
var m22 = input.ReadSingle();
var m23 = input.ReadSingle();
var m24 = input.ReadSingle();
var m31 = input.ReadSingle();
var m32 = input.ReadSingle();
var m33 = input.ReadSingle();
var m34 = input.ReadSingle();
var m41 = input.ReadSingle();
var m42 = input.ReadSingle();
var m43 = input.ReadSingle();
var m44 = input.ReadSingle();
return new Matrix(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
}
}
}
@@ -0,0 +1,199 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Diagnostics;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using System.Collections.Generic;
namespace Microsoft.Xna.Framework.Content
{
internal class ModelReader : ContentTypeReader<Model>
{
// List<VertexBuffer> vertexBuffers = new List<VertexBuffer>();
// List<IndexBuffer> indexBuffers = new List<IndexBuffer>();
// List<Effect> effects = new List<Effect>();
// List<GraphicsResource> sharedResources = new List<GraphicsResource>();
public ModelReader ()
{
}
static int ReadBoneReference(ContentReader reader, uint boneCount)
{
uint boneId;
// Read the bone ID, which may be encoded as either an 8 or 32 bit value.
if (boneCount < 255)
{
boneId = reader.ReadByte();
}
else
{
boneId = reader.ReadUInt32();
}
// Print out the bone ID.
if (boneId != 0)
{
//Debug.WriteLine("bone #{0}", boneId - 1);
return (int)(boneId - 1);
}
else
{
//Debug.WriteLine("null");
}
return -1;
}
protected internal override Model Read(ContentReader reader, Model existingInstance)
{
// Read the bone names and transforms.
uint boneCount = reader.ReadUInt32();
//Debug.WriteLine("Bone count: {0}", boneCount);
List<ModelBone> bones = new List<ModelBone>((int)boneCount);
for (uint i = 0; i < boneCount; i++)
{
string name = reader.ReadObject<string>();
var matrix = reader.ReadMatrix();
var bone = new ModelBone { Transform = matrix, Index = (int)i, Name = name };
bones.Add(bone);
}
// Read the bone hierarchy.
for (int i = 0; i < boneCount; i++)
{
var bone = bones[i];
//Debug.WriteLine("Bone {0} hierarchy:", i);
// Read the parent bone reference.
//Debug.WriteLine("Parent: ");
var parentIndex = ReadBoneReference(reader, boneCount);
if (parentIndex != -1)
{
bone.Parent = bones[parentIndex];
}
// Read the child bone references.
uint childCount = reader.ReadUInt32();
if (childCount != 0)
{
//Debug.WriteLine("Children:");
for (uint j = 0; j < childCount; j++)
{
var childIndex = ReadBoneReference(reader, boneCount);
if (childIndex != -1)
{
bone.AddChild(bones[childIndex]);
}
}
}
}
List<ModelMesh> meshes = new List<ModelMesh>();
//// Read the mesh data.
int meshCount = reader.ReadInt32();
//Debug.WriteLine("Mesh count: {0}", meshCount);
for (int i = 0; i < meshCount; i++)
{
//Debug.WriteLine("Mesh {0}", i);
string name = reader.ReadObject<string>();
var parentBoneIndex = ReadBoneReference(reader, boneCount);
var boundingSphere = reader.ReadBoundingSphere();
// Tag
var meshTag = reader.ReadObject<object>();
// Read the mesh part data.
int partCount = reader.ReadInt32();
//Debug.WriteLine("Mesh part count: {0}", partCount);
List<ModelMeshPart> parts = new List<ModelMeshPart>(partCount);
for (uint j = 0; j < partCount; j++)
{
ModelMeshPart part;
if (existingInstance != null)
part = existingInstance.Meshes[i].MeshParts[(int)j];
else
part = new ModelMeshPart();
part.VertexOffset = reader.ReadInt32();
part.NumVertices = reader.ReadInt32();
part.StartIndex = reader.ReadInt32();
part.PrimitiveCount = reader.ReadInt32();
// tag
part.Tag = reader.ReadObject<object>();
parts.Add(part);
int jj = (int)j;
reader.ReadSharedResource<VertexBuffer>(delegate (VertexBuffer v)
{
parts[jj].VertexBuffer = v;
});
reader.ReadSharedResource<IndexBuffer>(delegate (IndexBuffer v)
{
parts[jj].IndexBuffer = v;
});
reader.ReadSharedResource<Effect>(delegate (Effect v)
{
parts[jj].Effect = v;
});
}
if (existingInstance != null)
continue;
ModelMesh mesh = new ModelMesh(reader.GraphicsDevice, parts);
// Tag reassignment
mesh.Tag = meshTag;
mesh.Name = name;
mesh.ParentBone = bones[parentBoneIndex];
mesh.ParentBone.AddMesh(mesh);
mesh.BoundingSphere = boundingSphere;
meshes.Add(mesh);
}
if (existingInstance != null)
{
// Read past remaining data and return existing instance
ReadBoneReference(reader, boneCount);
reader.ReadObject<object>();
return existingInstance;
}
// Read the final pieces of model data.
var rootBoneIndex = ReadBoneReference(reader, boneCount);
Model model = new Model(reader.GraphicsDevice, bones, meshes);
model.Root = bones[rootBoneIndex];
model.BuildHierarchy();
// Tag?
model.Tag = reader.ReadObject<object>();
return model;
}
}
}
@@ -0,0 +1,83 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using MonoGame.Utilities;
namespace Microsoft.Xna.Framework.Content
{
internal class MultiArrayReader<T> : ContentTypeReader<Array>
{
ContentTypeReader elementReader;
public MultiArrayReader() { }
protected internal override void Initialize(ContentTypeReaderManager manager)
{
Type readerType = typeof(T);
elementReader = manager.GetTypeReader(readerType);
}
protected internal override Array Read(ContentReader input, Array existingInstance)
{
var rank = input.ReadInt32();
if (rank < 1)
throw new RankException();
var dimensions = new int[rank];
var count = 1;
for (int d = 0; d < dimensions.Length; d++)
count *= dimensions[d] = input.ReadInt32();
var array = existingInstance;
if (array == null)
array = Array.CreateInstance(typeof(T), dimensions);//new T[count];
else if (dimensions.Length != array.Rank)
throw new RankException("existingInstance");
var indices = new int[rank];
for (int i = 0; i < count; i++)
{
T value;
if (ReflectionHelpers.IsValueType(typeof(T)))
value = input.ReadObject<T>(elementReader);
else
{
var readerType = input.Read7BitEncodedInt();
if (readerType > 0)
value = input.ReadObject<T>(input.TypeReaders[readerType - 1]);
else
value = default(T);
}
CalcIndices(array, i, indices);
array.SetValue(value, indices);
}
return array;
}
static void CalcIndices(Array array, int index, int[] indices)
{
if (array.Rank != indices.Length)
throw new Exception("indices");
for (int d = 0; d < indices.Length; d++)
{
if (index == 0)
indices[d] = 0;
else
{
indices[d] = index % array.GetLength(d);
index /= array.GetLength(d);
}
}
if (index != 0)
throw new ArgumentOutOfRangeException("index");
}
}
}
@@ -0,0 +1,32 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class NullableReader<T> : ContentTypeReader<T?> where T : struct
{
ContentTypeReader elementReader;
public NullableReader()
{
}
protected internal override void Initialize(ContentTypeReaderManager manager)
{
Type readerType = typeof(T);
elementReader = manager.GetTypeReader(readerType);
}
protected internal override T? Read(ContentReader input, T? existingInstance)
{
if(input.ReadBoolean())
return input.ReadObject<T>(elementReader);
return null;
}
}
}
@@ -0,0 +1,22 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class PlaneReader : ContentTypeReader<Plane>
{
public PlaneReader()
{
}
protected internal override Plane Read(ContentReader input, Plane existingInstance)
{
existingInstance.Normal = input.ReadVector3();
existingInstance.D = input.ReadSingle();
return existingInstance;
}
}
}
@@ -0,0 +1,27 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
internal class PointReader : ContentTypeReader<Point>
{
public PointReader ()
{
}
protected internal override Point Read (ContentReader input, Point existingInstance)
{
int X = input.ReadInt32 ();
int Y = input.ReadInt32 ();
return new Point ( X, Y);
}
}
}
@@ -0,0 +1,20 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class QuaternionReader : ContentTypeReader<Quaternion>
{
public QuaternionReader()
{
}
protected internal override Quaternion Read(ContentReader input, Quaternion existingInstance)
{
return input.ReadQuaternion();
}
}
}
@@ -0,0 +1,23 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework;
namespace Microsoft.Xna.Framework.Content
{
internal class RayReader : ContentTypeReader<Ray>
{
public RayReader()
{
}
protected internal override Ray Read(ContentReader input, Ray existingInstance)
{
Vector3 position = input.ReadVector3();
Vector3 direction = input.ReadVector3();
return new Ray(position, direction);
}
}
}
@@ -0,0 +1,30 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
internal class RectangleReader : ContentTypeReader<Rectangle>
{
public RectangleReader()
{
}
protected internal override Rectangle Read(ContentReader input, Rectangle existingInstance)
{
int left = input.ReadInt32();
int top = input.ReadInt32();
int width = input.ReadInt32();
int height = input.ReadInt32();
return new Rectangle(left, top, width, height);
}
}
}
@@ -0,0 +1,191 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using MonoGame.Utilities;
namespace Microsoft.Xna.Framework.Content
{
internal class ReflectiveReader<T> : ContentTypeReader
{
delegate void ReadElement(ContentReader input, object parent);
private List<ReadElement> _readers;
private ConstructorInfo _constructor;
private ContentTypeReader _baseTypeReader;
public ReflectiveReader()
: base(typeof(T))
{
}
public override bool CanDeserializeIntoExistingObject
{
get { return TargetType.IsClass(); }
}
protected internal override void Initialize(ContentTypeReaderManager manager)
{
base.Initialize(manager);
var baseType = ReflectionHelpers.GetBaseType(TargetType);
if (baseType != null && baseType != typeof(object))
_baseTypeReader = manager.GetTypeReader(baseType);
_constructor = TargetType.GetDefaultConstructor();
var properties = TargetType.GetAllProperties();
var fields = TargetType.GetAllFields();
_readers = new List<ReadElement>(fields.Length + properties.Length);
// Gather the properties.
foreach (var property in properties)
{
var read = GetElementReader(manager, property);
if (read != null)
_readers.Add(read);
}
// Gather the fields.
foreach (var field in fields)
{
var read = GetElementReader(manager, field);
if (read != null)
_readers.Add(read);
}
}
private static ReadElement GetElementReader(ContentTypeReaderManager manager, MemberInfo member)
{
var property = member as PropertyInfo;
var field = member as FieldInfo;
Debug.Assert(field != null || property != null);
if (property != null)
{
// Properties must have at least a getter.
if (property.CanRead == false)
return null;
// Skip over indexer properties.
if (property.GetIndexParameters().Any())
return null;
}
// Are we explicitly asked to ignore this item?
if (ReflectionHelpers.GetCustomAttribute<ContentSerializerIgnoreAttribute>(member) != null)
return null;
var contentSerializerAttribute = ReflectionHelpers.GetCustomAttribute<ContentSerializerAttribute>(member);
if (contentSerializerAttribute == null)
{
if (property != null)
{
// There is no ContentSerializerAttribute, so non-public
// properties cannot be deserialized.
if (!ReflectionHelpers.PropertyIsPublic(property))
return null;
// If the read-only property has a type reader,
// and CanDeserializeIntoExistingObject is true,
// then it is safe to deserialize into the existing object.
if (!property.CanWrite)
{
var typeReader = manager.GetTypeReader(property.PropertyType);
if (typeReader == null || !typeReader.CanDeserializeIntoExistingObject)
return null;
}
}
else
{
// There is no ContentSerializerAttribute, so non-public
// fields cannot be deserialized.
if (!field.IsPublic)
return null;
// evolutional: Added check to skip initialise only fields
if (field.IsInitOnly)
return null;
}
}
Action<object, object> setter;
Type elementType;
if (property != null)
{
elementType = property.PropertyType;
if (property.CanWrite)
setter = (o, v) => property.SetValue(o, v, null);
else
setter = (o, v) => { };
}
else
{
elementType = field.FieldType;
setter = field.SetValue;
}
// Shared resources get special treatment.
if (contentSerializerAttribute != null && contentSerializerAttribute.SharedResource)
{
return (input, parent) =>
{
Action<object> action = value => setter(parent, value);
input.ReadSharedResource(action);
};
}
// We need to have a reader at this point.
var reader = manager.GetTypeReader(elementType);
if (reader == null)
if (elementType == typeof(System.Array))
reader = new ArrayReader<Array>();
else
throw new ContentLoadException(string.Format("Content reader could not be found for {0} type.", elementType.FullName));
// We use the construct delegate to pick the correct existing
// object to be the target of deserialization.
Func<object, object> construct = parent => null;
if (property != null && !property.CanWrite)
construct = parent => property.GetValue(parent, null);
return (input, parent) =>
{
var existing = construct(parent);
var obj2 = input.ReadObject(reader, existing);
setter(parent, obj2);
};
}
protected internal override object Read(ContentReader input, object existingInstance)
{
T obj;
if (existingInstance != null)
obj = (T)existingInstance;
else
obj = (_constructor == null ? (T)Activator.CreateInstance(typeof(T)) : (T)_constructor.Invoke(null));
if(_baseTypeReader != null)
_baseTypeReader.Read(input, obj);
// Box the type.
var boxed = (object)obj;
foreach (var reader in _readers)
reader(input, boxed);
// Unbox it... required for value types.
obj = (T)boxed;
return obj;
}
}
}
@@ -0,0 +1,20 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class SByteReader : ContentTypeReader<sbyte>
{
public SByteReader()
{
}
protected internal override sbyte Read(ContentReader input, sbyte existingInstance)
{
return input.ReadSByte();
}
}
}
@@ -0,0 +1,20 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class SingleReader : ContentTypeReader<float>
{
public SingleReader()
{
}
protected internal override float Read(ContentReader input, float existingInstance)
{
return input.ReadSingle();
}
}
}
@@ -0,0 +1,26 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
class SkinnedEffectReader : ContentTypeReader<SkinnedEffect>
{
protected internal override SkinnedEffect Read(ContentReader input, SkinnedEffect existingInstance)
{
var effect = new SkinnedEffect(input.GraphicsDevice);
effect.Texture = input.ReadExternalReference<Texture> () as Texture2D;
effect.WeightsPerVertex = input.ReadInt32 ();
effect.DiffuseColor = input.ReadVector3 ();
effect.EmissiveColor = input.ReadVector3 ();
effect.SpecularColor = input.ReadVector3 ();
effect.SpecularPower = input.ReadSingle ();
effect.Alpha = input.ReadSingle ();
return effect;
}
}
}
@@ -0,0 +1,59 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
internal class SpriteFontReader : ContentTypeReader<SpriteFont>
{
public SpriteFontReader()
{
}
protected internal override SpriteFont Read(ContentReader input, SpriteFont existingInstance)
{
if (existingInstance != null)
{
// Read the texture into the existing texture instance
input.ReadObject<Texture2D>(existingInstance.Texture);
// discard the rest of the SpriteFont data as we are only reloading GPU resources for now
input.ReadObject<List<Rectangle>>();
input.ReadObject<List<Rectangle>>();
input.ReadObject<List<char>>();
input.ReadInt32();
input.ReadSingle();
input.ReadObject<List<Vector3>>();
if (input.ReadBoolean())
{
input.ReadChar();
}
return existingInstance;
}
else
{
// Create a fresh SpriteFont instance
Texture2D texture = input.ReadObject<Texture2D>();
List<Rectangle> glyphs = input.ReadObject<List<Rectangle>>();
List<Rectangle> cropping = input.ReadObject<List<Rectangle>>();
List<char> charMap = input.ReadObject<List<char>>();
int lineSpacing = input.ReadInt32();
float spacing = input.ReadSingle();
List<Vector3> kerning = input.ReadObject<List<Vector3>>();
char? defaultCharacter = null;
if (input.ReadBoolean())
{
defaultCharacter = new char?(input.ReadChar());
}
return new SpriteFont(texture, glyphs, cropping, charMap, lineSpacing, spacing, kerning, defaultCharacter);
}
}
}
}
@@ -0,0 +1,22 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Text;
namespace Microsoft.Xna.Framework.Content
{
internal class StringReader : ContentTypeReader<String>
{
public StringReader()
{
}
protected internal override string Read(ContentReader input, string existingInstance)
{
return input.ReadString();
}
}
}
@@ -0,0 +1,181 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
internal class Texture2DReader : ContentTypeReader<Texture2D>
{
public Texture2DReader()
{
// Do nothing
}
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 = Math.Max(width >> level, 1);
int levelHeight = Math.Max(height >> level, 1);
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;
}
}
}
@@ -0,0 +1,50 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
internal class Texture3DReader : ContentTypeReader<Texture3D>
{
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;
#if OPENGL
Threading.BlockOnUIThread(() =>
{
#endif
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);
}
#if OPENGL
});
#endif
return texture;
}
}
}
@@ -0,0 +1,47 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
internal class TextureCubeReader : ContentTypeReader<TextureCube>
{
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;
#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 = reader.ContentManager.GetScratchBuffer(faceSize);
reader.Read(faceData, 0, faceSize);
textureCube.SetData<byte>((CubeMapFace)face, i, null, faceData, 0, faceSize);
}
}
#if OPENGL
});
#endif
return textureCube;
}
}
}
@@ -0,0 +1,17 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
internal class TextureReader : ContentTypeReader<Texture>
{
protected internal override Texture Read(ContentReader reader, Texture existingInstance)
{
return existingInstance;
}
}
}
@@ -0,0 +1,28 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework.Content;
namespace Microsoft.Xna.Framework.Content
{
internal class TimeSpanReader : ContentTypeReader<TimeSpan>
{
public TimeSpanReader ()
{
}
protected internal override TimeSpan Read (ContentReader input, TimeSpan existingInstance)
{
// Could not find any information on this really but from all the searching it looks
// like the constructor of number of ticks is long so I have placed that here for now
// long is a Int64 so we read with 64
// <Duration>PT2S</Duration>
//
return new TimeSpan(input.ReadInt64 ());
}
}
}
@@ -0,0 +1,20 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class UInt16Reader : ContentTypeReader<ushort>
{
public UInt16Reader()
{
}
protected internal override ushort Read(ContentReader input, ushort existingInstance)
{
return input.ReadUInt16();
}
}
}
@@ -0,0 +1,20 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class UInt32Reader : ContentTypeReader<uint>
{
public UInt32Reader()
{
}
protected internal override uint Read(ContentReader input, uint existingInstance)
{
return input.ReadUInt32();
}
}
}
@@ -0,0 +1,20 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class UInt64Reader : ContentTypeReader<ulong>
{
public UInt64Reader()
{
}
protected internal override ulong Read(ContentReader input, ulong existingInstance)
{
return input.ReadUInt64();
}
}
}
@@ -0,0 +1,22 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework.Content;
namespace Microsoft.Xna.Framework.Content
{
internal class Vector2Reader : ContentTypeReader<Vector2>
{
public Vector2Reader ()
{
}
protected internal override Vector2 Read (ContentReader input, Vector2 existingInstance)
{
return input.ReadVector2 ();
}
}
}
@@ -0,0 +1,22 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Text;
namespace Microsoft.Xna.Framework.Content
{
internal class Vector3Reader : ContentTypeReader<Vector3>
{
public Vector3Reader()
{
}
protected internal override Vector3 Read(ContentReader input, Vector3 existingInstance)
{
return input.ReadVector3();
}
}
}
@@ -0,0 +1,20 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
internal class Vector4Reader : ContentTypeReader<Vector4>
{
public Vector4Reader()
{
}
protected internal override Vector4 Read(ContentReader input, Vector4 existingInstance)
{
return input.ReadVector4();
}
}
}
@@ -0,0 +1,25 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
class VertexBufferReader : ContentTypeReader<VertexBuffer>
{
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;
}
}
}
@@ -0,0 +1,27 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Content
{
internal class VertexDeclarationReader : ContentTypeReader<VertexDeclaration>
{
protected internal override VertexDeclaration Read(ContentReader reader, VertexDeclaration existingInstance)
{
var vertexStride = reader.ReadInt32();
var elementCount = reader.ReadInt32();
VertexElement[] elements = new VertexElement[elementCount];
for (int i = 0; i < elementCount; ++i)
{
var offset = reader.ReadInt32();
var elementFormat = (VertexElementFormat)reader.ReadInt32();
var elementUsage = (VertexElementUsage)reader.ReadInt32();
var usageIndex = reader.ReadInt32();
elements[i] = new VertexElement(offset, elementFormat, elementUsage, usageIndex);
}
return VertexDeclaration.GetOrCreate(vertexStride, elements);
}
}
}
@@ -0,0 +1,74 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public sealed class ContentSerializerAttribute : Attribute
{
private string _collectionItemName;
/// <summary>
/// Creates an instance of the attribute.
/// </summary>
public ContentSerializerAttribute()
{
AllowNull = true;
}
public bool AllowNull { get; set; }
/// <summary>
/// Returns the overriden XML element name or the default "Item".
/// </summary>
public string CollectionItemName
{
get
{
// Return the defaul if unset.
if (string.IsNullOrEmpty(_collectionItemName))
return "Item";
return _collectionItemName;
}
set
{
_collectionItemName = value;
}
}
public string ElementName { get; set; }
public bool FlattenContent { get; set; }
/// <summary>
/// Returns true if the default CollectionItemName value was overridden.
/// </summary>
public bool HasCollectionItemName
{
get
{
return !string.IsNullOrEmpty(_collectionItemName);
}
}
public bool Optional { get; set; }
public bool SharedResource { get; set; }
public ContentSerializerAttribute Clone()
{
var clone = new ContentSerializerAttribute ();
clone.AllowNull = AllowNull;
clone._collectionItemName = _collectionItemName;
clone.ElementName = ElementName;
clone.FlattenContent = FlattenContent;
clone.Optional = Optional;
clone.SharedResource = SharedResource;
return clone;
}
}
}
@@ -0,0 +1,30 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
/// <summary>
/// This is used to specify the XML element name to use for each item in a collection.
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public sealed class ContentSerializerCollectionItemNameAttribute : Attribute
{
/// <summary>
/// Creates an instance of the attribute.
/// </summary>
/// <param name="collectionItemName">The XML element name to use for each item in the collection.</param>
public ContentSerializerCollectionItemNameAttribute(string collectionItemName)
{
CollectionItemName = collectionItemName;
}
/// <summary>
/// The XML element name to use for each item in the collection.
/// </summary>
public string CollectionItemName { get; private set;}
}
}
@@ -0,0 +1,57 @@
// #region License
// /*
// Microsoft Public License (Ms-PL)
// MonoGame - Copyright © 2009 The MonoGame Team
//
// All rights reserved.
//
// This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
// accept the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
// U.S. copyright law.
//
// A "contribution" is the original software, or any additions or changes to the software.
// A "contributor" is any person that distributes its contribution under this license.
// "Licensed patents" are a contributor's patent claims that read directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
// your patent license from such contributor to the software ends automatically.
// (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source code form, you may do so only under this license by including
// a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies with this license.
// (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
// or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
// permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
// purpose and non-infringement.
// */
// #endregion License
//
// Author: Kenneth James Pouncey
//
using System;
namespace Microsoft.Xna.Framework.Content
{
// http://msdn.microsoft.com/en-us/library/bb195465.aspx
// The class definition on msdn site shows: [AttributeUsageAttribute(384)]
// The following code var ff = (AttributeTargets)384; shows that ff is Field | Property
// so that is what we use.
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public sealed class ContentSerializerIgnoreAttribute : Attribute
{
}
}
@@ -0,0 +1,30 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
/// <summary>
/// This is used to specify the type to use when deserializing this object at runtime.
/// </summary>
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class)]
public sealed class ContentSerializerRuntimeTypeAttribute : Attribute
{
/// <summary>
/// Creates an instance of the attribute.
/// </summary>
/// <param name="runtimeType">The name of the type to use at runtime.</param>
public ContentSerializerRuntimeTypeAttribute(string runtimeType)
{
RuntimeType = runtimeType;
}
/// <summary>
/// The name of the type to use at runtime.
/// </summary>
public string RuntimeType { get; private set;}
}
}
@@ -0,0 +1,30 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Content
{
/// <summary>
/// This is used to specify the version when deserializing this object at runtime.
/// </summary>
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class)]
public sealed class ContentSerializerTypeVersionAttribute : Attribute
{
/// <summary>
/// Creates an instance of the attribute.
/// </summary>
/// <param name="typeVersion">The version passed to the type at runtime.</param>
public ContentSerializerTypeVersionAttribute(int typeVersion)
{
TypeVersion = typeVersion;
}
/// <summary>
/// The version passed to the type at runtime.
/// </summary>
public int TypeVersion { get; private set; }
}
}
@@ -0,0 +1,64 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.IO;
namespace Microsoft.Xna.Framework.Content
{
public abstract class ContentTypeReader
{
private Type _targetType;
public virtual bool CanDeserializeIntoExistingObject
{
get { return false; }
}
public Type TargetType
{
get { return _targetType; }
}
public virtual int TypeVersion
{
get { return 0; } // The default version (unless overridden) is zero
}
protected ContentTypeReader(Type targetType)
{
_targetType = targetType;
}
protected internal virtual void Initialize(ContentTypeReaderManager manager)
{
// Do nothing. Are we supposed to add ourselves to the manager?
}
protected internal abstract object Read(ContentReader input, object existingInstance);
}
public abstract class ContentTypeReader<T> : ContentTypeReader
{
protected ContentTypeReader()
: base(typeof(T))
{
// Nothing
}
protected internal override object Read(ContentReader input, object existingInstance)
{
// as per the documentation http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.content.contenttypereader.read.aspx
// existingInstance
// The object receiving the data, or null if a new instance of the object should be created.
if (existingInstance == null)
{
return Read(input, default(T));
}
return Read(input, (T)existingInstance);
}
protected internal abstract T Read(ContentReader input, T existingInstance);
}
}
@@ -0,0 +1,247 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using MonoGame.Utilities;
namespace Microsoft.Xna.Framework.Content
{
public sealed class ContentTypeReaderManager
{
private static readonly object _locker;
private static readonly Dictionary<Type, ContentTypeReader> _contentReadersCache;
private Dictionary<Type, ContentTypeReader> _contentReaders;
private static readonly string _assemblyName;
static ContentTypeReaderManager()
{
_locker = new object();
_contentReadersCache = new Dictionary<Type, ContentTypeReader>(255);
_assemblyName = ReflectionHelpers.GetAssembly(typeof(ContentTypeReaderManager)).FullName;
}
public ContentTypeReader GetTypeReader(Type targetType)
{
if (targetType.IsArray && targetType.GetArrayRank() > 1)
targetType = typeof(Array);
ContentTypeReader reader;
if (_contentReaders.TryGetValue(targetType, out reader))
return reader;
return null;
}
// Trick to prevent the linker removing the code, but not actually execute the code
static bool falseflag = false;
internal ContentTypeReader[] LoadAssetReaders(ContentReader reader)
{
#pragma warning disable 0219, 0649
// Trick to prevent the linker removing the code, but not actually execute the code
if (falseflag)
{
// 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
var hByteReader = new ByteReader();
var hSByteReader = new SByteReader();
var hDateTimeReader = new DateTimeReader();
var hDecimalReader = new DecimalReader();
var hBoundingSphereReader = new BoundingSphereReader();
var hBoundingFrustumReader = new BoundingFrustumReader();
var hRayReader = new RayReader();
var hCharListReader = new ListReader<Char>();
var hRectangleListReader = new ListReader<Rectangle>();
var hRectangleArrayReader = new ArrayReader<Rectangle>();
var hVector3ListReader = new ListReader<Vector3>();
var hStringListReader = new ListReader<StringReader>();
var hIntListReader = new ListReader<Int32>();
var hSpriteFontReader = new SpriteFontReader();
var hTexture2DReader = new Texture2DReader();
var hCharReader = new CharReader();
var hRectangleReader = new RectangleReader();
var hStringReader = new StringReader();
var hVector2Reader = new Vector2Reader();
var hVector3Reader = new Vector3Reader();
var hVector4Reader = new Vector4Reader();
var hCurveReader = new CurveReader();
var hIndexBufferReader = new IndexBufferReader();
var hBoundingBoxReader = new BoundingBoxReader();
var hMatrixReader = new MatrixReader();
var hBasicEffectReader = new BasicEffectReader();
var hVertexBufferReader = new VertexBufferReader();
var hAlphaTestEffectReader = new AlphaTestEffectReader();
var hEnumSpriteEffectsReader = new EnumReader<Graphics.SpriteEffects>();
var hArrayFloatReader = new ArrayReader<float>();
var hArrayVector2Reader = new ArrayReader<Vector2>();
var hListVector2Reader = new ListReader<Vector2>();
var hArrayMatrixReader = new ArrayReader<Matrix>();
var hEnumBlendReader = new EnumReader<Graphics.Blend>();
var hNullableRectReader = new NullableReader<Rectangle>();
var hEffectMaterialReader = new EffectMaterialReader();
var hExternalReferenceReader = new ExternalReferenceReader();
var hModelReader = new ModelReader();
var hInt32Reader = new Int32Reader();
var hEffectReader = new EffectReader();
var hSingleReader = new SingleReader();
}
#pragma warning restore 0219, 0649
// The first content byte i read tells me the number of content readers in this XNB file
var numberOfReaders = reader.Read7BitEncodedInt();
var contentReaders = new ContentTypeReader[numberOfReaders];
var needsInitialize = new BitArray(numberOfReaders);
_contentReaders = new Dictionary<Type, ContentTypeReader>(numberOfReaders);
// Lock until we're done allocating and initializing any new
// content type readers... this ensures we can load content
// from multiple threads and still cache the readers.
lock (_locker)
{
// 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 (var 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();
Func<ContentTypeReader> readerFunc;
if (typeCreators.TryGetValue(originalReaderTypeString, out readerFunc))
{
contentReaders[i] = readerFunc();
needsInitialize[i] = true;
}
else
{
//System.Diagnostics.Debug.WriteLine(originalReaderTypeString);
// Need to resolve namespace differences
string readerTypeString = originalReaderTypeString;
readerTypeString = PrepareType(readerTypeString);
var l_readerType = Type.GetType(readerTypeString);
if (l_readerType != null)
{
ContentTypeReader typeReader;
if (!_contentReadersCache.TryGetValue(l_readerType, out typeReader))
{
try
{
typeReader = l_readerType.GetDefaultConstructor().Invoke(null) as ContentTypeReader;
}
catch (TargetInvocationException ex)
{
// If you are getting here, the Mono runtime is most likely not able to JIT the type.
// In particular, MonoTouch needs help instantiating types that are only defined in strings in Xnb files.
throw new InvalidOperationException(
"Failed to get default constructor for ContentTypeReader. To work around, add a creation function to ContentTypeReaderManager.AddTypeCreator() " +
"with the following failed type string: " + originalReaderTypeString, ex);
}
needsInitialize[i] = true;
_contentReadersCache.Add(l_readerType, typeReader);
}
contentReaders[i] = typeReader;
}
else
throw new ContentLoadException(
"Could not find ContentTypeReader Type. Please ensure the name of the Assembly that contains the Type matches the assembly in the full type name: " +
originalReaderTypeString + " (" + readerTypeString + ")");
}
var targetType = contentReaders[i].TargetType;
if (targetType != null)
if (!_contentReaders.ContainsKey(targetType))
_contentReaders.Add(targetType, contentReaders[i]);
// I think the next 4 bytes refer to the "Version" of the type reader,
// although it always seems to be zero
reader.ReadInt32();
}
// Initialize any new readers.
for (var i = 0; i < contentReaders.Length; i++)
{
if (needsInitialize.Get(i))
contentReaders[i].Initialize(this);
}
} // lock (_locker)
return contentReaders;
}
/// <summary>
/// Removes Version, Culture and PublicKeyToken from a type string.
/// </summary>
/// <remarks>
/// Supports multiple generic types (e.g. Dictionary&lt;TKey,TValue&gt;) and nested generic types (e.g. List&lt;List&lt;int&gt;&gt;).
/// </remarks>
/// <param name="type">
/// A <see cref="System.String"/>
/// </param>
/// <returns>
/// A <see cref="System.String"/>
/// </returns>
public static string PrepareType(string type)
{
//Needed to support nested types
int count = type.Split(new[] {"[["}, StringSplitOptions.None).Length - 1;
string preparedType = type;
for(int i=0; i<count; i++)
{
preparedType = Regex.Replace(preparedType, @"\[(.+?), Version=.+?\]", "[$1]");
}
//Handle non generic types
if(preparedType.Contains("PublicKeyToken"))
preparedType = Regex.Replace(preparedType, @"(.+?), Version=.+?$", "$1");
// TODO: For WinRT this is most likely broken!
preparedType = preparedType.Replace(", Microsoft.Xna.Framework.Graphics", string.Format(", {0}", _assemblyName));
preparedType = preparedType.Replace(", Microsoft.Xna.Framework.Video", string.Format(", {0}", _assemblyName));
preparedType = preparedType.Replace(", Microsoft.Xna.Framework", string.Format(", {0}", _assemblyName));
return preparedType;
}
// Static map of type names to creation functions. Required as iOS requires all types at compile time
private static Dictionary<string, Func<ContentTypeReader>> typeCreators = new Dictionary<string, Func<ContentTypeReader>>();
/// <summary>
/// Adds the type creator.
/// </summary>
/// <param name='typeString'>
/// Type string.
/// </param>
/// <param name='createFunction'>
/// Create function.
/// </param>
public static void AddTypeCreator(string typeString, Func<ContentTypeReader> createFunction)
{
if (!typeCreators.ContainsKey(typeString))
typeCreators.Add(typeString, createFunction);
}
public static void ClearTypeCreators()
{
typeCreators.Clear();
}
}
}
@@ -0,0 +1,780 @@
#region HEADER
/* This file was derived from libmspack
* (C) 2003-2004 Stuart Caie.
* (C) 2011 Ali Scissons.
*
* The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted
* by Microsoft Corporation.
*
* This source file is Dual licensed; meaning the end-user of this source file
* may redistribute/modify it under the LGPL 2.1 or MS-PL licenses.
*/
#region LGPL License
/* GNU LESSER GENERAL PUBLIC LICENSE version 2.1
* LzxDecoder is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License (LGPL) version 2.1
*/
#endregion
#region MS-PL License
/*
* MICROSOFT PUBLIC LICENSE
* This source code is subject to the terms of the Microsoft Public License (Ms-PL).
*
* Redistribution and use in source and binary forms, with or without modification,
* is permitted provided that redistributions of the source code retain the above
* copyright notices and this file header.
*
* Additional copyright notices should be appended to the list above.
*
* For details, see <http://www.opensource.org/licenses/ms-pl.html>.
*/
#endregion
/*
* This derived work is recognized by Stuart Caie and is authorized to adapt
* any changes made to lzxd.c in his libmspack library and will still retain
* this dual licensing scheme. Big thanks to Stuart Caie!
*
* DETAILS
* This file is a pure C# port of the lzxd.c file from libmspack, with minor
* changes towards the decompression of XNB files. The original decompression
* software of LZX encoded data was written by Suart Caie in his
* libmspack/cabextract projects, which can be located at
* http://http://www.cabextract.org.uk/
*/
#endregion
using System;
using System.Diagnostics;
namespace Microsoft.Xna.Framework.Content
{
using System.IO;
class LzxDecoder
{
public static uint[] position_base = null;
public static byte[] extra_bits = null;
private LzxState m_state;
public LzxDecoder (int window)
{
uint wndsize = (uint)(1 << window);
int posn_slots;
// setup proper exception
if(window < 15 || window > 21) throw new UnsupportedWindowSizeRange();
// let's initialise our state
m_state = new LzxState();
m_state.actual_size = 0;
m_state.window = new byte[wndsize];
for(int i = 0; i < wndsize; i++) m_state.window[i] = 0xDC;
m_state.actual_size = wndsize;
m_state.window_size = wndsize;
m_state.window_posn = 0;
/* initialize static tables */
if(extra_bits == null)
{
extra_bits = new byte[52];
for(int i = 0, j = 0; i <= 50; i += 2)
{
extra_bits[i] = extra_bits[i+1] = (byte)j;
if ((i != 0) && (j < 17)) j++;
}
}
if(position_base == null)
{
position_base = new uint[51];
for(int i = 0, j = 0; i <= 50; i++)
{
position_base[i] = (uint)j;
j += 1 << extra_bits[i];
}
}
/* calculate required position slots */
if(window == 20) posn_slots = 42;
else if(window == 21) posn_slots = 50;
else posn_slots = window << 1;
m_state.R0 = m_state.R1 = m_state.R2 = 1;
m_state.main_elements = (ushort)(LzxConstants.NUM_CHARS + (posn_slots << 3));
m_state.header_read = 0;
m_state.frames_read = 0;
m_state.block_remaining = 0;
m_state.block_type = LzxConstants.BLOCKTYPE.INVALID;
m_state.intel_curpos = 0;
m_state.intel_started = 0;
// yo dawg i herd u liek arrays so we put arrays in ur arrays so u can array while u array
m_state.PRETREE_table = new ushort[(1 << LzxConstants.PRETREE_TABLEBITS) + (LzxConstants.PRETREE_MAXSYMBOLS << 1)];
m_state.PRETREE_len = new byte[LzxConstants.PRETREE_MAXSYMBOLS + LzxConstants.LENTABLE_SAFETY];
m_state.MAINTREE_table = new ushort[(1 << LzxConstants.MAINTREE_TABLEBITS) + (LzxConstants.MAINTREE_MAXSYMBOLS << 1)];
m_state.MAINTREE_len = new byte[LzxConstants.MAINTREE_MAXSYMBOLS + LzxConstants.LENTABLE_SAFETY];
m_state.LENGTH_table = new ushort[(1 << LzxConstants.LENGTH_TABLEBITS) + (LzxConstants.LENGTH_MAXSYMBOLS << 1)];
m_state.LENGTH_len = new byte[LzxConstants.LENGTH_MAXSYMBOLS + LzxConstants.LENTABLE_SAFETY];
m_state.ALIGNED_table = new ushort[(1 << LzxConstants.ALIGNED_TABLEBITS) + (LzxConstants.ALIGNED_MAXSYMBOLS << 1)];
m_state.ALIGNED_len = new byte[LzxConstants.ALIGNED_MAXSYMBOLS + LzxConstants.LENTABLE_SAFETY];
/* initialise tables to 0 (because deltas will be applied to them) */
for(int i = 0; i < LzxConstants.MAINTREE_MAXSYMBOLS; i++) m_state.MAINTREE_len[i] = 0;
for(int i = 0; i < LzxConstants.LENGTH_MAXSYMBOLS; i++) m_state.LENGTH_len[i] = 0;
}
public int Decompress(Stream inData, int inLen, Stream outData, int outLen)
{
BitBuffer bitbuf = new BitBuffer(inData);
long startpos = inData.Position;
long endpos = inData.Position + inLen;
byte[] window = m_state.window;
uint window_posn = m_state.window_posn;
uint window_size = m_state.window_size;
uint R0 = m_state.R0;
uint R1 = m_state.R1;
uint R2 = m_state.R2;
uint i, j;
int togo = outLen, this_run, main_element, match_length, match_offset, length_footer, extra, verbatim_bits;
int rundest, runsrc, copy_length, aligned_bits;
bitbuf.InitBitStream();
/* read header if necessary */
if(m_state.header_read == 0)
{
uint intel = bitbuf.ReadBits(1);
if(intel != 0)
{
// read the filesize
i = bitbuf.ReadBits(16); j = bitbuf.ReadBits(16);
m_state.intel_filesize = (int)((i << 16) | j);
}
m_state.header_read = 1;
}
/* main decoding loop */
while(togo > 0)
{
/* last block finished, new block expected */
if(m_state.block_remaining == 0)
{
// TODO may screw something up here
if(m_state.block_type == LzxConstants.BLOCKTYPE.UNCOMPRESSED) {
if((m_state.block_length & 1) == 1) inData.ReadByte(); /* realign bitstream to word */
bitbuf.InitBitStream();
}
m_state.block_type = (LzxConstants.BLOCKTYPE)bitbuf.ReadBits(3);;
i = bitbuf.ReadBits(16);
j = bitbuf.ReadBits(8);
m_state.block_remaining = m_state.block_length = (uint)((i << 8) | j);
switch(m_state.block_type)
{
case LzxConstants.BLOCKTYPE.ALIGNED:
for(i = 0, j = 0; i < 8; i++) { j = bitbuf.ReadBits(3); m_state.ALIGNED_len[i] = (byte)j; }
MakeDecodeTable(LzxConstants.ALIGNED_MAXSYMBOLS, LzxConstants.ALIGNED_TABLEBITS,
m_state.ALIGNED_len, m_state.ALIGNED_table);
/* rest of aligned header is same as verbatim */
goto case LzxConstants.BLOCKTYPE.VERBATIM;
case LzxConstants.BLOCKTYPE.VERBATIM:
ReadLengths(m_state.MAINTREE_len, 0, 256, bitbuf);
ReadLengths(m_state.MAINTREE_len, 256, m_state.main_elements, bitbuf);
MakeDecodeTable(LzxConstants.MAINTREE_MAXSYMBOLS, LzxConstants.MAINTREE_TABLEBITS,
m_state.MAINTREE_len, m_state.MAINTREE_table);
if(m_state.MAINTREE_len[0xE8] != 0) m_state.intel_started = 1;
ReadLengths(m_state.LENGTH_len, 0, LzxConstants.NUM_SECONDARY_LENGTHS, bitbuf);
MakeDecodeTable(LzxConstants.LENGTH_MAXSYMBOLS, LzxConstants.LENGTH_TABLEBITS,
m_state.LENGTH_len, m_state.LENGTH_table);
break;
case LzxConstants.BLOCKTYPE.UNCOMPRESSED:
m_state.intel_started = 1; /* because we can't assume otherwise */
bitbuf.EnsureBits(16); /* get up to 16 pad bits into the buffer */
if(bitbuf.GetBitsLeft() > 16) inData.Seek(-2, SeekOrigin.Current); /* and align the bitstream! */
byte hi, mh, ml, lo;
lo = (byte)inData.ReadByte(); ml = (byte)inData.ReadByte(); mh = (byte)inData.ReadByte(); hi = (byte)inData.ReadByte();
R0 = (uint)(lo | ml << 8 | mh << 16 | hi << 24);
lo = (byte)inData.ReadByte(); ml = (byte)inData.ReadByte(); mh = (byte)inData.ReadByte(); hi = (byte)inData.ReadByte();
R1 = (uint)(lo | ml << 8 | mh << 16 | hi << 24);
lo = (byte)inData.ReadByte(); ml = (byte)inData.ReadByte(); mh = (byte)inData.ReadByte(); hi = (byte)inData.ReadByte();
R2 = (uint)(lo | ml << 8 | mh << 16 | hi << 24);
break;
default:
return -1; // TODO throw proper exception
}
}
/* buffer exhaustion check */
if(inData.Position > (startpos + inLen))
{
/* it's possible to have a file where the next run is less than
* 16 bits in size. In this case, the READ_HUFFSYM() macro used
* in building the tables will exhaust the buffer, so we should
* allow for this, but not allow those accidentally read bits to
* be used (so we check that there are at least 16 bits
* remaining - in this boundary case they aren't really part of
* the compressed data)
*/
//Debug.WriteLine("WTF");
if(inData.Position > (startpos+inLen+2) || bitbuf.GetBitsLeft() < 16) return -1; //TODO throw proper exception
}
while((this_run = (int)m_state.block_remaining) > 0 && togo > 0)
{
if(this_run > togo) this_run = togo;
togo -= this_run;
m_state.block_remaining -= (uint)this_run;
/* apply 2^x-1 mask */
window_posn &= window_size - 1;
/* runs can't straddle the window wraparound */
if((window_posn + this_run) > window_size)
return -1; //TODO throw proper exception
switch(m_state.block_type)
{
case LzxConstants.BLOCKTYPE.VERBATIM:
while(this_run > 0)
{
main_element = (int)ReadHuffSym(m_state.MAINTREE_table, m_state.MAINTREE_len,
LzxConstants.MAINTREE_MAXSYMBOLS, LzxConstants.MAINTREE_TABLEBITS,
bitbuf);
if(main_element < LzxConstants.NUM_CHARS)
{
/* literal: 0 to NUM_CHARS-1 */
window[window_posn++] = (byte)main_element;
this_run--;
}
else
{
/* match: NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
main_element -= LzxConstants.NUM_CHARS;
match_length = main_element & LzxConstants.NUM_PRIMARY_LENGTHS;
if(match_length == LzxConstants.NUM_PRIMARY_LENGTHS)
{
length_footer = (int)ReadHuffSym(m_state.LENGTH_table, m_state.LENGTH_len,
LzxConstants.LENGTH_MAXSYMBOLS, LzxConstants.LENGTH_TABLEBITS,
bitbuf);
match_length += length_footer;
}
match_length += LzxConstants.MIN_MATCH;
match_offset = main_element >> 3;
if(match_offset > 2)
{
/* not repeated offset */
if(match_offset != 3)
{
extra = extra_bits[match_offset];
verbatim_bits = (int)bitbuf.ReadBits((byte)extra);
match_offset = (int)position_base[match_offset] - 2 + verbatim_bits;
}
else
{
match_offset = 1;
}
/* update repeated offset LRU queue */
R2 = R1; R1 = R0; R0 = (uint)match_offset;
}
else if(match_offset == 0)
{
match_offset = (int)R0;
}
else if(match_offset == 1)
{
match_offset = (int)R1;
R1 = R0; R0 = (uint)match_offset;
}
else /* match_offset == 2 */
{
match_offset = (int)R2;
R2 = R0; R0 = (uint)match_offset;
}
rundest = (int)window_posn;
this_run -= match_length;
/* copy any wrapped around source data */
if(window_posn >= match_offset)
{
/* no wrap */
runsrc = rundest - match_offset;
}
else
{
runsrc = rundest + ((int)window_size - match_offset);
copy_length = match_offset - (int)window_posn;
if(copy_length < match_length)
{
match_length -= copy_length;
window_posn += (uint)copy_length;
while(copy_length-- > 0) window[rundest++] = window[runsrc++];
runsrc = 0;
}
}
window_posn += (uint)match_length;
/* copy match data - no worries about destination wraps */
while(match_length-- > 0) window[rundest++] = window[runsrc++];
}
}
break;
case LzxConstants.BLOCKTYPE.ALIGNED:
while(this_run > 0)
{
main_element = (int)ReadHuffSym(m_state.MAINTREE_table, m_state.MAINTREE_len,
LzxConstants.MAINTREE_MAXSYMBOLS, LzxConstants.MAINTREE_TABLEBITS,
bitbuf);
if(main_element < LzxConstants.NUM_CHARS)
{
/* literal 0 to NUM_CHARS-1 */
window[window_posn++] = (byte)main_element;
this_run--;
}
else
{
/* match: NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
main_element -= LzxConstants.NUM_CHARS;
match_length = main_element & LzxConstants.NUM_PRIMARY_LENGTHS;
if(match_length == LzxConstants.NUM_PRIMARY_LENGTHS)
{
length_footer = (int)ReadHuffSym(m_state.LENGTH_table, m_state.LENGTH_len,
LzxConstants.LENGTH_MAXSYMBOLS, LzxConstants.LENGTH_TABLEBITS,
bitbuf);
match_length += length_footer;
}
match_length += LzxConstants.MIN_MATCH;
match_offset = main_element >> 3;
if(match_offset > 2)
{
/* not repeated offset */
extra = extra_bits[match_offset];
match_offset = (int)position_base[match_offset] - 2;
if(extra > 3)
{
/* verbatim and aligned bits */
extra -= 3;
verbatim_bits = (int)bitbuf.ReadBits((byte)extra);
match_offset += (verbatim_bits << 3);
aligned_bits = (int)ReadHuffSym(m_state.ALIGNED_table, m_state.ALIGNED_len,
LzxConstants.ALIGNED_MAXSYMBOLS, LzxConstants.ALIGNED_TABLEBITS,
bitbuf);
match_offset += aligned_bits;
}
else if(extra == 3)
{
/* aligned bits only */
aligned_bits = (int)ReadHuffSym(m_state.ALIGNED_table, m_state.ALIGNED_len,
LzxConstants.ALIGNED_MAXSYMBOLS, LzxConstants.ALIGNED_TABLEBITS,
bitbuf);
match_offset += aligned_bits;
}
else if (extra > 0) /* extra==1, extra==2 */
{
/* verbatim bits only */
verbatim_bits = (int)bitbuf.ReadBits((byte)extra);
match_offset += verbatim_bits;
}
else /* extra == 0 */
{
/* ??? */
match_offset = 1;
}
/* update repeated offset LRU queue */
R2 = R1; R1 = R0; R0 = (uint)match_offset;
}
else if( match_offset == 0)
{
match_offset = (int)R0;
}
else if(match_offset == 1)
{
match_offset = (int)R1;
R1 = R0; R0 = (uint)match_offset;
}
else /* match_offset == 2 */
{
match_offset = (int)R2;
R2 = R0; R0 = (uint)match_offset;
}
rundest = (int)window_posn;
this_run -= match_length;
/* copy any wrapped around source data */
if(window_posn >= match_offset)
{
/* no wrap */
runsrc = rundest - match_offset;
}
else
{
runsrc = rundest + ((int)window_size - match_offset);
copy_length = match_offset - (int)window_posn;
if(copy_length < match_length)
{
match_length -= copy_length;
window_posn += (uint)copy_length;
while(copy_length-- > 0) window[rundest++] = window[runsrc++];
runsrc = 0;
}
}
window_posn += (uint)match_length;
/* copy match data - no worries about destination wraps */
while(match_length-- > 0) window[rundest++] = window[runsrc++];
}
}
break;
case LzxConstants.BLOCKTYPE.UNCOMPRESSED:
if((inData.Position + this_run) > endpos) return -1; //TODO throw proper exception
byte[] temp_buffer = new byte[this_run];
inData.Read(temp_buffer, 0, this_run);
temp_buffer.CopyTo(window, (int)window_posn);
window_posn += (uint)this_run;
break;
default:
return -1; //TODO throw proper exception
}
}
}
if(togo != 0) return -1; //TODO throw proper exception
int start_window_pos = (int)window_posn;
if(start_window_pos == 0) start_window_pos = (int)window_size;
start_window_pos -= outLen;
outData.Write(window, start_window_pos, outLen);
m_state.window_posn = window_posn;
m_state.R0 = R0;
m_state.R1 = R1;
m_state.R2 = R2;
// TODO finish intel E8 decoding
/* intel E8 decoding */
if((m_state.frames_read++ < 32768) && m_state.intel_filesize != 0)
{
if(outLen <= 6 || m_state.intel_started == 0)
{
m_state.intel_curpos += outLen;
}
else
{
int dataend = outLen - 10;
uint curpos = (uint)m_state.intel_curpos;
m_state.intel_curpos = (int)curpos + outLen;
while(outData.Position < dataend)
{
if(outData.ReadByte() != 0xE8) { curpos++; continue; }
}
}
return -1;
}
return 0;
}
// READ_LENGTHS(table, first, last)
// if(lzx_read_lens(LENTABLE(table), first, last, bitsleft))
// return ERROR (ILLEGAL_DATA)
//
// TODO make returns throw exceptions
private int MakeDecodeTable(uint nsyms, uint nbits, byte[] length, ushort[] table)
{
ushort sym;
uint leaf;
byte bit_num = 1;
uint fill;
uint pos = 0; /* the current position in the decode table */
uint table_mask = (uint)(1 << (int)nbits);
uint bit_mask = table_mask >> 1; /* don't do 0 length codes */
uint next_symbol = bit_mask; /* base of allocation for long codes */
/* fill entries for codes short enough for a direct mapping */
while (bit_num <= nbits )
{
for(sym = 0; sym < nsyms; sym++)
{
if(length[sym] == bit_num)
{
leaf = pos;
if((pos += bit_mask) > table_mask) return 1; /* table overrun */
/* fill all possible lookups of this symbol with the symbol itself */
fill = bit_mask;
while(fill-- > 0) table[leaf++] = sym;
}
}
bit_mask >>= 1;
bit_num++;
}
/* if there are any codes longer than nbits */
if(pos != table_mask)
{
/* clear the remainder of the table */
for(sym = (ushort)pos; sym < table_mask; sym++) table[sym] = 0;
/* give ourselves room for codes to grow by up to 16 more bits */
pos <<= 16;
table_mask <<= 16;
bit_mask = 1 << 15;
while(bit_num <= 16)
{
for(sym = 0; sym < nsyms; sym++)
{
if(length[sym] == bit_num)
{
leaf = pos >> 16;
for(fill = 0; fill < bit_num - nbits; fill++)
{
/* if this path hasn't been taken yet, 'allocate' two entries */
if(table[leaf] == 0)
{
table[(next_symbol << 1)] = 0;
table[(next_symbol << 1) + 1] = 0;
table[leaf] = (ushort)(next_symbol++);
}
/* follow the path and select either left or right for next bit */
leaf = (uint)(table[leaf] << 1);
if(((pos >> (int)(15-fill)) & 1) == 1) leaf++;
}
table[leaf] = sym;
if((pos += bit_mask) > table_mask) return 1;
}
}
bit_mask >>= 1;
bit_num++;
}
}
/* full talbe? */
if(pos == table_mask) return 0;
/* either erroneous table, or all elements are 0 - let's find out. */
for(sym = 0; sym < nsyms; sym++) if(length[sym] != 0) return 1;
return 0;
}
// TODO throw exceptions instead of returns
private void ReadLengths(byte[] lens, uint first, uint last, BitBuffer bitbuf)
{
uint x, y;
int z;
// hufftbl pointer here?
for(x = 0; x < 20; x++)
{
y = bitbuf.ReadBits(4);
m_state.PRETREE_len[x] = (byte)y;
}
MakeDecodeTable(LzxConstants.PRETREE_MAXSYMBOLS, LzxConstants.PRETREE_TABLEBITS,
m_state.PRETREE_len, m_state.PRETREE_table);
for(x = first; x < last;)
{
z = (int)ReadHuffSym(m_state.PRETREE_table, m_state.PRETREE_len,
LzxConstants.PRETREE_MAXSYMBOLS, LzxConstants.PRETREE_TABLEBITS, bitbuf);
if(z == 17)
{
y = bitbuf.ReadBits(4); y += 4;
while(y-- != 0) lens[x++] = 0;
}
else if(z == 18)
{
y = bitbuf.ReadBits(5); y += 20;
while(y-- != 0) lens[x++] = 0;
}
else if(z == 19)
{
y = bitbuf.ReadBits(1); y += 4;
z = (int)ReadHuffSym(m_state.PRETREE_table, m_state.PRETREE_len,
LzxConstants.PRETREE_MAXSYMBOLS, LzxConstants.PRETREE_TABLEBITS, bitbuf);
z = lens[x] - z; if(z < 0) z += 17;
while(y-- != 0) lens[x++] = (byte)z;
}
else
{
z = lens[x] - z; if(z < 0) z += 17;
lens[x++] = (byte)z;
}
}
}
private uint ReadHuffSym(ushort[] table, byte[] lengths, uint nsyms, uint nbits, BitBuffer bitbuf)
{
uint i, j;
bitbuf.EnsureBits(16);
if((i = table[bitbuf.PeekBits((byte)nbits)]) >= nsyms)
{
j = (uint)(1 << (int)((sizeof(uint)*8) - nbits));
do
{
j >>= 1; i <<= 1; i |= (bitbuf.GetBuffer() & j) != 0 ? (uint)1 : 0;
if(j == 0) return 0; // TODO throw proper exception
} while((i = table[i]) >= nsyms);
}
j = lengths[i];
bitbuf.RemoveBits((byte)j);
return i;
}
#region Our BitBuffer Class
private class BitBuffer
{
uint buffer;
byte bitsleft;
Stream byteStream;
public BitBuffer(Stream stream)
{
byteStream = stream;
InitBitStream();
}
public void InitBitStream()
{
buffer = 0;
bitsleft = 0;
}
public void EnsureBits(byte bits)
{
while(bitsleft < bits) {
int lo = (byte)byteStream.ReadByte();
int hi = (byte)byteStream.ReadByte();
//int amount2shift = sizeof(uint)*8 - 16 - bitsleft;
buffer |= (uint)(((hi << 8) | lo) << (sizeof(uint)*8 - 16 - bitsleft));
bitsleft += 16;
}
}
public uint PeekBits(byte bits)
{
return (buffer >> ((sizeof(uint)*8) - bits));
}
public void RemoveBits(byte bits)
{
buffer <<= bits;
bitsleft -= bits;
}
public uint ReadBits(byte bits)
{
uint ret = 0;
if(bits > 0)
{
EnsureBits(bits);
ret = PeekBits(bits);
RemoveBits(bits);
}
return ret;
}
public uint GetBuffer()
{
return buffer;
}
public byte GetBitsLeft()
{
return bitsleft;
}
}
#endregion
struct LzxState {
public uint R0, R1, R2; /* for the LRU offset system */
public ushort main_elements; /* number of main tree elements */
public int header_read; /* have we started decoding at all yet? */
public LzxConstants.BLOCKTYPE block_type; /* type of this block */
public uint block_length; /* uncompressed length of this block */
public uint block_remaining; /* uncompressed bytes still left to decode */
public uint frames_read; /* the number of CFDATA blocks processed */
public int intel_filesize; /* magic header value used for transform */
public int intel_curpos; /* current offset in transform space */
public int intel_started; /* have we seen any translateable data yet? */
public ushort[] PRETREE_table;
public byte[] PRETREE_len;
public ushort[] MAINTREE_table;
public byte[] MAINTREE_len;
public ushort[] LENGTH_table;
public byte[] LENGTH_len;
public ushort[] ALIGNED_table;
public byte[] ALIGNED_len;
// NEEDED MEMBERS
// CAB actualsize
// CAB window
// CAB window_size
// CAB window_posn
public uint actual_size;
public byte[] window;
public uint window_size;
public uint window_posn;
}
}
/* CONSTANTS */
struct LzxConstants {
public const ushort MIN_MATCH = 2;
public const ushort MAX_MATCH = 257;
public const ushort NUM_CHARS = 256;
public enum BLOCKTYPE {
INVALID = 0,
VERBATIM = 1,
ALIGNED = 2,
UNCOMPRESSED = 3
}
public const ushort PRETREE_NUM_ELEMENTS = 20;
public const ushort ALIGNED_NUM_ELEMENTS = 8;
public const ushort NUM_PRIMARY_LENGTHS = 7;
public const ushort NUM_SECONDARY_LENGTHS = 249;
public const ushort PRETREE_MAXSYMBOLS = PRETREE_NUM_ELEMENTS;
public const ushort PRETREE_TABLEBITS = 6;
public const ushort MAINTREE_MAXSYMBOLS = NUM_CHARS + 50*8;
public const ushort MAINTREE_TABLEBITS = 12;
public const ushort LENGTH_MAXSYMBOLS = NUM_SECONDARY_LENGTHS + 1;
public const ushort LENGTH_TABLEBITS = 12;
public const ushort ALIGNED_MAXSYMBOLS = ALIGNED_NUM_ELEMENTS;
public const ushort ALIGNED_TABLEBITS = 7;
public const ushort LENTABLE_SAFETY = 64;
}
/* EXCEPTIONS */
class UnsupportedWindowSizeRange : Exception
{
}
}
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Resources;
namespace Microsoft.Xna.Framework.Content
{
public class ResourceContentManager : ContentManager
{
private ResourceManager resource;
public ResourceContentManager(IServiceProvider servicesProvider, ResourceManager resource)
: base(servicesProvider)
{
if (resource == null)
{
throw new ArgumentNullException("resource");
}
this.resource = resource;
}
protected override System.IO.Stream OpenStream(string assetName)
{
object obj = this.resource.GetObject(assetName);
if (obj == null)
{
throw new ContentLoadException("Resource not found");
}
if (!(obj is byte[]))
{
throw new ContentLoadException("Resource is not in binary format");
}
return new MemoryStream(obj as byte[]);
}
}
}