(77d1794a) Tester's build January 10th, 2020

This commit is contained in:
juanjp600
2020-01-10 14:42:38 -03:00
parent c02da46ef5
commit e6a08d715b
4529 changed files with 1145046 additions and 218950 deletions

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<dllmap dll="SDL2.dll" os="osx" target="libSDL2-2.0.0.dylib"/>
<dllmap dll="soft_oal.dll" os="osx" target="libopenal.1.dylib" />
<dllmap dll="SDL2.dll" os="linux" cpu="x86" target="./x86/libSDL2-2.0.so.0"/>
<dllmap dll="soft_oal.dll" os="linux" cpu="x86" target="./x86/libopenal.so.1" />
<dllmap dll="SDL2.dll" os="linux" cpu="x86-64" target="./x64/libSDL2-2.0.so.0"/>
<dllmap dll="soft_oal.dll" os="linux" cpu="x86-64" target="./x64/libopenal.so.1" />
</configuration>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
# http://EditorConfig.org
root = true
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.cs]
indent_style = space
indent_size = 4

View File

@@ -0,0 +1,93 @@
#OS junk files
[Tt]humbs.db
*.DS_Store
#Output Linux Installer
Installers/Linux/tmp_deb/
Installers/Linux/tmp_run/
*.run
*.deb
#Visual Studio files
*.pidb
*.userprefs
*.[Oo]bj
*.exe
*.pdb
*.user
*.aps
*.pch
*.vspscc
*.vssscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.[Cc]ache
*.ilk
*.log
*.lib
*.sbr
*.sdf
*.csproj.csdat
ipch/
obj/
[Bb]in
[Dd]ebug*/
[Rr]elease*/
Ankh.NoLoad
.vs/
project.lock.json
/MonoGame.Framework/MonoGame.Framework.Net.WindowsUniversal.project.lock.json
/MonoGame.Framework/MonoGame.Framework.WindowsUniversal.project.lock.json
artifacts/
# JetBrains Rider
.idea/
#Tooling
_ReSharper*/
*.resharper
[Tt]est[Rr]esult*
#Visual Studio Rebracer extension, allows the user to automatically change the style configuration by project
rebracer.xml
#Subversion files
.svn
# Office Temp Files
~$*
#monodroid private beta
monodroid*.msi
#Unix temporary files
*~
# Output docs
Documentation/Output/
# Protobuild Generated Files
*.speccache
*.ncrunchproject
*.ncrunchsolution
#Mac Package Files
*.pkg
*.mpack
**/packages
#Nuget Packages
**/*.nupkg
#Zip files
*.zip
Installers/MacOS/Scripts/Framework/postinstall
IDE/MonoDevelop/MonoDevelop.MonoGame/templates/Common/MonoGame.Framework.dll.config
ThirdParty/*

View File

@@ -0,0 +1,9 @@
[submodule "ThirdParty/Dependencies"]
path = ThirdParty/Dependencies
url = https://github.com/Mono-Game/MonoGame.Dependencies.git
[submodule "ThirdParty/NVorbis"]
path = ThirdParty/NVorbis
url=https://github.com/MrHelmut/NVorbis.git
[submodule "ThirdParty/SDL_GameControllerDB"]
path = ThirdParty/SDL_GameControllerDB
url = https://github.com/gabomdq/SDL_GameControllerDB.git

View File

@@ -0,0 +1,525 @@
# Change Log
## 3.7.1 Release - 12/8/2018
- MGCB now generates content building statistics. [#6401](https://github.com/MonoGame/MonoGame/pull/6401)
- Fixes to dependency loading in Pipeline Tool. [#6450](https://github.com/MonoGame/MonoGame/pull/6450)
- Fixed crash when canceling choose folder dialog in Pipeline Tool. [#6449](https://github.com/MonoGame/MonoGame/pull/6449)
- Fix add item dialog jumping around in Pipeline Tool. [#6451](https://github.com/MonoGame/MonoGame/pull/6451)
- Fix OpenAL library loading on some Android phones. [#6454](https://github.com/MonoGame/MonoGame/pull/6454)
- Fix Gamepad index tracking under UWP. [#6456](https://github.com/MonoGame/MonoGame/pull/6456)
- Rename "Copy Asset Path" to "Copy Asset Name" for consistency with XNA in Pipeline Tool. [#6457](https://github.com/MonoGame/MonoGame/pull/6457)
- Fix TextInput Keys argument for UWP. [#6455](https://github.com/MonoGame/MonoGame/pull/6455)
- Add new GamePad.GetState() overloads to support different dead zone modes. [#6467](https://github.com/MonoGame/MonoGame/pull/6467)
- Fixed incorrect offset DynamicSoundEffectInstance.SubmitBuffer under XAudio. [#6523](https://github.com/MonoGame/MonoGame/pull/6523)
- Improved accuracy of fixed time step. [#6535](https://github.com/MonoGame/MonoGame/pull/6535)
- Ensure intermediate output path exists before writing stats in Pipeline Tool. [#6503](https://github.com/MonoGame/MonoGame/pull/6503)
- Fix for special window close case under SDL. [#6489](https://github.com/MonoGame/MonoGame/pull/6489)
- Marshal microphone identifiers as UTF-8. [#6530](https://github.com/MonoGame/MonoGame/pull/6530)
- Clear the current selections when excluding items in the Pipeline Tool. [#6549](https://github.com/MonoGame/MonoGame/pull/6549)
- Enable standard derivatives extension for GLSL shaders. [#6501](https://github.com/MonoGame/MonoGame/pull/6501)
- Fixed framebuffer object EXT loading under OpenGL. [#6562](https://github.com/MonoGame/MonoGame/pull/6562)
- Fixed GL.RenderbufferStorage for devices that use the EXT entry points. [#6563](https://github.com/MonoGame/MonoGame/pull/6563)
- Fix VS template installation when C# folder is missing. [#6544](https://github.com/MonoGame/MonoGame/pull/6544)
- Fix for SDL loading when a '#' is in the directory path. [#6573](https://github.com/MonoGame/MonoGame/pull/6573)
- Restored Buttons[] constructor in GamePadState fixing XNA compatibility. [#6572](https://github.com/MonoGame/MonoGame/pull/6572)
## 3.7 Release - 9/23/2018
- Remove Scale and Rotation properties from Matrix. [#5584](https://github.com/MonoGame/MonoGame/pull/5584)
- Added Switch as a platform. [#5596](https://github.com/MonoGame/MonoGame/pull/5596)
- DirectX: Fixed multisample clamping logic. [#5477](https://github.com/MonoGame/MonoGame/pull/5477)
- SDL Gamepad DB update. [#5605](https://github.com/MonoGame/MonoGame/pull/5605)
- Add Missing method OpaqueDataDictionary.GetValue. [#5637](https://github.com/MonoGame/MonoGame/pull/5637)
- Increase code coverage in Model* family. [#5632](https://github.com/MonoGame/MonoGame/pull/5632)
- Fix scroll wheel events on Windows Universal. [#5631](https://github.com/MonoGame/MonoGame/pull/5631)
- Implement GetHashCode on Vertex types. [#5654](https://github.com/MonoGame/MonoGame/pull/5654)
- Implement GetHashCode and ToString methods for Joystick. [#5670](https://github.com/MonoGame/MonoGame/pull/5670)
- Fixed Gamepad DPad on Android. [#5673](https://github.com/MonoGame/MonoGame/pull/5673)
- Pipeline process not terminating on exit fix. [#5672](https://github.com/MonoGame/MonoGame/pull/5672)
- Added Joystick.IsSupported property. [#5678](https://github.com/MonoGame/MonoGame/pull/5678)
- Use GraphicsCapabilities.MaxTextureAnisotropy on SamplerState. [#5676](https://github.com/MonoGame/MonoGame/pull/5676)
- Make SpriteBatch.End throw when Begin not called. [#5689](https://github.com/MonoGame/MonoGame/pull/5689)
- Add Open Output Directory option to Pipeline Tool. [#5690](https://github.com/MonoGame/MonoGame/pull/5690)
- Rename Exit to Quit on Pipeline Tool Linux Headerbar. [#5687](https://github.com/MonoGame/MonoGame/pull/5687)
- Added minimum size to the Pipeline Tool window. [#5692](https://github.com/MonoGame/MonoGame/pull/5692)
- Added Id and DisplayName properties to Gamepad. [#5625](https://github.com/MonoGame/MonoGame/pull/5625)
- Improved GameController database loading for DesktopGL. [#5606](https://github.com/MonoGame/MonoGame/pull/5606)
- RPC curves are now updated before Cue is played. [#5709](https://github.com/MonoGame/MonoGame/pull/5709)
- Fixes to Texture2D.FromStream on Windows DirectX. [#5712](https://github.com/MonoGame/MonoGame/pull/5712)
- Support DistanceScale and DopplerFactor under OpenAL. [#5718](https://github.com/MonoGame/MonoGame/pull/5718)
- Implemented Microphone for OpenAL platforms. [#5651](https://github.com/MonoGame/MonoGame/pull/5651)
- Implemented caching of staging resources used to copy data from a Texture2D under DirectX. [#5704](https://github.com/MonoGame/MonoGame/pull/5704)
- Reusable function for raising events. [#5713](https://github.com/MonoGame/MonoGame/pull/5713)
- Remove reference to SharpDX from project templates. [#5611](https://github.com/MonoGame/MonoGame/pull/5611)
- Improvements to VideoPlayer for Desktop DirectX. [#5737](https://github.com/MonoGame/MonoGame/pull/5737)
- Use SharpDX NuGet packages from our NuGet packages. [#5748](https://github.com/MonoGame/MonoGame/pull/5748)
- Fixed leaks that affected shutting down and recreating GraphicsDevice under DirectX. [#5728](https://github.com/MonoGame/MonoGame/pull/5728)
- Texture2D mipmap generation and population fixes. [#5614](https://github.com/MonoGame/MonoGame/pull/5614)
- Remove SharpDX.RawInput.dll reference from DirectX graphics backend. [#5723](https://github.com/MonoGame/MonoGame/pull/5723)
- New fast Texture2D.FromStream implementation for DesktopGL ported from STB. [#5630](https://github.com/MonoGame/MonoGame/pull/5630)
- Added support DrawInstancedPrimitives on OpenGL platforms. [#4920](https://github.com/MonoGame/MonoGame/pull/4920)
- Fixed mouse touch event to release when mouse moves outside the client area or we loses focus. [#5641](https://github.com/MonoGame/MonoGame/pull/5641)
- Added GraphicsAdapter.UseDebugLayers to enable GPU debug features in release builds. [#5791](https://github.com/MonoGame/MonoGame/pull/5791)
- Fixed DirectX back buffer update when multisampling changes. [#5617](https://github.com/MonoGame/MonoGame/pull/5617)
- Adds Xbox One S controller support to Linux. [#5797](https://github.com/MonoGame/MonoGame/pull/5797)
- Do not allow the Pipeline tool to delete files outside the content folder. [#5820](https://github.com/MonoGame/MonoGame/pull/5820)
- OpenGL Mouse.SetCursor now works with alpha correctly. [#5829](https://github.com/MonoGame/MonoGame/pull/5829)
- Implement Mouse.SetCursor() for Windows. [#5831](https://github.com/MonoGame/MonoGame/pull/5831)
- Fix pre-emptive song finish in OggStreamer. [#5821](https://github.com/MonoGame/MonoGame/pull/5821)
- UWP Templates use target version selected in wizard. [#5819](https://github.com/MonoGame/MonoGame/pull/5819)
- Implement Mouse.WindowHandle under Windows DirectX. [#5816](https://github.com/MonoGame/MonoGame/pull/5816)
- Improve shader error/warning parsing in Pipeline Tool. [#5849](https://github.com/MonoGame/MonoGame/pull/5849)
- Fix crash on multi-editing bool values in Pipeline Tool. [#5859](https://github.com/MonoGame/MonoGame/pull/5859)
- Fixes to XACT sound effect pooling. [#5832](https://github.com/MonoGame/MonoGame/pull/5832)
- Improved disposal of OpenGL resources. [#5850](https://github.com/MonoGame/MonoGame/pull/5850)
- Better support for WAV audio formats in content pipeline and FromStream. [#5750](https://github.com/MonoGame/MonoGame/pull/5750)
- Fix for build hang with no mgcb file in project. [#5886](https://github.com/MonoGame/MonoGame/pull/5886)
- Removed deprecated Rider settings from Linux installer. [#5881](https://github.com/MonoGame/MonoGame/pull/5881)
- Improved performance of SpriteFont.MeasureString() & SpriteBatch.DrawString(). [#5874](https://github.com/MonoGame/MonoGame/pull/5874)
- Sort content when saving MGCB files. [#5930](https://github.com/MonoGame/MonoGame/pull/5930)
- Fix a crash when building content in xbuild. [#5897](https://github.com/MonoGame/MonoGame/pull/5897)
- Fixed back button problems in UWP. [#5810](https://github.com/MonoGame/MonoGame/pull/5810)
- Removed Windows 8.1 and Windows Phone 8.1 support. [#5809](https://github.com/MonoGame/MonoGame/pull/5809)
- Upgrade to SharpDX 4.0.1. [#5949](https://github.com/MonoGame/MonoGame/pull/5949)
- Update the UWP Template to use the Latest SDK. [#5931](https://github.com/MonoGame/MonoGame/pull/5931)
- Fixed the Scissor rect calculation on DesktopGL and OpenGL platforms. [#5977](https://github.com/MonoGame/MonoGame/pull/5977)
- Calculate the Client Bounds a bit later. [#5975](https://github.com/MonoGame/MonoGame/pull/5975)
- Rework Android OpenGL Framebuffer Support. [#5993](https://github.com/MonoGame/MonoGame/pull/5993)
- Implemented GraphicsDevice.GetBackBufferData. [#5114](https://github.com/MonoGame/MonoGame/pull/5114)
- Optimizations to Length and Normalize in Vector3 and Vector4. [#6004](https://github.com/MonoGame/MonoGame/pull/6004)
- Added MGCB man page for Linux. [#5987](https://github.com/MonoGame/MonoGame/pull/5987)
- Included mgcb autocomplete for bash. [#5985](https://github.com/MonoGame/MonoGame/pull/5985)
- Fixed GamePad.SetVibration crash. [#5965](https://github.com/MonoGame/MonoGame/pull/5965)
- Fallback SurfaceFormat for RenderTargets. [#6170](https://github.com/MonoGame/MonoGame/pull/6170)
- Added O(1) EffectParameter lookups by name. [#6146](https://github.com/MonoGame/MonoGame/pull/6146)
- Reduce MouseState garbage in Desktop DirectX. [#6168](https://github.com/MonoGame/MonoGame/pull/6168)
- Made SpriteFont constructor public. [#6126](https://github.com/MonoGame/MonoGame/pull/6126)
- New Template System using Nuget. [#6135](https://github.com/MonoGame/MonoGame/pull/6135)
- Use StbSharp for all Texture2D.FromStream. [#6008](https://github.com/MonoGame/MonoGame/pull/6008)
- Dynamic reference loading in Pipeline Tool. [#6202](https://github.com/MonoGame/MonoGame/pull/6202)
- Fix Pipeline tool to work regardless of Mono changes. [#6197](https://github.com/MonoGame/MonoGame/pull/6197)
- Update Template Icons and Fix Mac Info.plist. [#6209](https://github.com/MonoGame/MonoGame/pull/6209)
- Fix typo in VS2013 Shared Project Template. [#6216](https://github.com/MonoGame/MonoGame/pull/6216)
- Fill up dotnet template info. [#6226](https://github.com/MonoGame/MonoGame/pull/6226)
- Support Mac Unit Tests. [#5952](https://github.com/MonoGame/MonoGame/pull/5952)
- Updated Assimp to latest version. [#6222](https://github.com/MonoGame/MonoGame/pull/6222)
- Make sure that the window titlebar is within screen bounds on DesktopGL. [#6258](https://github.com/MonoGame/MonoGame/pull/6258)
- Fixed trigger/dpad button state and reduced garbage in iOS Gamepad. [#6271](https://github.com/MonoGame/MonoGame/pull/6271)
- Updated Windows Universal Min SDK Versions. [#6257](https://github.com/MonoGame/MonoGame/pull/6257)
- Fix property content serialization detection when using a property named `Item`. [#5996](https://github.com/MonoGame/MonoGame/pull/5996)
- Fix launcher default mimetype in Linux installer. [#6275](https://github.com/MonoGame/MonoGame/pull/6275)
- Restore NVTT. [#6239](https://github.com/MonoGame/MonoGame/pull/6239)
- Support unicode in window title under DesktopGL. [#6335](https://github.com/MonoGame/MonoGame/pull/6335)
- Add crash report window to Pipeline Tool. [#6272](https://github.com/MonoGame/MonoGame/pull/6272)
- Fix linking for copy action in Pipeline Tool. [#6398](https://github.com/MonoGame/MonoGame/pull/6398)
- Implemented KeyboardInput and MessageBox for Windows DX. [#6410](https://github.com/MonoGame/MonoGame/pull/6410)
- Fixed audio interruption bug on iOS. [#6433](https://github.com/MonoGame/MonoGame/pull/6433)
## 3.6 Release - 2/28/2017
- Fixed XML deserialization of Curve type. [#5494](https://github.com/MonoGame/MonoGame/pull/5494)
- Fix #5498 Pipeline Tool template loading on MacOS. [#5501](https://github.com/MonoGame/MonoGame/pull/5501)
- Fix typo in the exclude.addins which cause warnings when installing the Addin in XS. [#5500](https://github.com/MonoGame/MonoGame/pull/5500)
- Added support for arbitrary defines passed to the Effect compiler. [#5496](https://github.com/MonoGame/MonoGame/pull/5496)
- Fixed GraphicsDevice.Present() to check for current render target. [#5389](https://github.com/MonoGame/MonoGame/pull/5389)
- Custom texture compression for SpriteFonts. [#5299](https://github.com/MonoGame/MonoGame/pull/5299)
- Performance improvements to SpriteBatch.DrawString(). [#5226](https://github.com/MonoGame/MonoGame/pull/5226)
- Removed the OUYA platform [#5194](https://github.com/MonoGame/MonoGame/pull/5194)
- Dispose of all graphical resources in unit tests. [#5133](https://github.com/MonoGame/MonoGame/pull/5133)
- Throw NoSuitableGraphicsDeviceException if graphics device creation fails. [#5130](https://github.com/MonoGame/MonoGame/pull/5130)
- Optimized and added additional constructors to Color. [#5117](https://github.com/MonoGame/MonoGame/pull/5117)
- Added SamplerState.TextureFilterMode to correctly support comparison filtering. [#5112](https://github.com/MonoGame/MonoGame/pull/5112)
- Fixed Apply3D() on stereo SoundEffect. [#5099](https://github.com/MonoGame/MonoGame/pull/5099)
- Fixed Effect.OnApply to return void to match XNA. [#5090](https://github.com/MonoGame/MonoGame/pull/5090)
- Fix crash when DynamicSoundEffectInstance not disposed. [#5075](https://github.com/MonoGame/MonoGame/pull/5075)
- Texture2D.FromStream now correctly throws on null arguments. [#5050](https://github.com/MonoGame/MonoGame/pull/5050)
- Implemented GraphicsAdapter for DirectX platforms. [#5024](https://github.com/MonoGame/MonoGame/pull/5024)
- Fixed initialization of GameComponent when created within another GameComponent. [#5020](https://github.com/MonoGame/MonoGame/pull/5020)
- Improved SoundEffect internal platform extendability. [#5006](https://github.com/MonoGame/MonoGame/pull/5006)
- Refactored audio processing for platform extensibility. [#5001](https://github.com/MonoGame/MonoGame/pull/5001)
- Refactored texture processing for platform extensibility. [#4996](https://github.com/MonoGame/MonoGame/pull/4996)
- Refactor ShaderProfile to allow for pipeline extensibility. [#4992](https://github.com/MonoGame/MonoGame/pull/4992)
- Removed unnessasary dictionary lookup for user index buffers for DirectX platforms. [#4988](https://github.com/MonoGame/MonoGame/pull/4988)
- New SetRenderTargets() method which allows for variable target count. [#4987](https://github.com/MonoGame/MonoGame/pull/4987)
- Added support for XACT reverb and filter effects. [#4974](https://github.com/MonoGame/MonoGame/pull/4974)
- Remove array in GamePadDPad constructor. [#4970](https://github.com/MonoGame/MonoGame/pull/4970)
- Updated to the latest version of Protobuild. [#4964](https://github.com/MonoGame/MonoGame/pull/4964)
- Fixed static VBs and IBs on UWP on XB1. [#4955](https://github.com/MonoGame/MonoGame/pull/4955)
- Updated to the latest version of Protobuild. [#4950](https://github.com/MonoGame/MonoGame/pull/4950)
- Update Xamarin Studio addin for latest platform changes. [#4926](https://github.com/MonoGame/MonoGame/pull/4926)
- Replace OpenTK with custom OpenGL bindings [#4874](https://github.com/MonoGame/MonoGame/pull/4874)
- Fix Mouse updating when moving the Window. [#4924](https://github.com/MonoGame/MonoGame/pull/4924)
- Fix incorrect use of startIndex in Texture2D.GetData DX. [#4833](https://github.com/MonoGame/MonoGame/pull/4833)
- Cleanup of AssemblyInfo for framework assembly. [#4810](https://github.com/MonoGame/MonoGame/pull/4810)
- New SDL2 backend for desktop GL platforms. [#4428](https://github.com/MonoGame/MonoGame/pull/4428)
- Two MaterialProcessor properties fixed. [#4746](https://github.com/MonoGame/MonoGame/pull/4746)
- Fixed thumbstick virtual buttons to always use independent axes. [#4742](https://github.com/MonoGame/MonoGame/pull/4742)
- Fixed back buffer MSAA on DirectX platforms. [#4739](https://github.com/MonoGame/MonoGame/pull/4739)
- Added new CHANGELOG.md to project. [#4732](https://github.com/MonoGame/MonoGame/pull/4732)
- Added obsolete attribute and updated documentation. [#4731](https://github.com/MonoGame/MonoGame/pull/4731)
- Fixed layout of UWP windows in VS template to ignore window chrome. [#4727](https://github.com/MonoGame/MonoGame/pull/4727)
- Remove support for reading raw assets through ContentManager. [#4726](https://github.com/MonoGame/MonoGame/pull/4726)
- Implemented DynamicSoundEffectInstance for DirectX and OpenAL platforms. [#4715](https://github.com/MonoGame/MonoGame/pull/4715)
- Removed unused Yeti Mp3 compressor. [#4713](https://github.com/MonoGame/MonoGame/pull/4713)
- MonoGame Portable Assemblies. [#4712](https://github.com/MonoGame/MonoGame/pull/4712)
- Fixed RGBA64 packing and added unit tests. [#4683](https://github.com/MonoGame/MonoGame/pull/4683)
- Fix Gamepad crash when platform doesn't support the amount. [#4677](https://github.com/MonoGame/MonoGame/pull/4677)
- Fixed Song stopping before they are finished on Windows. [#4668](https://github.com/MonoGame/MonoGame/pull/4668)
- Removed the Linux .deb installer. [#4665](https://github.com/MonoGame/MonoGame/pull/4665)
- OpenAssetImporter is now automatically selected for all the formats it supports. [#4663](https://github.com/MonoGame/MonoGame/pull/4663)
- Fixed broken unit tests under Linux. [#4614](https://github.com/MonoGame/MonoGame/pull/4614)
- Split out Title Container into partial classes. [#4590](https://github.com/MonoGame/MonoGame/pull/4590)
- Added Rider Support to Linux installer. [#4589](https://github.com/MonoGame/MonoGame/pull/4589)
- Implement vertexStride in VertexBuffer.SetData for OpenGL. [#4568](https://github.com/MonoGame/MonoGame/pull/4568)
- Performance improvement to SpriteBatch vertex generation. [#4547](https://github.com/MonoGame/MonoGame/pull/4547)
- Optimization of indices initialization in SpriteBatcher. [#4546](https://github.com/MonoGame/MonoGame/pull/4546)
- Optimized ContentReader to decode LZ4 compressed streams directly. [#4522](https://github.com/MonoGame/MonoGame/pull/4522)
- TitleContainer partial class cleanup. [#4520](https://github.com/MonoGame/MonoGame/pull/4520)
- Remove raw asset support from ContentManager. [#4489](https://github.com/MonoGame/MonoGame/pull/4489)
- Initial implementation of RenderTargetCube for OpenGL. [#4488](https://github.com/MonoGame/MonoGame/pull/4488)
- Removed unnecessary platform differences in MGFX. [#4486](https://github.com/MonoGame/MonoGame/pull/4486)
- SoundEffect fixes and tests. [#4469](https://github.com/MonoGame/MonoGame/pull/4469)
- Cleanup FX syntax for shader compiler. [#4462](https://github.com/MonoGame/MonoGame/pull/4462)
- General Improvements to Pipeline Gtk implementation. [#4459](https://github.com/MonoGame/MonoGame/pull/4459)
- ShaderProfile Refactor. [#4438](https://github.com/MonoGame/MonoGame/pull/4438)
- GraphicsDeviceManager partial class refactor. [#4425](https://github.com/MonoGame/MonoGame/pull/4425)
- Remove legacy Storage classes. [#4320](https://github.com/MonoGame/MonoGame/pull/4320)
- Added mipmap generation for DirectX render targets. [#4189](https://github.com/MonoGame/MonoGame/pull/4189)
## 3.5.1 Release - 3/30/2016
- Fixed negative values when pressing up on left thumbstick on Mac.
- Removed exception and just return empty state when requesting an invalid GamePad index.
- Fixed texture processing for 64bpp textures.
- Fixed Texture2D.SaveAsPng on Mac.
## 3.5 Release - 3/17/2016
- Content Pipeline Integration for Xamarin Studio and MonoDevleop on Mac and Linux.
- Automatic inclusion of XNBs into your final project on Mac and Linux.
- Improved Mac and Linux installers.
- Assemblies are now installed locally on Mac and Linux just like they are on Windows.
- New cross-platform “Desktop” project where same binary and content will work on Windows, Linux and Mac desktops.
- Better Support for Xamarin.Mac and Xam.Mac.
- Apple TV support (requires to be built from source at the moment).
- Various sound system fixes.
- New GraphicsMetrics API.
- Optimizations to SpriteBatch performance and garbage generation.
- Many improvements to the Pipeline tool: added toolbar, new filtered output view, new templates, drag and drop, and more.
- New GamePad support for UWP.
- Mac and Linux now support Vorbis compressed music.
- Major refactor of texture support in content pipeline.
- Added 151 new unit tests.
- Big improvements to FBX and model content processing.
- Various fixes to XML serialization.
- MediaLibrary implementation for Windows platforms.
- Removed PlayStation Mobile platform.
- Added content pipeline extension template project.
- Support for binding multiple vertex buffers in a draw call.
- Fixed deadzone issues in GamePad support.
- OcclusionQuery support for DX platforms.
- Fixed incorrect z depth in SpriteBatch.
- Lots of OpenTK backend fixes.
- Much improved font processing.
- Added new VertexPosition vertex format.
- Better VS project template installation under Windows.
## 3.4 Release - 4/29/2015
- Removed old XNA content pipeline extensions.
- Added all missing PackedVector types.
- Replacement of old SDL joystick path with OpenTK.
- Added SamplerState.ComparisonFunction feature to DX and OGL platforms.
- Fixed bug where content importers would not be autodetected on upper case file extensions.
- Fixed compatibility with XNA sound effect XNBs.
- Lots of reference doc improvements.
- Added SamplerState.BorderColor feature to DX and OGL platforms.
- Lots of improvements to the Mac, Linux and Windows versions of the Pipeline GUI tool.
- Fixes for bad key mapping on Linux.
- Support for texture arrays on DX platforms.
- Fixed broken ModelMesh.Tag
- VS templates will now only install if VS is detected on your system.
- Added Color.MonoGameOrange.
- Fixed Xact SoundBack loading bug on Android.
- Added support for a bunch of missing render states to MGFX.
- Added support for sRGB texture formats to DX and OGL platforms.
- Added RasterizerState.DepthClipEnable support for DX and OGL platforms.
- New support for the Windows 10 UAP plafform.
- Fixed bug which caused the GamePad left thumbstick to not work correctly.
- Preliminary base classed for future Joystick API.
- Performance improvement on iOS by avoiding unnessasary GL context changes.
- Fixed bug where MediaPlayer volume affected all sounds.
- New XamarinStudio/MonoDevelop Addin for Mac.
- New Mac installer packages.
## 3.3 Release - 3/16/2015
- Support for vertex texture fetch on Windows.
- New modern classes for KeyboardInput and MessageBox.
- Added more validation to draw calls and render states.
- Cleaned up usage of statics to support multiple GraphicsDevice instances.
- Support Window.Position on WindowsGL platform.
- Reduction of redundant OpenGL calls.
- Fullscreen support for Windows DX platform.
- Implemented Texture2D SaveAsPng and SaveAsJpeg for Android.
- Improved GamePad deadzone calculations.
- We now use FFmpeg for audio content building.
- BoundingSphere fixes and optimizations.
- Many improvements to Linux platform.
- Various fixes to FontTextureProcessor.
- New Windows Universal App template for Windows Store and Windows Phone support.
- Many fixes to reduce garbage generation during runtime.
- Adding support for TextureFormatOptions to FontDescriptionProcessor.
- XNA compatibility improvements to FontDescriptionProcessor.
- Resuscitated the unit test framework with 100s of additional unit tests.
- BoundingFrustum fixes and optimizations.
- Added VS2013 project templates.
- Moved to new MonoGame logo.
- Added MSAA render target support for OpenGL platforms.
- Added optional content compression support to content pipeline and runtime.
- TextureCube content reader and GetData fixes.
- New OpenAL software implementation for Android.
- Xact compatibility improvements.
- Lots of Android fixes and improvements.
- Added MediaLibrary implementation for Android, iOS, Windows Phone, and Windows Store.
- Added ReflectiveWriter implementation to content pipeline.
- Fixes to Texture2D.GetData on DirectX platforms.
- SpriteFont rendering performance optimizations.
- Huge refactor of ModelProcessor to be more compatible with XNA.
- Moved NET and GamerServices into its own MonoGame.Framework.Net assembly.
- Runtime support for ETC1 textures for Androud.
- Improved compatibility for FBXImporter and XImporter.
- Multiple SpritBatch compatibility fixes.
- We now use FreeImage in TextureImporter to support many more input formats.
- MGFX parsing and render state improvements.
- New Pipeline GUI tool for managing content projects for Windows, Mac, and Linux desktops.
- New implementation of content pipeline IntermediateSerializer.
- All tools and content pipeline built for 64-bit.
- New documentation system.
- Implement web platform (JSIL) stubs.
- Lots of fixes to PSM.
- Added Protobuild support for project generation.
- Major refactor of internals to better separate platform specific code.
- Added MGCB command line tool to Windows installer.
## 3.2 Release - 4/7/2014
- Implemented missing PackedVector types.
- VS2013 support for MonoGame templates.
- Big improvement to XInput performance on Windows/Windows8.
- Added GameWindow.TextInput event enhancement.
- Added Xamarin.Mac compatability.
- Support for WPF interop under DirectX.
- Enhancement to support multiple GameWindows on Windows under DirectX.
- Various SpriteFont compatibility improvements.
- OpenAL performance/memory/error handling improvements.
- Reduction of Effect runtime memory usage.
- Support for DXT/S3TC textures on Android.
- Touch support on Windows desktop games.
- Added new RenderTarget3D enhancement.
- OUYA gamepad improvements.
- Internal improvements to reduce garbage generation.
- Various windowing fixes for OpenTK on Linux, Mac, and Windows.
- Automatic support for content reloading on resume for Android.
- Support for TextureCube, Texture3D, and RenderTargetCube on DirectX.
- Added TitleContainer.SupportRetina enhancement for loading @2x content.
- Lots of Android/Kindle compatibility fixes.
- Added enhancement GameWindow.IsBorderless.
- OpenGL now supports multiple render targets.
- Game.IsRunningSlowly working accurately to XNA.
- Game tick resolution improvements.
- XACT compatibility improvements.
- Various fixes and improvements to math types.
- DrawUserIndexedPrimitives now works with 32bit indicies.
- GamerServices fixes under iOS.
- Various MonoGame FX improvements and fixes.
- Render target fixes for Windows Phone.
- MediaPlayer/MediaQueue/Song fixes on Windows Phone.
- XNA accuracy fixes to TitleContainer.
- Fixes to SpriteBatch performance and compatibility with XNA.
- Threading fixes around SoundEffectInstance.
- Support for Song.Duration.
- Fixed disposal of OpenGL shader program cache.
- Improved support of PoT textures in OpenGL.
- Implemented missing EffectParameter SetValue/GetValue calls.
- Touch fixes to Windows Phone.
- Fixes to orientation support in iOS.
- Lots of PSM fixes which make it usable for 2D games.
- New Windows desktop platform using DirectX/XAudio.
- Old Windows project renamed WindowsGL.
- Fixed offsetInBytes parameter in IndexBuffer/VertexBuffer SetData.
- Fixed subpixel offset when viewport is changed in OpenGL.
- Tons of content pipeline improvements making it close to complete.
## 3.0.1 Release - 3/3/2013
- Fix template error.
- Fix offsetInBytes parameter in IndexBuffer/VertexBuffer SetData.
- Fixes the scale applied on the origin in SpriteBatch.
- Fixed render targets on WP8.
- Removed minVertexIndex Exception.
- Fixed some threading issues on iOS.
- Use generic link for opening store on iOS.
- Fix Matrix::Transpose.
- Fixed vertexOffset in DrawUserIndexedPrimitives in GL.
- Keys.RightControl/RightShift Support for WinRT.
- Dispose in ShaderProgramCache.
- IsRunningSlowly Fix.
## 3.0 Release - 1/21/2013
- 3D (many thanks to Infinite Flight Studios for the code and Sickhead Games in taking the time to merge the code in).
- New platforms: Windows 8, Windows Phone 8, OUYA, PlayStation Mobile (including Vita).
- Custom Effects.
- PVRTC support for iOS.
- iOS supports compressed Songs.
- Skinned Meshs.
- VS2012 templates.
- New Windows Installer.
- New MonoDevelop Package/AddIn.
- A LOT of bug fixes.
- Closer XNA 4 compatibility.
## 2.5.1 Release - 6/18/2012
- Updated android to use enumerations rather than hardocded ids as part of the Mono for Android 4.2 update.
- Changed the Android video player to make use of the ViewView.
- Corrected namespaces for SongReader and SoundEffectReader.
- Updated the Keyboard mapping for android.
- Added RectangleArrayReader.
- Removed links to the third party GamePadBridge.
- Added some missing mouseState operators.
- Replaced all calls to DateTime.Now with DateTime.UtcNow.
- Fixed SpriteFont rendering (again).
- Added code to correclty dispose of Textures on all platforms.
- Added some fixes for the sound on iOS.
- Adding missing MediaQueue class.
- Fixed Rectangle Intersect code.
- Changed the way UserPrimitives work on windows.
- Made sure the @2x file support on iOS works.
- Updated project templates.
- Added project templates for MacOS.
- Fixed MonoDevelop.MonoGame AddIn so it works on Linux.
## 2.5 Release - 3/29/2012
### Fixes and Features
- Minor fixes to the Networking stack to make it more reliable when looking for games.
- SpriteBatch Fixes including making sure the matrix parameter is applied in both gles 1.1 and gles 2.0.
- Updated IDrawable and IUpdatable interfaces to match XNA 4.0.
- Fixed the Tick method.
- Updated VideoPlayer constructor contract to match XNA 4.0.
- Added Code to Lookup the Host Application Guid for Networking, the guid id is now pulled from the AssemblyInfo.cs if one is present.
- Uses OpenAL on all platforms except Android.
- Added Dxt5 decompression support.
- Improves SpriteFont to conform more closely to XNA 4.0.
- Moved DynamicVertexBuffer and DynamicIndexBuffer into its own files.
### iOS
- Fixed Console.WriteLine problem.
- Fixed loading of @2x Retina files.
- Fixed Landscape Rendering.
- Fixed Orientations changes correctly animate.
- Fixed Guide.BeginShowKeyboardInput.
- Fixed StorageDevice AOT compile problem.
- Fixed SpriteBatch to respect matrices when drawn.
- Fixed DoubleTap, improves touches in serial Game instances.
- Fixed App startup in non-Portrait orientations.
- Fixed UnauthorizedAccessException using TitleContainer.
- Fixed a runtime JIT error that was occuring with List<AddJournalEntry<T>().
- Guide.ShowKeyboard is not working.
- App Backgrounding has regressed. A patch is already being tested in the develop branch and the fix will be rolled out as part of the v2.5.1.
### Android
- Project Templates for MonoDevelop.
- Fixed a few issues with Gestures.
- Fixed the name of the assembly to be MonoGame.Framework.Android.
- Fixed a Memory Leak in Texture Loading.
- Force linear filter and clamp wrap on npot textures in ES2.0 on Android.
- Added SetData and GetData support for Texture2D.
- Guide.SignIn picks up the first email account on the phone.
- CatapultWars does not render correctly under gles 1.1.
### MacOS X
- SoundEffectInstance.Stop now works correctly.
### Linux
- Project Templates for Visual Studio and MonoDevelop.
- Fixed a bug when loading of Wav files.
### Windows
- Project Templates for Visual Studio and MonoDevelop.
- Fixed a bug when loading of Wav files.
- Added Game.IsMouseVisible implementation for Windows.
- Guide.SignIn picks up the logged in user.
- Added a new Installer to install the MonoDevelop and / or Visual Studio Templates and binaries.
## 2.1 Release - 10/28/2011
### Features
- Content Manager rewritten to use partial classes and implementation of cached assets that are loaded. Greatly improves memory footprint.
- Experimental support for GamePads and Joysticks. Enhancements will be coming to integrate better for developers.
- ContentReader improvements across the board.
- Improved support for XACT audio.
- StarterKits VectorRumble.
### iOS
- Gesture support has been improved.
- Better support for portrait to landscape rotations.
- Fixed a rendering bug related to upsidedown portrait mode.
- Better WaveBank support.
- The Guide functionality is only available in iOS, for this release.
### Android
- Updated to support Mono for Android 4.0.
- Improvements to the Orientation Support.
- Changed Sound system to use SoundPool.
- Added Tap and DoubleTap Gesture Support.
### MacOS X
- A lot of enhancements and fixes for Full Screen and Windowed control.
- Cursor support fixed for IsMouseVisible.
- Implementation of IsActive property and the events Activated and Deactivated.
- First steps of DrawPrimitives, DrawUserPrimitives, DrawIndexedPrimitives.
- Better WaveBank support.
- Support for ApplyChanges() and setting the backbuffer and viewport sizes correctly.
### Linux
- All new implementation which share quite a bit of code between MacOS X and Windows.
- Added shader support via the Effects class.
### Windows
- All new implementation which shares quite a bit of code between MacOS and Linux.
## 2.0 Release - 10/28/2011
- Project renamed MonoGame.
- Project moved to GitHub.
- Support for Linux, Mac, Linux, and OpenGL on Windows.
## 0.7 Release - 12/2/2009
- First stable release.
- Originally named XnaTouch.
- iPhone support only.
- 2D rendering support.
- Audio support.
- Networking support.
- Partial multitouch support.
- Partial accelerometer support.

View File

@@ -0,0 +1,228 @@
> #### NOTE: This code style standard for MonoGame is a work in progress and much of the code does not currently conform to these rules. This is something that will be addressed by the core team.
# Introduction
As the MonoGame project gains more traction and becomes more widely used, we aim to provide a more professional and consistent look to the large amount of source now in the project. It was a broadly supported decision by the core development team to follow the Microsoft coding guidelines (the default provided in Visual Studio's C# editor). These coding guidelines listed below are based on a [MSDN blog post](http://blogs.msdn.com/b/brada/archive/2005/01/26/361363.aspx) from 2005 by Brad Abrams describing the internal coding guidelines at Microsoft, with some changes to suit our project.
# Coding Guidelines
## Tabs & Indenting
Tab characters (\0x09) should not be used in code. All indentation should be done with 4 space characters.
## Bracing
Open braces should always be at the beginning of the line after the statement that begins the block. Contents of the brace should be indented by 4 spaces. Single statements do not have braces. For example:
```
if (someExpression)
{
DoSomething();
DoAnotherThing();
}
else
DoSomethingElse();
```
`case` statements should be indented from the switch statement like this:
```
switch (someExpression)
{
case 0:
DoSomething();
break;
case 1:
DoSomethingElse();
break;
case 2:
{
int n = 1;
DoAnotherThing(n);
}
break;
}
```
Braces are not used for single statement blocks immediately following a `for`, `foreach`, `if`, `do`, etc. The single statement block should always be on the following line and indented by four spaces. This increases code readability and maintainability.
```
for (int i = 0; i < 100; ++i)
DoSomething(i);
```
## Single line property statements
Single line property statements can have braces that begin and end on the same line. This should only be used for simple property statements. Add a single space before and after the braces.
```
public class Foo
{
int bar;
public int Bar
{
get { return bar; }
set { bar = value; }
}
}
```
## Commenting
Comments should be used to describe intention, algorithmic overview, and/or logical flow. It would be ideal if, from reading the comments alone, someone other than the author could understand a function's intended behavior and general operation. While there are no minimum comment requirements (and certainly some very small routines need no commenting at all), it is best that most routines have comments reflecting the programmer's intent and approach.
Comments must provide added value or explanation to the code. Simply describing the code is not helpful or useful.
```
// Wrong
// Set count to 1
count = 1;
// Right
// Set the initial reference count so it isn't cleaned up next frame
count = 1;
```
### Copyright/License notice
Each file should start with a copyright notice. This is a short statement declaring the project name and copyright notice, and directing the reader to the license document elsewhere in the project. To avoid errors in doc comment builds, avoid using triple-slash doc comments.
```
// 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.
```
### Documentation Comments
All methods should use XML doc comments. For internal dev comments, the `<devdoc>` tag should be used.
```
public class Foo
{
/// <summary>Public stuff about the method</summary>
/// <param name="bar">What a neat parameter!</param>
/// <devdoc>Cool internal stuff!</devdoc>
public void MyMethod(int bar)
{
...
}
}
```
### Comment Style
The // (two slashes) style of comment tags should be used in most situations. Wherever possible, place comments above the code instead of beside it. Here are some examples:
```
// This is required for WebClient to work through the proxy
GlobalProxySelection.Select = new WebProxy("http://itgproxy");
// Create object to access Internet resources
WebClient myClient = new WebClient();
```
## Spacing
Spaces improve readability by decreasing code density. Here are some guidelines for the use of space characters within code:
Do use a single space after a comma between function arguments.
```
Console.In.Read(myChar, 0, 1); // Right
Console.In.Read(myChar,0,1); // Wrong
```
Do not use a space after the parenthesis and function arguments.
```
CreateFoo(myChar, 0, 1) // Right
CreateFoo( myChar, 0, 1 ) // Wrong
```
Do not use spaces between a function name and parentheses.
```
CreateFoo() // Right
CreateFoo () // Wrong
```
Do not use spaces inside brackets.
```
x = dataArray[index]; // Right
x = dataArray[ index ]; // Wrong
```
Do use a single space before flow control statements.
```
while (x == y) // Right
while(x==y) // Wrong
```
Do use a single space before and after binary operators.
```
if (x == y) // Right
if (x==y) // Wrong
```
Do not use a space between a unary operator and the operand.
```
++i; // Right
++ i; // Wrong
```
Do not use a space before a semi-colon. Do use a space after a semi-colon if there is more on the same line.
```
for (int i = 0; i < 100; ++i) // Right
for (int i=0 ; i<100 ; ++i) // Wrong
```
## Naming
Follow all .NET Framework Design Guidelines for both internal and external members. Highlights of these include:
* Do not use Hungarian notation
* Do use an underscore prefix for member variables, e.g. "_foo"
* Do use camelCasing for member variables (first word all lowercase, subsequent words initial uppercase)
* Do use camelCasing for parameters
* Do use camelCasing for local variables
* Do use PascalCasing for function, property, event, and class names (all words initial uppercase)
* Do prefix interfaces names with "I"
* Do not prefix enums, classes, or delegates with any letter
The reasons to extend the public rules (no Hungarian, underscore prefix for member variables, etc.) is to produce a consistent source code appearance. In addition, the goal is to have clean, readable source. Code legibility should be a primary goal.
## File Organization
* Source files should contain only one public type, although multiple internal types are permitted if required
* Source files should be given the name of the public type in the file
* Directory names should follow the namespace for the class after `Framework`. For example, one would expect to find the public class `Microsoft.Xna.Framework.Graphics.GraphicsDevice` in **MonoGame.Framework\Graphics\GraphicsDevice.cs**
* Class members should be grouped logically, and encapsulated into regions (Fields, Constructors, Properties, Events, Methods, Private interface implementations, Nested types)
* Using statements should be before the namespace declaration.
```
using System;
namespace MyNamespace
{
public class MyClass : IFoo
{
#region Fields
int foo;
#endregion
#region Properties
public int Foo { get { ... } set { ... } }
#endregion
#region Constructors
public MyClass()
{
...
}
#endregion
#region Events
public event EventHandler FooChanged { add { ... } remove { ... } }
#endregion
#region Methods
void DoSomething()
{
...
}
void FindSomething()
{
...
}
#endregion
#region Private interface implementations
void IFoo.DoSomething()
{
DoSomething();
}
#endregion
#region Nested types
class NestedType
{
...
}
#endregion
}
}
```
# Useful Links
[C# Coding Conventions (MSDN)](http://msdn.microsoft.com/en-us/library/ff926074.aspx)

View File

@@ -0,0 +1,79 @@
# Contributing to MonoGame
We're happy that you have chosen to contribute to the MonoGame project.
You are joining a group of hundreds of volunteers that have helped build MonoGame since 2009. To organize these efforts, the MonoGame Team has written this simple guide to help you.
Please read this document completely before contributing.
## How To Contribute
MonoGame has a `master` branch for stable releases and a `develop` branch for daily development. New features and fixes are always submitted to the `develop` branch.
If you are looking for ways to help, you should start by looking at the [Help Wanted tasks](https://github.com/mono/MonoGame/issues?q=is%3Aissue+is%3Aopen+label%3A%22Help+Wanted%22). Please let us know if you plan to work on an issue so that others are not duplicating work.
The MonoGame project follows standard [GitHub flow](https://guides.github.com/introduction/flow/index.html). You should learn and be familiar with how to [use Git](https://help.github.com/articles/set-up-git/), how to [create a fork of MonoGame](https://help.github.com/articles/fork-a-repo/), and how to [submit a Pull Request](https://help.github.com/articles/using-pull-requests/).
After you submit a PR, the [MonoGame build server](http://teamcity.monogame.net/?guest=1) will build your changes and verify all tests pass. Project maintainers and contributors will review your changes and provide constructive feedback to improve your submission.
Once we are satisfied that your changes are good for MonoGame, we will merge it.
## Quick Guidelines
Here are a few simple rules and suggestions to remember when contributing to MonoGame.
* :bangbang: **NEVER** commit code that you didn't personally write.
* :bangbang: **NEVER** use decompiler tools to steal code and submit them as your own work.
* :bangbang: **NEVER** decompile XNA assemblies and steal Microsoft's copyrighted code.
* **PLEASE** try keep your PRs focused on a single topic and of a reasonable size or we may ask you to break it up.
* **PLEASE** be sure to write simple and descriptive commit messages.
* **DO NOT** surprise us with new APIs or big new features. Open an issue to discuss your ideas first.
* **DO NOT** reorder type members as it makes it difficult to compare code changes in a PR.
* **DO** try to follow our [coding style](CODESTYLE.md) for new code.
* **DO** give priority to the existing style of the file you're changing.
* **DO** try to add to our [unit tests](Test) when adding new features or fixing bugs.
* **DO NOT** send PRs for code style changes or make code changes just for the sake of style.
* **PLEASE** keep a civil and respectful tone when discussing and reviewing contributions.
* **PLEASE** tell others about MonoGame and your contributions via social media.
## Decompiler Tools
We prohibit the use of tools like dotPeek, ILSpy, JustDecompiler, or .NET Reflector which convert compiled assemblies into readable code.
There has been confusion on this point in the past, so we want to make this clear. It is **NEVER ACCEPTABLE** to decompile copyrighted assemblies and submit that code to the MonoGame project.
* It **DOES NOT** matter how much you change the code.
* It **DOES NOT** matter what country you live in or what your local laws say.
* It **DOES NOT** matter that XNA is discontinued.
* It **DOES NOT** matter how small the bit of code you have stolen is.
* It **DOES NOT** matter what your opinion is of stealing code.
If you did not write the code, you do not have ownership of the code and you shouldn't submit it to MonoGame.
If we find a contribution to be in violation of copyright, it will be immediately removed. We will bar that contributor from the MonoGame project.
## Licensing
The MonoGame project is under the [Microsoft Public License](https://opensource.org/licenses/MS-PL) except for a few portions of the code. See the [LICENSE.txt](LICENSE.txt) file for more details. Third-party libraries used by MonoGame are under their own licenses. Please refer to those libraries for details on the license they use.
We accept contributions in "good faith" that it isn't bound to a conflicting license. By submitting a PR you agree to distribute your work under the MonoGame license and copyright.
To this end, when submitting new files, include the following in the header if appropriate:
```csharp
// 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.
```
## Need More Help?
If you need help, please ask questions on our [community forums](http://community.monogame.net/) or come [chat on Gitter](https://gitter.im/mono/MonoGame).
Thanks for reading this guide and helping make MonoGame great!
:heart: The MonoGame Team

View File

@@ -0,0 +1,25 @@
<!--
# Please make sure that the issue is present in the
# develop branch of MonoGame before reporting
#
# You can download the development build installer from:
# http://www.monogame.net/downloads/
-->
<!-- Write your issue below -->
<!-- System stats -->
#### What version of MonoGame does the bug occur on:
- MonoGame 3.7
#### What operating system are you using:
- Windows
#### What MonoGame platform are you using:
<!-- e.g. DesktopGL, WindowsDX, WindowsUWP, Android -->
- DesktopGL

View File

@@ -0,0 +1,86 @@
Microsoft Public License (Ms-PL)
MonoGame - Copyright © 2009-2018 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.
-------------------------------------------------------------------------------
The MIT License (MIT)
Portions Copyright © The Mono.Xna Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,17 @@
//TODO: maybe make this compile even if SDL isn't available
namespace Microsoft.Xna.Framework
{
public static class Clipboard
{
public static string GetText()
{
return Sdl.GetClipboardText();
}
public static void SetText(string text)
{
Sdl.SetClipboardText(text);
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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)
{
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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());
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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>();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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 ();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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 ();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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");
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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 ());
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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 ();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;}
}
}

View File

@@ -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
{
}
}

View File

@@ -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;}
}
}

View File

@@ -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; }
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,248 @@
// 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));
preparedType = preparedType.Replace(", MonoGame.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();
}
}
}

View File

@@ -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
{
}
}

View File

@@ -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[]);
}
}
}

View File

@@ -0,0 +1,338 @@
// 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.ComponentModel;
using System.Runtime.Serialization;
namespace Microsoft.Xna.Framework
{
/// <summary>
/// Contains a collection of <see cref="CurveKey"/> points in 2D space and provides methods for evaluating features of the curve they define.
/// </summary>
// TODO : [TypeConverter(typeof(ExpandableObjectConverter))]
[DataContract]
public class Curve
{
#region Private Fields
private CurveLoopType _preLoop;
private CurveLoopType _postLoop;
private CurveKeyCollection _keys;
#endregion
#region Public Properties
/// <summary>
/// Returns <c>true</c> if this curve is constant (has zero or one points); <c>false</c> otherwise.
/// </summary>
[DataMember]
public bool IsConstant
{
get { return this._keys.Count <= 1; }
}
/// <summary>
/// Defines how to handle weighting values that are less than the first control point in the curve.
/// </summary>
[DataMember]
public CurveLoopType PreLoop
{
get { return this._preLoop; }
set { this._preLoop = value; }
}
/// <summary>
/// Defines how to handle weighting values that are greater than the last control point in the curve.
/// </summary>
[DataMember]
public CurveLoopType PostLoop
{
get { return this._postLoop; }
set { this._postLoop = value; }
}
/// <summary>
/// The collection of curve keys.
/// </summary>
[DataMember]
public CurveKeyCollection Keys
{
get { return this._keys; }
}
#endregion
#region Public Constructors
/// <summary>
/// Constructs a curve.
/// </summary>
public Curve()
{
this._keys = new CurveKeyCollection();
}
#endregion
#region Public Methods
/// <summary>
/// Creates a copy of this curve.
/// </summary>
/// <returns>A copy of this curve.</returns>
public Curve Clone()
{
Curve curve = new Curve();
curve._keys = this._keys.Clone();
curve._preLoop = this._preLoop;
curve._postLoop = this._postLoop;
return curve;
}
/// <summary>
/// Evaluate the value at a position of this <see cref="Curve"/>.
/// </summary>
/// <param name="position">The position on this <see cref="Curve"/>.</param>
/// <returns>Value at the position on this <see cref="Curve"/>.</returns>
public float Evaluate(float position)
{
if (_keys.Count == 0)
{
return 0f;
}
if (_keys.Count == 1)
{
return _keys[0].Value;
}
CurveKey first = _keys[0];
CurveKey last = _keys[_keys.Count - 1];
if (position < first.Position)
{
switch (this.PreLoop)
{
case CurveLoopType.Constant:
//constant
return first.Value;
case CurveLoopType.Linear:
// linear y = a*x +b with a tangeant of last point
return first.Value - first.TangentIn * (first.Position - position);
case CurveLoopType.Cycle:
//start -> end / start -> end
int cycle = GetNumberOfCycle(position);
float virtualPos = position - (cycle * (last.Position - first.Position));
return GetCurvePosition(virtualPos);
case CurveLoopType.CycleOffset:
//make the curve continue (with no step) so must up the curve each cycle of delta(value)
cycle = GetNumberOfCycle(position);
virtualPos = position - (cycle * (last.Position - first.Position));
return (GetCurvePosition(virtualPos) + cycle * (last.Value - first.Value));
case CurveLoopType.Oscillate:
//go back on curve from end and target start
// start-> end / end -> start
cycle = GetNumberOfCycle(position);
if (0 == cycle % 2f)//if pair
virtualPos = position - (cycle * (last.Position - first.Position));
else
virtualPos = last.Position - position + first.Position + (cycle * (last.Position - first.Position));
return GetCurvePosition(virtualPos);
}
}
else if (position > last.Position)
{
int cycle;
switch (this.PostLoop)
{
case CurveLoopType.Constant:
//constant
return last.Value;
case CurveLoopType.Linear:
// linear y = a*x +b with a tangeant of last point
return last.Value + first.TangentOut * (position - last.Position);
case CurveLoopType.Cycle:
//start -> end / start -> end
cycle = GetNumberOfCycle(position);
float virtualPos = position - (cycle * (last.Position - first.Position));
return GetCurvePosition(virtualPos);
case CurveLoopType.CycleOffset:
//make the curve continue (with no step) so must up the curve each cycle of delta(value)
cycle = GetNumberOfCycle(position);
virtualPos = position - (cycle * (last.Position - first.Position));
return (GetCurvePosition(virtualPos) + cycle * (last.Value - first.Value));
case CurveLoopType.Oscillate:
//go back on curve from end and target start
// start-> end / end -> start
cycle = GetNumberOfCycle(position);
virtualPos = position - (cycle * (last.Position - first.Position));
if (0 == cycle % 2f)//if pair
virtualPos = position - (cycle * (last.Position - first.Position));
else
virtualPos = last.Position - position + first.Position + (cycle * (last.Position - first.Position));
return GetCurvePosition(virtualPos);
}
}
//in curve
return GetCurvePosition(position);
}
/// <summary>
/// Computes tangents for all keys in the collection.
/// </summary>
/// <param name="tangentType">The tangent type for both in and out.</param>
public void ComputeTangents (CurveTangent tangentType)
{
ComputeTangents(tangentType, tangentType);
}
/// <summary>
/// Computes tangents for all keys in the collection.
/// </summary>
/// <param name="tangentInType">The tangent in-type. <see cref="CurveKey.TangentIn"/> for more details.</param>
/// <param name="tangentOutType">The tangent out-type. <see cref="CurveKey.TangentOut"/> for more details.</param>
public void ComputeTangents(CurveTangent tangentInType, CurveTangent tangentOutType)
{
for (var i = 0; i < Keys.Count; ++i)
{
ComputeTangent(i, tangentInType, tangentOutType);
}
}
/// <summary>
/// Computes tangent for the specific key in the collection.
/// </summary>
/// <param name="keyIndex">The index of a key in the collection.</param>
/// <param name="tangentType">The tangent type for both in and out.</param>
public void ComputeTangent(int keyIndex, CurveTangent tangentType)
{
ComputeTangent(keyIndex, tangentType, tangentType);
}
/// <summary>
/// Computes tangent for the specific key in the collection.
/// </summary>
/// <param name="keyIndex">The index of key in the collection.</param>
/// <param name="tangentInType">The tangent in-type. <see cref="CurveKey.TangentIn"/> for more details.</param>
/// <param name="tangentOutType">The tangent out-type. <see cref="CurveKey.TangentOut"/> for more details.</param>
public void ComputeTangent(int keyIndex, CurveTangent tangentInType, CurveTangent tangentOutType)
{
// See http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.curvetangent.aspx
var key = _keys[keyIndex];
float p0, p, p1;
p0 = p = p1 = key.Position;
float v0, v, v1;
v0 = v = v1 = key.Value;
if ( keyIndex > 0 )
{
p0 = _keys[keyIndex - 1].Position;
v0 = _keys[keyIndex - 1].Value;
}
if (keyIndex < _keys.Count-1)
{
p1 = _keys[keyIndex + 1].Position;
v1 = _keys[keyIndex + 1].Value;
}
switch (tangentInType)
{
case CurveTangent.Flat:
key.TangentIn = 0;
break;
case CurveTangent.Linear:
key.TangentIn = v - v0;
break;
case CurveTangent.Smooth:
var pn = p1 - p0;
if (Math.Abs(pn) < float.Epsilon)
key.TangentIn = 0;
else
key.TangentIn = (v1 - v0) * ((p - p0) / pn);
break;
}
switch (tangentOutType)
{
case CurveTangent.Flat:
key.TangentOut = 0;
break;
case CurveTangent.Linear:
key.TangentOut = v1 - v;
break;
case CurveTangent.Smooth:
var pn = p1 - p0;
if (Math.Abs(pn) < float.Epsilon)
key.TangentOut = 0;
else
key.TangentOut = (v1 - v0) * ((p1 - p) / pn);
break;
}
}
#endregion
#region Private Methods
private int GetNumberOfCycle(float position)
{
float cycle = (position - _keys[0].Position) / (_keys[_keys.Count - 1].Position - _keys[0].Position);
if (cycle < 0f)
cycle--;
return (int)cycle;
}
private float GetCurvePosition(float position)
{
//only for position in curve
CurveKey prev = this._keys[0];
CurveKey next;
for (int i = 1; i < this._keys.Count; ++i)
{
next = this.Keys[i];
if (next.Position >= position)
{
if (prev.Continuity == CurveContinuity.Step)
{
if (position >= 1f)
{
return next.Value;
}
return prev.Value;
}
float t = (position - prev.Position) / (next.Position - prev.Position);//to have t in [0,1]
float ts = t * t;
float tss = ts * t;
//After a lot of search on internet I have found all about spline function
// and bezier (phi'sss ancien) but finaly use hermite curve
//http://en.wikipedia.org/wiki/Cubic_Hermite_spline
//P(t) = (2*t^3 - 3t^2 + 1)*P0 + (t^3 - 2t^2 + t)m0 + (-2t^3 + 3t^2)P1 + (t^3-t^2)m1
//with P0.value = prev.value , m0 = prev.tangentOut, P1= next.value, m1 = next.TangentIn
return (2 * tss - 3 * ts + 1f) * prev.Value + (tss - 2 * ts + t) * prev.TangentOut + (3 * ts - 2 * tss) * next.Value + (tss - ts) * next.TangentIn;
}
prev = next;
}
return 0f;
}
#endregion
}
}

View File

@@ -0,0 +1,21 @@
// 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.
namespace Microsoft.Xna.Framework
{
/// <summary>
/// Defines the continuity of keys on a <see cref="Curve"/>.
/// </summary>
public enum CurveContinuity
{
/// <summary>
/// Interpolation can be used between this key and the next.
/// </summary>
Smooth,
/// <summary>
/// Interpolation cannot be used. A position between the two points returns this point.
/// </summary>
Step
}
}

View File

@@ -0,0 +1,201 @@
// 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.ComponentModel;
using System.Runtime.Serialization;
namespace Microsoft.Xna.Framework
{
/// <summary>
/// Key point on the <see cref="Curve"/>.
/// </summary>
// TODO : [TypeConverter(typeof(ExpandableObjectConverter))]
[DataContract]
public class CurveKey : IEquatable<CurveKey>, IComparable<CurveKey>
{
#region Private Fields
private CurveContinuity _continuity;
private readonly float _position;
private float _tangentIn;
private float _tangentOut;
private float _value;
#endregion
#region Properties
/// <summary>
/// Gets or sets the indicator whether the segment between this point and the next point on the curve is discrete or continuous.
/// </summary>
[DataMember]
public CurveContinuity Continuity
{
get { return this._continuity; }
set { this._continuity = value; }
}
/// <summary>
/// Gets a position of the key on the curve.
/// </summary>
[DataMember]
public float Position
{
get { return this._position; }
}
/// <summary>
/// Gets or sets a tangent when approaching this point from the previous point on the curve.
/// </summary>
[DataMember]
public float TangentIn
{
get { return this._tangentIn; }
set { this._tangentIn = value; }
}
/// <summary>
/// Gets or sets a tangent when leaving this point to the next point on the curve.
/// </summary>
[DataMember]
public float TangentOut
{
get { return this._tangentOut; }
set { this._tangentOut = value; }
}
/// <summary>
/// Gets a value of this point.
/// </summary>
[DataMember]
public float Value
{
get { return this._value; }
set { this._value = value; }
}
#endregion
#region Constructors
/// <summary>
/// Creates a new instance of <see cref="CurveKey"/> class with position: 0 and value: 0.
/// </summary>
public CurveKey() : this(0, 0)
{
// This parameterless constructor is needed for correct serialization of CurveKeyCollection and CurveKey.
}
/// <summary>
/// Creates a new instance of <see cref="CurveKey"/> class.
/// </summary>
/// <param name="position">Position on the curve.</param>
/// <param name="value">Value of the control point.</param>
public CurveKey(float position, float value)
: this(position, value, 0, 0, CurveContinuity.Smooth)
{
}
/// <summary>
/// Creates a new instance of <see cref="CurveKey"/> class.
/// </summary>
/// <param name="position">Position on the curve.</param>
/// <param name="value">Value of the control point.</param>
/// <param name="tangentIn">Tangent approaching point from the previous point on the curve.</param>
/// <param name="tangentOut">Tangent leaving point toward next point on the curve.</param>
public CurveKey(float position, float value, float tangentIn, float tangentOut)
: this(position, value, tangentIn, tangentOut, CurveContinuity.Smooth)
{
}
/// <summary>
/// Creates a new instance of <see cref="CurveKey"/> class.
/// </summary>
/// <param name="position">Position on the curve.</param>
/// <param name="value">Value of the control point.</param>
/// <param name="tangentIn">Tangent approaching point from the previous point on the curve.</param>
/// <param name="tangentOut">Tangent leaving point toward next point on the curve.</param>
/// <param name="continuity">Indicates whether the curve is discrete or continuous.</param>
public CurveKey(float position, float value, float tangentIn, float tangentOut, CurveContinuity continuity)
{
this._position = position;
this._value = value;
this._tangentIn = tangentIn;
this._tangentOut = tangentOut;
this._continuity = continuity;
}
#endregion
/// <summary>
///
/// Compares whether two <see cref="CurveKey"/> instances are not equal.
/// </summary>
/// <param name="value1"><see cref="CurveKey"/> instance on the left of the not equal sign.</param>
/// <param name="value2"><see cref="CurveKey"/> instance on the right of the not equal sign.</param>
/// <returns><c>true</c> if the instances are not equal; <c>false</c> otherwise.</returns>
public static bool operator !=(CurveKey value1, CurveKey value2)
{
return !(value1 == value2);
}
/// <summary>
/// Compares whether two <see cref="CurveKey"/> instances are equal.
/// </summary>
/// <param name="value1"><see cref="CurveKey"/> instance on the left of the equal sign.</param>
/// <param name="value2"><see cref="CurveKey"/> instance on the right of the equal sign.</param>
/// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
public static bool operator ==(CurveKey value1, CurveKey value2)
{
if (object.Equals(value1, null))
return object.Equals(value2, null);
if (object.Equals(value2, null))
return object.Equals(value1, null);
return (value1._position == value2._position)
&& (value1._value == value2._value)
&& (value1._tangentIn == value2._tangentIn)
&& (value1._tangentOut == value2._tangentOut)
&& (value1._continuity == value2._continuity);
}
/// <summary>
/// Creates a copy of this key.
/// </summary>
/// <returns>A copy of this key.</returns>
public CurveKey Clone()
{
return new CurveKey(this._position, this._value, this._tangentIn, this._tangentOut, this._continuity);
}
#region Inherited Methods
public int CompareTo(CurveKey other)
{
return this._position.CompareTo(other._position);
}
public bool Equals(CurveKey other)
{
return (this == other);
}
public override bool Equals(object obj)
{
return (obj as CurveKey) != null && Equals((CurveKey)obj);
}
public override int GetHashCode()
{
return this._position.GetHashCode() ^ this._value.GetHashCode() ^ this._tangentIn.GetHashCode() ^
this._tangentOut.GetHashCode() ^ this._continuity.GetHashCode();
}
#endregion
}
}

View File

@@ -0,0 +1,200 @@
// 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;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.Serialization;
namespace Microsoft.Xna.Framework
{
/// <summary>
/// The collection of the <see cref="CurveKey"/> elements and a part of the <see cref="Curve"/> class.
/// </summary>
// TODO : [TypeConverter(typeof(ExpandableObjectConverter))]
[DataContract]
public class CurveKeyCollection : ICollection<CurveKey>
{
#region Private Fields
private readonly List<CurveKey> _keys;
#endregion
#region Properties
/// <summary>
/// Indexer.
/// </summary>
/// <param name="index">The index of key in this collection.</param>
/// <returns><see cref="CurveKey"/> at <paramref name="index"/> position.</returns>
[DataMember(Name = "Items")]
public CurveKey this[int index]
{
get { return _keys[index]; }
set
{
if (value == null)
throw new ArgumentNullException();
if (index >= _keys.Count)
throw new IndexOutOfRangeException();
if (_keys[index].Position == value.Position)
_keys[index] = value;
else
{
_keys.RemoveAt(index);
_keys.Add(value);
}
}
}
/// <summary>
/// Returns the count of keys in this collection.
/// </summary>
[DataMember]
public int Count
{
get { return _keys.Count; }
}
/// <summary>
/// Returns false because it is not a read-only collection.
/// </summary>
[DataMember]
public bool IsReadOnly
{
get { return false; }
}
#endregion
#region Constructors
/// <summary>
/// Creates a new instance of <see cref="CurveKeyCollection"/> class.
/// </summary>
public CurveKeyCollection()
{
_keys = new List<CurveKey>();
}
#endregion
IEnumerator IEnumerable.GetEnumerator()
{
return _keys.GetEnumerator();
}
/// <summary>
/// Adds a key to this collection.
/// </summary>
/// <param name="item">New key for the collection.</param>
/// <exception cref="ArgumentNullException">Throws if <paramref name="item"/> is null.</exception>
/// <remarks>The new key would be added respectively to a position of that key and the position of other keys.</remarks>
public void Add(CurveKey item)
{
if (item == null)
throw new ArgumentNullException("item");
if (_keys.Count == 0)
{
this._keys.Add(item);
return;
}
for (int i = 0; i < this._keys.Count; i++)
{
if (item.Position < this._keys[i].Position)
{
this._keys.Insert(i, item);
return;
}
}
this._keys.Add(item);
}
/// <summary>
/// Removes all keys from this collection.
/// </summary>
public void Clear()
{
_keys.Clear();
}
/// <summary>
/// Creates a copy of this collection.
/// </summary>
/// <returns>A copy of this collection.</returns>
public CurveKeyCollection Clone()
{
CurveKeyCollection ckc = new CurveKeyCollection();
foreach (CurveKey key in this._keys)
ckc.Add(key);
return ckc;
}
/// <summary>
/// Determines whether this collection contains a specific key.
/// </summary>
/// <param name="item">The key to locate in this collection.</param>
/// <returns><c>true</c> if the key is found; <c>false</c> otherwise.</returns>
public bool Contains(CurveKey item)
{
return _keys.Contains(item);
}
/// <summary>
/// Copies the keys of this collection to an array, starting at the array index provided.
/// </summary>
/// <param name="array">Destination array where elements will be copied.</param>
/// <param name="arrayIndex">The zero-based index in the array to start copying from.</param>
public void CopyTo(CurveKey[] array, int arrayIndex)
{
_keys.CopyTo(array, arrayIndex);
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>An enumerator for the <see cref="CurveKeyCollection"/>.</returns>
public IEnumerator<CurveKey> GetEnumerator()
{
return _keys.GetEnumerator();
}
/// <summary>
/// Finds element in the collection and returns its index.
/// </summary>
/// <param name="item">Element for the search.</param>
/// <returns>Index of the element; or -1 if item is not found.</returns>
public int IndexOf(CurveKey item)
{
return _keys.IndexOf(item);
}
/// <summary>
/// Removes element at the specified index.
/// </summary>
/// <param name="index">The index which element will be removed.</param>
public void RemoveAt(int index)
{
_keys.RemoveAt(index);
}
/// <summary>
/// Removes specific element.
/// </summary>
/// <param name="item">The element</param>
/// <returns><c>true</c> if item is successfully removed; <c>false</c> otherwise. This method also returns <c>false</c> if item was not found.</returns>
public bool Remove(CurveKey item)
{
return _keys.Remove(item);
}
}
}

View File

@@ -0,0 +1,35 @@
// 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.
namespace Microsoft.Xna.Framework
{
/// <summary>
/// Defines how the <see cref="Curve"/> value is determined for position before first point or after the end point on the <see cref="Curve"/>.
/// </summary>
public enum CurveLoopType
{
/// <summary>
/// The value of <see cref="Curve"/> will be evaluated as first point for positions before the beginning and end point for positions after the end.
/// </summary>
Constant,
/// <summary>
/// The positions will wrap around from the end to beginning of the <see cref="Curve"/> for determined the value.
/// </summary>
Cycle,
/// <summary>
/// The positions will wrap around from the end to beginning of the <see cref="Curve"/>.
/// The value will be offset by the difference between the values of first and end <see cref="CurveKey"/> multiplied by the wrap amount.
/// If the position is before the beginning of the <see cref="Curve"/> the difference will be subtracted from its value; otherwise the difference will be added.
/// </summary>
CycleOffset,
/// <summary>
/// The value at the end of the <see cref="Curve"/> act as an offset from the same side of the <see cref="Curve"/> toward the opposite side.
/// </summary>
Oscillate,
/// <summary>
/// The linear interpolation will be performed for determined the value.
/// </summary>
Linear
}
}

View File

@@ -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.
namespace Microsoft.Xna.Framework
{
/// <summary>
/// Defines the different tangent types to be calculated for <see cref="CurveKey"/> points in a <see cref="Curve"/>.
/// </summary>
public enum CurveTangent
{
/// <summary>
/// The tangent which always has a value equal to zero.
/// </summary>
Flat,
/// <summary>
/// The tangent which contains a difference between current tangent value and the tangent value from the previous <see cref="CurveKey"/>.
/// </summary>
Linear,
/// <summary>
/// The smoouth tangent which contains the inflection between <see cref="CurveKey.TangentIn"/> and <see cref="CurveKey.TangentOut"/> by taking into account the values of both neighbors of the <see cref="CurveKey"/>.
/// </summary>
Smooth
}
}

View File

@@ -0,0 +1,72 @@
// 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.ComponentModel;
using System.Globalization;
namespace Microsoft.Xna.Framework.Design
{
public class Vector2TypeConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (VectorConversion.CanConvertTo(context, destinationType))
return true;
if (destinationType == typeof(string))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
var vec = (Vector2)value;
if (VectorConversion.CanConvertTo(context, destinationType))
{
var vec4 = new Vector4(vec.X, vec.Y, 0.0f, 0.0f);
return VectorConversion.ConvertToFromVector4(context, culture, vec4, destinationType);
}
if (destinationType == typeof(string))
{
var terms = new string[2];
terms[0] = vec.X.ToString("R", culture);
terms[1] = vec.Y.ToString("R", culture);
return string.Join(culture.TextInfo.ListSeparator + " ", terms);
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var sourceType = value.GetType();
var vec = Vector2.Zero;
if (sourceType == typeof(string))
{
var str = (string)value;
var words = str.Split(culture.TextInfo.ListSeparator.ToCharArray());
vec.X = float.Parse(words[0], culture);
vec.Y = float.Parse(words[1], culture);
return vec;
}
return base.ConvertFrom(context, culture, value);
}
}
}

View File

@@ -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;
using System.ComponentModel;
using System.Globalization;
namespace Microsoft.Xna.Framework.Design
{
public class Vector3TypeConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (VectorConversion.CanConvertTo(context, destinationType))
return true;
if (destinationType == typeof(string))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
var vec = (Vector3)value;
if (VectorConversion.CanConvertTo(context, destinationType))
{
var vec4 = new Vector4(vec.X, vec.Y, vec.Z, 0.0f);
return VectorConversion.ConvertToFromVector4(context, culture, vec4, destinationType);
}
if (destinationType == typeof(string))
{
var terms = new string[3];
terms[0] = vec.X.ToString("R", culture);
terms[1] = vec.Y.ToString("R", culture);
terms[2] = vec.Z.ToString("R", culture);
return string.Join(culture.TextInfo.ListSeparator + " ", terms);
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var sourceType = value.GetType();
var vec = Vector3.Zero;
if (sourceType == typeof(string))
{
var str = (string)value;
var words = str.Split(culture.TextInfo.ListSeparator.ToCharArray());
vec.X = float.Parse(words[0], culture);
vec.Y = float.Parse(words[1], culture);
vec.Z = float.Parse(words[2], culture);
return vec;
}
return base.ConvertFrom(context, culture, value);
}
}
}

View File

@@ -0,0 +1,76 @@
// 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.ComponentModel;
using System.Globalization;
namespace Microsoft.Xna.Framework.Design
{
public class Vector4TypeConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (VectorConversion.CanConvertTo(context, destinationType))
return true;
if (destinationType == typeof(string))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
var vec = (Vector4)value;
if (VectorConversion.CanConvertTo(context, destinationType))
{
return VectorConversion.ConvertToFromVector4(context, culture, vec, destinationType);
}
if (destinationType == typeof(string))
{
var terms = new string[4];
terms[0] = vec.X.ToString("R", culture);
terms[1] = vec.Y.ToString("R", culture);
terms[2] = vec.Z.ToString("R", culture);
terms[3] = vec.W.ToString("R", culture);
return string.Join(culture.TextInfo.ListSeparator + " ", terms);
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var sourceType = value.GetType();
var vec = Vector4.Zero;
if (sourceType == typeof(string))
{
var str = (string)value;
var words = str.Split(culture.TextInfo.ListSeparator.ToCharArray());
vec.X = float.Parse(words[0], culture);
vec.Y = float.Parse(words[1], culture);
vec.Z = float.Parse(words[2], culture);
vec.W = float.Parse(words[3], culture);
return vec;
}
return base.ConvertFrom(context, culture, value);
}
}
}

View File

@@ -0,0 +1,46 @@
using System;
using System.ComponentModel;
using System.Globalization;
using Microsoft.Xna.Framework.Graphics.PackedVector;
namespace Microsoft.Xna.Framework.Design
{
internal static class VectorConversion
{
public static bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(float))
return true;
if (destinationType == typeof(Vector2))
return true;
if (destinationType == typeof(Vector3))
return true;
if (destinationType == typeof(Vector4))
return true;
if (destinationType.GetInterface("IPackedVector") != null)
return true;
return false;
}
public static object ConvertToFromVector4(ITypeDescriptorContext context, CultureInfo culture, Vector4 value, Type destinationType)
{
if (destinationType == typeof(float))
return value.X;
if (destinationType == typeof(Vector2))
return new Vector2(value.X, value.Y);
if (destinationType == typeof(Vector3))
return new Vector3(value.X, value.Y, value.Z);
if (destinationType == typeof(Vector4))
return new Vector4(value.X, value.Y, value.Z, value.W);
if (destinationType.GetInterface("IPackedVector") != null)
{
var packedVec = (IPackedVector)Activator.CreateInstance(destinationType);
packedVec.PackFromVector4(value);
return packedVec;
}
return null;
}
}
}

View File

@@ -0,0 +1,40 @@
// 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
{
/// <summary>
/// Defines the orientation of the display.
/// </summary>
[Flags]
public enum DisplayOrientation
{
/// <summary>
/// The default orientation.
/// </summary>
Default = 0,
/// <summary>
/// The display is rotated counterclockwise into a landscape orientation. Width is greater than height.
/// </summary>
LandscapeLeft = 1,
/// <summary>
/// The display is rotated clockwise into a landscape orientation. Width is greater than height.
/// </summary>
LandscapeRight = 2,
/// <summary>
/// The display is rotated as portrait, where height is greater than width.
/// </summary>
Portrait = 4,
/// <summary>
/// The display is rotated as inverted portrait, where height is greater than width.
/// </summary>
PortraitDown = 8,
/// <summary>
/// Unknown display orientation.
/// </summary>
Unknown = 16
}
}

View File

@@ -0,0 +1,79 @@
// 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
{
public class DrawableGameComponent : GameComponent, IDrawable
{
private bool _initialized;
private int _drawOrder;
private bool _visible = true;
public Graphics.GraphicsDevice GraphicsDevice
{
get { return this.Game.GraphicsDevice; }
}
public int DrawOrder
{
get { return _drawOrder; }
set
{
if (_drawOrder != value)
{
_drawOrder = value;
OnDrawOrderChanged(this, EventArgs.Empty);
}
}
}
public bool Visible
{
get { return _visible; }
set
{
if (_visible != value)
{
_visible = value;
OnVisibleChanged(this, EventArgs.Empty);
}
}
}
public event EventHandler<EventArgs> DrawOrderChanged;
public event EventHandler<EventArgs> VisibleChanged;
public DrawableGameComponent(Game game)
: base(game)
{
}
public override void Initialize()
{
if (!_initialized)
{
_initialized = true;
LoadContent();
}
}
protected virtual void LoadContent() { }
protected virtual void UnloadContent () { }
public virtual void Draw(GameTime gameTime) { }
protected virtual void OnVisibleChanged(object sender, EventArgs args)
{
EventHelpers.Raise(sender, VisibleChanged, args);
}
protected virtual void OnDrawOrderChanged(object sender, EventArgs args)
{
EventHelpers.Raise(sender, DrawOrderChanged, args);
}
}
}

View File

@@ -0,0 +1,45 @@
// 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
{
/// <summary>
/// Provides helper methods to make it easier
/// to safely raise events.
/// </summary>
internal static class EventHelpers
{
/// <summary>
/// Safely raises an event by storing a copy of the event's delegate
/// in the <paramref name="handler"/> parameter and checking it for
/// null before invoking it.
/// </summary>
/// <typeparam name="TEventArgs"></typeparam>
/// <param name="sender">The object raising the event.</param>
/// <param name="handler"><see cref="EventHandler{TEventArgs}"/> to be invoked</param>
/// <param name="e">The <typeparamref name="TEventArgs"/> passed to <see cref="EventHandler{TEventArgs}"/></param>
internal static void Raise<TEventArgs>(object sender, EventHandler<TEventArgs> handler, TEventArgs e)
where TEventArgs : EventArgs
{
if (handler != null)
handler(sender, e);
}
/// <summary>
/// Safely raises an event by storing a copy of the event's delegate
/// in the <paramref name="handler"/> parameter and checking it for
/// null before invoking it.
/// </summary>
/// <param name="sender">The object raising the event.</param>
/// <param name="handler"><see cref="EventHandler"/> to be invoked</param>
/// <param name="e">The <see cref="EventArgs"/> passed to <see cref="EventHandler"/></param>
internal static void Raise(object sender, EventHandler handler, EventArgs e)
{
if (handler != null)
handler(sender, e);
}
}
}

View File

@@ -0,0 +1,43 @@
// 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.Audio;
namespace Microsoft.Xna.Framework
{
/// <summary>
/// Helper class for processing internal framework events.
/// </summary>
/// <remarks>
/// If you use <see cref="Game"/> class, <see cref="Update()"/> is called automatically.
/// Otherwise you must call it as part of your game loop.
/// </remarks>
public static class FrameworkDispatcher
{
private static bool _initialized = false;
/// <summary>
/// Processes framework events.
/// </summary>
public static void Update()
{
if (!_initialized)
Initialize();
DoUpdate();
}
private static void DoUpdate()
{
}
private static void Initialize()
{
_initialized = true;
}
}
}

View File

@@ -0,0 +1,15 @@
// 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
{
internal static class FrameworkResources
{
#region Error strings
internal const string ResourceCreationWhenDeviceIsNull = "The GraphicsDevice must not be null when creating new resources.";
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,92 @@
// 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
{
public class GameComponent : IGameComponent, IUpdateable, IComparable<GameComponent>, IDisposable
{
bool _enabled = true;
int _updateOrder;
public Game Game { get; private set; }
public bool Enabled
{
get { return _enabled; }
set
{
if (_enabled != value)
{
_enabled = value;
OnEnabledChanged(this, EventArgs.Empty);
}
}
}
public int UpdateOrder
{
get { return _updateOrder; }
set
{
if (_updateOrder != value)
{
_updateOrder = value;
OnUpdateOrderChanged(this, EventArgs.Empty);
}
}
}
public event EventHandler<EventArgs> EnabledChanged;
public event EventHandler<EventArgs> UpdateOrderChanged;
public GameComponent(Game game)
{
this.Game = game;
}
~GameComponent()
{
Dispose(false);
}
public virtual void Initialize() { }
public virtual void Update(GameTime gameTime) { }
protected virtual void OnUpdateOrderChanged(object sender, EventArgs args)
{
EventHelpers.Raise(sender, UpdateOrderChanged, args);
}
protected virtual void OnEnabledChanged(object sender, EventArgs args)
{
EventHelpers.Raise(sender, EnabledChanged, args);
}
/// <summary>
/// Shuts down the component.
/// </summary>
protected virtual void Dispose(bool disposing) { }
/// <summary>
/// Shuts down the component.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#region IComparable<GameComponent> Members
// TODO: Should be removed, as it is not part of XNA 4.0
public int CompareTo(GameComponent other)
{
return other.UpdateOrder - this.UpdateOrder;
}
#endregion
}
}

View File

@@ -0,0 +1,76 @@
// 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.ObjectModel;
namespace Microsoft.Xna.Framework
{
public sealed class GameComponentCollection : Collection<IGameComponent>
{
/// <summary>
/// Event that is triggered when a <see cref="GameComponent"/> is added
/// to this <see cref="GameComponentCollection"/>.
/// </summary>
public event EventHandler<GameComponentCollectionEventArgs> ComponentAdded;
/// <summary>
/// Event that is triggered when a <see cref="GameComponent"/> is removed
/// from this <see cref="GameComponentCollection"/>.
/// </summary>
public event EventHandler<GameComponentCollectionEventArgs> ComponentRemoved;
/// <summary>
/// Removes every <see cref="GameComponent"/> from this <see cref="GameComponentCollection"/>.
/// Triggers <see cref="OnComponentRemoved"/> once for each <see cref="GameComponent"/> removed.
/// </summary>
protected override void ClearItems()
{
for (int i = 0; i < base.Count; i++)
{
this.OnComponentRemoved(new GameComponentCollectionEventArgs(base[i]));
}
base.ClearItems();
}
protected override void InsertItem(int index, IGameComponent item)
{
if (base.IndexOf(item) != -1)
{
throw new ArgumentException("Cannot Add Same Component Multiple Times");
}
base.InsertItem(index, item);
if (item != null)
{
this.OnComponentAdded(new GameComponentCollectionEventArgs(item));
}
}
private void OnComponentAdded(GameComponentCollectionEventArgs eventArgs)
{
EventHelpers.Raise(this, ComponentAdded, eventArgs);
}
private void OnComponentRemoved(GameComponentCollectionEventArgs eventArgs)
{
EventHelpers.Raise(this, ComponentRemoved, eventArgs);
}
protected override void RemoveItem(int index)
{
IGameComponent gameComponent = base[index];
base.RemoveItem(index);
if (gameComponent != null)
{
this.OnComponentRemoved(new GameComponentCollectionEventArgs(gameComponent));
}
}
protected override void SetItem(int index, IGameComponent item)
{
throw new NotSupportedException();
}
}
}

Some files were not shown because too many files have changed in this diff Show More