badlogic преди 4 години
родител
ревизия
42b7efdcd6
променени са 5 файла, в които са добавени 847 реда и са изтрити 847 реда
  1. 226 226
      spine-xna/example/spine-xna-example.csproj
  2. 253 253
      spine-xna/example/src/ExampleGame.cs
  3. 195 195
      spine-xna/src/MeshBatcher.cs
  4. 79 79
      spine-xna/src/Util.cs
  5. 94 94
      spine-xna/src/XnaTextureLoader.cs

+ 226 - 226
spine-xna/example/spine-xna-example.csproj

@@ -1,227 +1,227 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <ProjectGuid>{29CC4385-294A-4885-A3E8-FD4825E0CFDD}</ProjectGuid>
-    <ProjectTypeGuids>{6D335F3A-9D43-41b4-9D22-F6F17C4BE596};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
-    <OutputType>WinExe</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Spine</RootNamespace>
-    <AssemblyName>spine-xna-example</AssemblyName>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
-    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
-    <XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
-    <XnaPlatform>Windows</XnaPlatform>
-    <XnaProfile>HiDef</XnaProfile>
-    <XnaCrossPlatformGroupID>bf3b738e-f348-48d3-b35b-94bc118edb90</XnaCrossPlatformGroupID>
-    <XnaOutputType>Game</XnaOutputType>
-    <ApplicationIcon>Game.ico</ApplicationIcon>
-    <Thumbnail>GameThumbnail.png</Thumbnail>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <XnaUpgrade />
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\x86\Debug</OutputPath>
-    <DefineConstants>DEBUG;TRACE;WINDOWS</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <NoStdLib>true</NoStdLib>
-    <UseVSHostingProcess>false</UseVSHostingProcess>
-    <PlatformTarget>x86</PlatformTarget>
-    <XnaCompressContent>True</XnaCompressContent>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\x86\Release</OutputPath>
-    <DefineConstants>TRACE;WINDOWS</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <NoStdLib>true</NoStdLib>
-    <UseVSHostingProcess>false</UseVSHostingProcess>
-    <PlatformTarget>x86</PlatformTarget>
-    <XnaCompressContent>True</XnaCompressContent>
-  </PropertyGroup>
-  <PropertyGroup>
-    <StartupObject>Spine.ExampleProgram</StartupObject>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="Microsoft.Xna.Framework.Game, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="Microsoft.Xna.Framework.GamerServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="Microsoft.Xna.Framework.Xact, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="Microsoft.Xna.Framework.Video, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="Microsoft.Xna.Framework.Avatar, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="Microsoft.Xna.Framework.Net, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="Microsoft.Xna.Framework.Storage, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="mscorlib">
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="System">
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="System.Xml">
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="System.Core">
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="System.Xml.Linq">
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="System.Net">
-      <Private>False</Private>
-    </Reference>
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="src\ExampleGame.cs" />
-    <Compile Include="src\ExampleProgram.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="data\coin.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\coin-pro.skel">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\raptor.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\spineboy.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\raptor_normals.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <Content Include="data\tank.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Game.ico" />
-    <Content Include="GameThumbnail.png" />
-    <None Include="data\tank.atlas">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\tank-pro.json">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\tank-pro.skel">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\spine-csharp\spine-csharp.csproj">
-      <Project>{94144e22-2431-4a8f-ac04-dec22f7edd8f}</Project>
-      <Name>spine-csharp</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\example-content\spine-xna-example-content.contentproj">
-      <Project>{D0632D20-BC92-4A73-896B-30BB687732B8}</Project>
-      <Name>spine-xna-example-content</Name>
-      <XnaReferenceType>Content</XnaReferenceType>
-    </ProjectReference>
-    <ProjectReference Include="..\spine-xna.csproj">
-      <Project>{7F8F2327-C016-49C8-BB4D-F3F77971961E}</Project>
-      <Name>spine-xna</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">
-      <Visible>False</Visible>
-      <ProductName>Microsoft .NET Framework 4 Client Profile %28x86 and x64%29</ProductName>
-      <Install>true</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
-      <Install>false</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 3.5 SP1</ProductName>
-      <Install>false</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
-      <Visible>False</Visible>
-      <ProductName>Windows Installer 3.1</ProductName>
-      <Install>true</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Xna.Framework.4.0">
-      <Visible>False</Visible>
-      <ProductName>Microsoft XNA Framework Redistributable 4.0</ProductName>
-      <Install>true</Install>
-    </BootstrapperPackage>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="data\coin.atlas">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\coin-pro.json">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\goblins-pro.json">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\goblins-pro.skel">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\raptor.atlas">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\raptor-pro.json">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\spineboy.atlas">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="data\spineboy-ess.json">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets" />
-  <!--
-      To modify your build process, add your task inside one of the targets below and uncomment it. 
-      Other similar extension points exist, see Microsoft.Common.targets.
-      <Target Name="BeforeBuild">
-      </Target>
-      <Target Name="AfterBuild">
-      </Target>
-    -->
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ProjectGuid>{29CC4385-294A-4885-A3E8-FD4825E0CFDD}</ProjectGuid>
+    <ProjectTypeGuids>{6D335F3A-9D43-41b4-9D22-F6F17C4BE596};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <OutputType>WinExe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Spine</RootNamespace>
+    <AssemblyName>spine-xna-example</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
+    <XnaPlatform>Windows</XnaPlatform>
+    <XnaProfile>HiDef</XnaProfile>
+    <XnaCrossPlatformGroupID>bf3b738e-f348-48d3-b35b-94bc118edb90</XnaCrossPlatformGroupID>
+    <XnaOutputType>Game</XnaOutputType>
+    <ApplicationIcon>Game.ico</ApplicationIcon>
+    <Thumbnail>GameThumbnail.png</Thumbnail>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <XnaUpgrade />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\x86\Debug</OutputPath>
+    <DefineConstants>DEBUG;TRACE;WINDOWS</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoStdLib>true</NoStdLib>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <PlatformTarget>x86</PlatformTarget>
+    <XnaCompressContent>True</XnaCompressContent>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\x86\Release</OutputPath>
+    <DefineConstants>TRACE;WINDOWS</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoStdLib>true</NoStdLib>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <PlatformTarget>x86</PlatformTarget>
+    <XnaCompressContent>True</XnaCompressContent>
+  </PropertyGroup>
+  <PropertyGroup>
+    <StartupObject>Spine.ExampleProgram</StartupObject>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.Xna.Framework.Game, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.Xna.Framework.GamerServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.Xna.Framework.Xact, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.Xna.Framework.Video, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.Xna.Framework.Avatar, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.Xna.Framework.Net, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.Xna.Framework.Storage, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="mscorlib">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System.Xml">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System.Core">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System.Xml.Linq">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System.Net">
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="src\ExampleGame.cs" />
+    <Compile Include="src\ExampleProgram.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="data\coin.png">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="data\coin-pro.skel">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="data\raptor.png">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="data\spineboy.png">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="data\raptor_normals.png">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <Content Include="data\tank.png">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="Game.ico" />
+    <Content Include="GameThumbnail.png" />
+    <None Include="data\tank.atlas">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="data\tank-pro.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="data\tank-pro.skel">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\spine-csharp\spine-csharp.csproj">
+      <Project>{94144e22-2431-4a8f-ac04-dec22f7edd8f}</Project>
+      <Name>spine-csharp</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\example-content\spine-xna-example-content.contentproj">
+      <Project>{D0632D20-BC92-4A73-896B-30BB687732B8}</Project>
+      <Name>spine-xna-example-content</Name>
+      <XnaReferenceType>Content</XnaReferenceType>
+    </ProjectReference>
+    <ProjectReference Include="..\spine-xna.csproj">
+      <Project>{7F8F2327-C016-49C8-BB4D-F3F77971961E}</Project>
+      <Name>spine-xna</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">
+      <Visible>False</Visible>
+      <ProductName>Microsoft .NET Framework 4 Client Profile %28x86 and x64%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Xna.Framework.4.0">
+      <Visible>False</Visible>
+      <ProductName>Microsoft XNA Framework Redistributable 4.0</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="data\coin.atlas">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="data\coin-pro.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="data\goblins-pro.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="data\goblins-pro.skel">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="data\raptor.atlas">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="data\raptor-pro.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="data\spineboy.atlas">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Include="data\spineboy-ess.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets" />
+  <!--
+      To modify your build process, add your task inside one of the targets below and uncomment it. 
+      Other similar extension points exist, see Microsoft.Common.targets.
+      <Target Name="BeforeBuild">
+      </Target>
+      <Target Name="AfterBuild">
+      </Target>
+    -->
 </Project>

+ 253 - 253
spine-xna/example/src/ExampleGame.cs

@@ -1,253 +1,253 @@
-/******************************************************************************
- * Spine Runtimes License Agreement
- * Last updated January 1, 2020. Replaces all prior versions.
- *
- * Copyright (c) 2013-2020, Esoteric Software LLC
- *
- * Integration of the Spine Runtimes into software or otherwise creating
- * derivative works of the Spine Runtimes is permitted under the terms and
- * conditions of Section 2 of the Spine Editor License Agreement:
- * http://esotericsoftware.com/spine-editor-license
- *
- * Otherwise, it is permitted to integrate the Spine Runtimes into software
- * or otherwise create derivative works of the Spine Runtimes (collectively,
- * "Products"), provided that each user of the Products must obtain their own
- * Spine Editor license and redistribution of the Products in any form must
- * include this license and copyright notice.
- *
- * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
- * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-
-using System;
-using System.IO;
-using System.Collections.Generic;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Content;
-using Microsoft.Xna.Framework.Graphics;
-using Microsoft.Xna.Framework.Input;
-using Microsoft.Xna.Framework.Media;
-using Spine;
-
-namespace Spine {
-	public class Example : Microsoft.Xna.Framework.Game {
-		GraphicsDeviceManager graphics;
-		SkeletonRenderer skeletonRenderer;
-		SkeletonDebugRenderer skeletonDebugRenderer;
-		Skeleton skeleton;
-		Slot headSlot;
-		AnimationState state;
-		SkeletonBounds bounds = new SkeletonBounds();
-
-#if WINDOWS_STOREAPP
-		private string assetsFolder = @"Assets\";
-#else
-		private string assetsFolder = "data/";
-#endif
-
-		public Example () {
-			IsMouseVisible = true;
-
-			graphics = new GraphicsDeviceManager(this);
-			graphics.IsFullScreen = false;
-			graphics.PreferredBackBufferWidth = 800;
-			graphics.PreferredBackBufferHeight = 600;
-		}
-
-		protected override void Initialize () {
-			// TODO: Add your initialization logic here
-
-			base.Initialize();
-		}
-
-		protected override void LoadContent () {
-
-			bool useNormalmapShader = false;
-			Effect spineEffect;
-			if (!useNormalmapShader) {
-				// Two color tint effect. Note that you can also use the default BasicEffect instead.
-				spineEffect = Content.Load<Effect>("spine-xna-example-content\\SpineEffect");
-			}
-			else {
-				spineEffect = Content.Load<Effect>("spine-xna-example-content\\SpineEffectNormalmap");
-				spineEffect.Parameters["Light0_Direction"].SetValue(new Vector3(-0.5265408f, 0.5735765f, -0.6275069f));
-				spineEffect.Parameters["Light0_Diffuse"].SetValue(new Vector3(1, 0.9607844f, 0.8078432f));
-				spineEffect.Parameters["Light0_Specular"].SetValue(new Vector3(1, 0.9607844f, 0.8078432f));
-				spineEffect.Parameters["Light0_SpecularExponent"].SetValue(2.0f);
-			}
-			spineEffect.Parameters["World"].SetValue(Matrix.Identity);
-			spineEffect.Parameters["View"].SetValue(Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, 1.0f), Vector3.Zero, Vector3.Up));
-
-			skeletonRenderer = new SkeletonRenderer(GraphicsDevice);
-			skeletonRenderer.PremultipliedAlpha = false;
-			skeletonRenderer.Effect = spineEffect;
-
-			skeletonDebugRenderer = new SkeletonDebugRenderer(GraphicsDevice);
-			skeletonDebugRenderer.DisableAll();
-			skeletonDebugRenderer.DrawClipping = true;
-
-			// String name = "spineboy-ess";
-			// String name = "goblins-pro";
-			String name = "raptor-pro";
-			// String name = "tank-pro";
-			//String name = "coin-pro";
-			if (useNormalmapShader)
-				name = "raptor-pro"; // we only have normalmaps for raptor
-			String atlasName = name.Replace("-pro", "").Replace("-ess", "");
-			if (name == "goblins-pro") atlasName = "goblins-mesh";
-			bool binaryData = false;
-
-			Atlas atlas;
-			if (!useNormalmapShader) {
-				atlas = new Atlas(assetsFolder + atlasName + ".atlas", new XnaTextureLoader(GraphicsDevice));
-			}
-			else {
-				atlas = new Atlas(assetsFolder + atlasName + ".atlas", new XnaTextureLoader(GraphicsDevice,
-								loadMultipleTextureLayers: true, textureSuffixes: new string[] { "", "_normals" }));
-			}
-			float scale = 1;
-			if (name == "spineboy-ess") scale = 0.6f;
-			if (name == "raptor-pro") scale = 0.5f;
-			if (name == "tank-pro") scale = 0.3f;
-			if (name == "coin-pro") scale = 1;
-
-			SkeletonData skeletonData;
-			if (binaryData) {
-				SkeletonBinary binary = new SkeletonBinary(atlas);
-				binary.Scale = scale;
-				skeletonData = binary.ReadSkeletonData(assetsFolder + name + ".skel");
-			} else {
-				SkeletonJson json = new SkeletonJson(atlas);
-				json.Scale = scale;
-				skeletonData = json.ReadSkeletonData(assetsFolder + name + ".json");
-			}
-			skeleton = new Skeleton(skeletonData);
-			if (name == "goblins-pro") skeleton.SetSkin("goblin");
-
-			// Define mixing between animations.
-			AnimationStateData stateData = new AnimationStateData(skeleton.Data);
-			state = new AnimationState(stateData);
-
-			if (name == "spineboy-ess") {
-				skeleton.SetAttachment("head-bb", "head");
-
-				stateData.SetMix("run", "jump", 0.2f);
-				stateData.SetMix("jump", "run", 0.4f);
-
-				// Event handling for all animations.
-				state.Start += Start;
-				state.End += End;
-				state.Complete += Complete;
-				state.Event += Event;
-
-				state.SetAnimation(0, "run", true);
-				TrackEntry entry = state.AddAnimation(0, "jump", false, 0);
-				entry.End += End; // Event handling for queued animations.
-				state.AddAnimation(0, "run", true, 0);
-			}
-			else if (name == "raptor-pro") {
-				state.SetAnimation(0, "walk", true);
-				state.AddAnimation(1, "gun-grab", false, 2);
-			}
-			else if (name == "coin-pro") {
-				state.SetAnimation(0, "animation", true);
-			}
-			else if (name == "tank-pro") {
-				skeleton.X += 300;
-				state.SetAnimation(0, "drive", true);
-			}
-			else {
-				state.SetAnimation(0, "walk", true);
-			}
-
-			skeleton.X += 400;
-			skeleton.Y += GraphicsDevice.Viewport.Height;
-			skeleton.UpdateWorldTransform();
-
-			headSlot = skeleton.FindSlot("head");
-		}
-
-		protected override void UnloadContent () {
-			// TODO: Unload any non ContentManager content here
-		}
-
-		protected override void Update (GameTime gameTime) {
-			// TODO: Add your update logic here
-#if (!WINDOWS_STOREAPP || WINDOWS_PHONE81) && !IOS
-			if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
-					this.Exit();
-#endif
-			base.Update(gameTime);
-		}
-
-		protected override void Draw (GameTime gameTime) {
-			GraphicsDevice.Clear(Color.Black);
-
-			state.Update(gameTime.ElapsedGameTime.Milliseconds / 1000f);
-			state.Apply(skeleton);
-			skeleton.UpdateWorldTransform();
-			if (skeletonRenderer.Effect is BasicEffect) {
-				((BasicEffect)skeletonRenderer.Effect).Projection = Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 1, 0);
-			} else {
-				skeletonRenderer.Effect.Parameters["Projection"].SetValue(Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 1, 0));
-			}
-			skeletonRenderer.Begin();
-			skeletonRenderer.Draw(skeleton);
-			skeletonRenderer.End();
-
-			skeletonDebugRenderer.Effect.Projection = Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 1, 0);
-			skeletonDebugRenderer.Begin();
-			skeletonDebugRenderer.Draw(skeleton);
-			skeletonDebugRenderer.End();
-
-			bounds.Update(skeleton, true);
-			MouseState mouse = Mouse.GetState();
-			if (headSlot != null) {
-				headSlot.G = 1;
-				headSlot.B = 1;
-				if (bounds.AabbContainsPoint(mouse.X, mouse.Y)) {
-					BoundingBoxAttachment hit = bounds.ContainsPoint(mouse.X, mouse.Y);
-					if (hit != null) {
-						headSlot.G = 0;
-						headSlot.B = 0;
-					}
-				}
-			}
-
-			base.Draw(gameTime);
-		}
-
-		public void Start (TrackEntry entry) {
-#if !WINDOWS_STOREAPP
-			Console.WriteLine(entry + ": start");
-#endif
-		}
-
-		public void End (TrackEntry entry) {
-#if !WINDOWS_STOREAPP
-			Console.WriteLine(entry + ": end");
-#endif
-		}
-
-		public void Complete (TrackEntry entry) {
-#if !WINDOWS_STOREAPP
-			Console.WriteLine(entry + ": complete ");
-#endif
-		}
-
-		public void Event (TrackEntry entry, Event e) {
-#if !WINDOWS_STOREAPP
-			Console.WriteLine(entry + ": event " + e);
-#endif
-		}
-	}
-}
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated January 1, 2020. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2020, Esoteric Software LLC
+ *
+ * Integration of the Spine Runtimes into software or otherwise creating
+ * derivative works of the Spine Runtimes is permitted under the terms and
+ * conditions of Section 2 of the Spine Editor License Agreement:
+ * http://esotericsoftware.com/spine-editor-license
+ *
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software
+ * or otherwise create derivative works of the Spine Runtimes (collectively,
+ * "Products"), provided that each user of the Products must obtain their own
+ * Spine Editor license and redistribution of the Products in any form must
+ * include this license and copyright notice.
+ *
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+using Microsoft.Xna.Framework.Media;
+using Spine;
+
+namespace Spine {
+	public class Example : Microsoft.Xna.Framework.Game {
+		GraphicsDeviceManager graphics;
+		SkeletonRenderer skeletonRenderer;
+		SkeletonDebugRenderer skeletonDebugRenderer;
+		Skeleton skeleton;
+		Slot headSlot;
+		AnimationState state;
+		SkeletonBounds bounds = new SkeletonBounds();
+
+#if WINDOWS_STOREAPP
+		private string assetsFolder = @"Assets\";
+#else
+		private string assetsFolder = "data/";
+#endif
+
+		public Example () {
+			IsMouseVisible = true;
+
+			graphics = new GraphicsDeviceManager(this);
+			graphics.IsFullScreen = false;
+			graphics.PreferredBackBufferWidth = 800;
+			graphics.PreferredBackBufferHeight = 600;
+		}
+
+		protected override void Initialize () {
+			// TODO: Add your initialization logic here
+
+			base.Initialize();
+		}
+
+		protected override void LoadContent () {
+
+			bool useNormalmapShader = false;
+			Effect spineEffect;
+			if (!useNormalmapShader) {
+				// Two color tint effect. Note that you can also use the default BasicEffect instead.
+				spineEffect = Content.Load<Effect>("spine-xna-example-content\\SpineEffect");
+			}
+			else {
+				spineEffect = Content.Load<Effect>("spine-xna-example-content\\SpineEffectNormalmap");
+				spineEffect.Parameters["Light0_Direction"].SetValue(new Vector3(-0.5265408f, 0.5735765f, -0.6275069f));
+				spineEffect.Parameters["Light0_Diffuse"].SetValue(new Vector3(1, 0.9607844f, 0.8078432f));
+				spineEffect.Parameters["Light0_Specular"].SetValue(new Vector3(1, 0.9607844f, 0.8078432f));
+				spineEffect.Parameters["Light0_SpecularExponent"].SetValue(2.0f);
+			}
+			spineEffect.Parameters["World"].SetValue(Matrix.Identity);
+			spineEffect.Parameters["View"].SetValue(Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, 1.0f), Vector3.Zero, Vector3.Up));
+
+			skeletonRenderer = new SkeletonRenderer(GraphicsDevice);
+			skeletonRenderer.PremultipliedAlpha = false;
+			skeletonRenderer.Effect = spineEffect;
+
+			skeletonDebugRenderer = new SkeletonDebugRenderer(GraphicsDevice);
+			skeletonDebugRenderer.DisableAll();
+			skeletonDebugRenderer.DrawClipping = true;
+
+			// String name = "spineboy-ess";
+			// String name = "goblins-pro";
+			String name = "raptor-pro";
+			// String name = "tank-pro";
+			//String name = "coin-pro";
+			if (useNormalmapShader)
+				name = "raptor-pro"; // we only have normalmaps for raptor
+			String atlasName = name.Replace("-pro", "").Replace("-ess", "");
+			if (name == "goblins-pro") atlasName = "goblins-mesh";
+			bool binaryData = false;
+
+			Atlas atlas;
+			if (!useNormalmapShader) {
+				atlas = new Atlas(assetsFolder + atlasName + ".atlas", new XnaTextureLoader(GraphicsDevice));
+			}
+			else {
+				atlas = new Atlas(assetsFolder + atlasName + ".atlas", new XnaTextureLoader(GraphicsDevice,
+								loadMultipleTextureLayers: true, textureSuffixes: new string[] { "", "_normals" }));
+			}
+			float scale = 1;
+			if (name == "spineboy-ess") scale = 0.6f;
+			if (name == "raptor-pro") scale = 0.5f;
+			if (name == "tank-pro") scale = 0.3f;
+			if (name == "coin-pro") scale = 1;
+
+			SkeletonData skeletonData;
+			if (binaryData) {
+				SkeletonBinary binary = new SkeletonBinary(atlas);
+				binary.Scale = scale;
+				skeletonData = binary.ReadSkeletonData(assetsFolder + name + ".skel");
+			} else {
+				SkeletonJson json = new SkeletonJson(atlas);
+				json.Scale = scale;
+				skeletonData = json.ReadSkeletonData(assetsFolder + name + ".json");
+			}
+			skeleton = new Skeleton(skeletonData);
+			if (name == "goblins-pro") skeleton.SetSkin("goblin");
+
+			// Define mixing between animations.
+			AnimationStateData stateData = new AnimationStateData(skeleton.Data);
+			state = new AnimationState(stateData);
+
+			if (name == "spineboy-ess") {
+				skeleton.SetAttachment("head-bb", "head");
+
+				stateData.SetMix("run", "jump", 0.2f);
+				stateData.SetMix("jump", "run", 0.4f);
+
+				// Event handling for all animations.
+				state.Start += Start;
+				state.End += End;
+				state.Complete += Complete;
+				state.Event += Event;
+
+				state.SetAnimation(0, "run", true);
+				TrackEntry entry = state.AddAnimation(0, "jump", false, 0);
+				entry.End += End; // Event handling for queued animations.
+				state.AddAnimation(0, "run", true, 0);
+			}
+			else if (name == "raptor-pro") {
+				state.SetAnimation(0, "walk", true);
+				state.AddAnimation(1, "gun-grab", false, 2);
+			}
+			else if (name == "coin-pro") {
+				state.SetAnimation(0, "animation", true);
+			}
+			else if (name == "tank-pro") {
+				skeleton.X += 300;
+				state.SetAnimation(0, "drive", true);
+			}
+			else {
+				state.SetAnimation(0, "walk", true);
+			}
+
+			skeleton.X += 400;
+			skeleton.Y += GraphicsDevice.Viewport.Height;
+			skeleton.UpdateWorldTransform();
+
+			headSlot = skeleton.FindSlot("head");
+		}
+
+		protected override void UnloadContent () {
+			// TODO: Unload any non ContentManager content here
+		}
+
+		protected override void Update (GameTime gameTime) {
+			// TODO: Add your update logic here
+#if (!WINDOWS_STOREAPP || WINDOWS_PHONE81) && !IOS
+			if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
+					this.Exit();
+#endif
+			base.Update(gameTime);
+		}
+
+		protected override void Draw (GameTime gameTime) {
+			GraphicsDevice.Clear(Color.Black);
+
+			state.Update(gameTime.ElapsedGameTime.Milliseconds / 1000f);
+			state.Apply(skeleton);
+			skeleton.UpdateWorldTransform();
+			if (skeletonRenderer.Effect is BasicEffect) {
+				((BasicEffect)skeletonRenderer.Effect).Projection = Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 1, 0);
+			} else {
+				skeletonRenderer.Effect.Parameters["Projection"].SetValue(Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 1, 0));
+			}
+			skeletonRenderer.Begin();
+			skeletonRenderer.Draw(skeleton);
+			skeletonRenderer.End();
+
+			skeletonDebugRenderer.Effect.Projection = Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 1, 0);
+			skeletonDebugRenderer.Begin();
+			skeletonDebugRenderer.Draw(skeleton);
+			skeletonDebugRenderer.End();
+
+			bounds.Update(skeleton, true);
+			MouseState mouse = Mouse.GetState();
+			if (headSlot != null) {
+				headSlot.G = 1;
+				headSlot.B = 1;
+				if (bounds.AabbContainsPoint(mouse.X, mouse.Y)) {
+					BoundingBoxAttachment hit = bounds.ContainsPoint(mouse.X, mouse.Y);
+					if (hit != null) {
+						headSlot.G = 0;
+						headSlot.B = 0;
+					}
+				}
+			}
+
+			base.Draw(gameTime);
+		}
+
+		public void Start (TrackEntry entry) {
+#if !WINDOWS_STOREAPP
+			Console.WriteLine(entry + ": start");
+#endif
+		}
+
+		public void End (TrackEntry entry) {
+#if !WINDOWS_STOREAPP
+			Console.WriteLine(entry + ": end");
+#endif
+		}
+
+		public void Complete (TrackEntry entry) {
+#if !WINDOWS_STOREAPP
+			Console.WriteLine(entry + ": complete ");
+#endif
+		}
+
+		public void Event (TrackEntry entry, Event e) {
+#if !WINDOWS_STOREAPP
+			Console.WriteLine(entry + ": event " + e);
+#endif
+		}
+	}
+}

+ 195 - 195
spine-xna/src/MeshBatcher.cs

@@ -1,195 +1,195 @@
-/******************************************************************************
- * Spine Runtimes License Agreement
- * Last updated January 1, 2020. Replaces all prior versions.
- *
- * Copyright (c) 2013-2020, Esoteric Software LLC
- *
- * Integration of the Spine Runtimes into software or otherwise creating
- * derivative works of the Spine Runtimes is permitted under the terms and
- * conditions of Section 2 of the Spine Editor License Agreement:
- * http://esotericsoftware.com/spine-editor-license
- *
- * Otherwise, it is permitted to integrate the Spine Runtimes into software
- * or otherwise create derivative works of the Spine Runtimes (collectively,
- * "Products"), provided that each user of the Products must obtain their own
- * Spine Editor license and redistribution of the Products in any form must
- * include this license and copyright notice.
- *
- * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
- * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-
-using System;
-using System.Collections.Generic;
-using Microsoft.Xna.Framework.Graphics;
-using Microsoft.Xna.Framework;
-
-namespace Spine {
-	public struct VertexPositionColorTextureColor : IVertexType {
-		public Vector3 Position;
-		public Color Color;
-		public Vector2 TextureCoordinate;
-		public Color Color2;
-
-		public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration
-		(
-			new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
-			new VertexElement(12, VertexElementFormat.Color, VertexElementUsage.Color, 0),
-			new VertexElement(16, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
-			new VertexElement(24, VertexElementFormat.Color, VertexElementUsage.Color, 1)
-		);
-
-		VertexDeclaration IVertexType.VertexDeclaration {
-			get { return VertexDeclaration; }
-		}
-	}
-
-	// #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
-	//
-
-	/// <summary>Draws batched meshes.</summary>
-	public class MeshBatcher {
-		private readonly List<MeshItem> items;
-		private readonly Queue<MeshItem> freeItems;
-		private VertexPositionColorTextureColor[] vertexArray = { };
-		private short[] triangles = { };
-
-		public MeshBatcher () {
-			items = new List<MeshItem>(256);
-			freeItems = new Queue<MeshItem>(256);
-			EnsureCapacity(256, 512);
-		}
-
-		/// <summary>Returns a pooled MeshItem.</summary>
-		public MeshItem NextItem (int vertexCount, int triangleCount) {
-			MeshItem item = freeItems.Count > 0 ? freeItems.Dequeue() : new MeshItem();
-			if (item.vertices.Length < vertexCount) item.vertices = new VertexPositionColorTextureColor[vertexCount];
-			if (item.triangles.Length < triangleCount) item.triangles = new int[triangleCount];
-			item.vertexCount = vertexCount;
-			item.triangleCount = triangleCount;
-			items.Add(item);
-			return item;
-		}
-
-		private void EnsureCapacity (int vertexCount, int triangleCount) {
-			if (vertexArray.Length < vertexCount) vertexArray = new VertexPositionColorTextureColor[vertexCount];
-			if (triangles.Length < triangleCount) triangles = new short[triangleCount];
-		}
-
-		public void Draw (GraphicsDevice device) {
-			if (items.Count == 0) return;
-
-			int itemCount = items.Count;
-			int vertexCount = 0, triangleCount = 0;
-			for (int i = 0; i < itemCount; i++) {
-				MeshItem item = items[i];
-				vertexCount += item.vertexCount;
-				triangleCount += item.triangleCount;
-			}
-			EnsureCapacity(vertexCount, triangleCount);
-
-			vertexCount = 0;
-			triangleCount = 0;
-			Texture2D lastTexture = null;
-			for (int i = 0; i < itemCount; i++) {
-				MeshItem item = items[i];
-				int itemVertexCount = item.vertexCount;
-
-				if (item.texture != lastTexture || vertexCount + itemVertexCount > short.MaxValue) {
-					FlushVertexArray(device, vertexCount, triangleCount);
-					vertexCount = 0;
-					triangleCount = 0;
-					lastTexture = item.texture;
-					device.Textures[0] = lastTexture;
-					if (item.textureLayers != null) {
-						for (int layer = 1; layer < item.textureLayers.Length; ++layer)
-							device.Textures[layer] = item.textureLayers[layer];
-					}
-				}
-
-				int[] itemTriangles = item.triangles;
-				int itemTriangleCount = item.triangleCount;
-				for (int ii = 0, t = triangleCount; ii < itemTriangleCount; ii++, t++)
-					triangles[t] = (short)(itemTriangles[ii] + vertexCount);
-				triangleCount += itemTriangleCount;
-
-				Array.Copy(item.vertices, 0, vertexArray, vertexCount, itemVertexCount);
-				vertexCount += itemVertexCount;
-			}
-			FlushVertexArray(device, vertexCount, triangleCount);
-		}
-
-		public void AfterLastDrawPass () {
-			int itemCount = items.Count;
-			for (int i = 0; i < itemCount; i++) {
-				var item = items[i];
-				item.texture = null;
-				freeItems.Enqueue(item);
-			}
-			items.Clear();
-		}
-
-		private void FlushVertexArray (GraphicsDevice device, int vertexCount, int triangleCount) {
-			if (vertexCount == 0) return;
-			device.DrawUserIndexedPrimitives(
-				PrimitiveType.TriangleList,
-				vertexArray, 0, vertexCount,
-				triangles, 0, triangleCount / 3,
-				VertexPositionColorTextureColor.VertexDeclaration);
-		}
-	}
-
-	public class MeshItem {
-		public Texture2D texture = null;
-		public Texture2D[] textureLayers = null;
-		public int vertexCount, triangleCount;
-		public VertexPositionColorTextureColor[] vertices = { };
-		public int[] triangles = { };
-	}
-}
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated January 1, 2020. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2020, Esoteric Software LLC
+ *
+ * Integration of the Spine Runtimes into software or otherwise creating
+ * derivative works of the Spine Runtimes is permitted under the terms and
+ * conditions of Section 2 of the Spine Editor License Agreement:
+ * http://esotericsoftware.com/spine-editor-license
+ *
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software
+ * or otherwise create derivative works of the Spine Runtimes (collectively,
+ * "Products"), provided that each user of the Products must obtain their own
+ * Spine Editor license and redistribution of the Products in any form must
+ * include this license and copyright notice.
+ *
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework;
+
+namespace Spine {
+	public struct VertexPositionColorTextureColor : IVertexType {
+		public Vector3 Position;
+		public Color Color;
+		public Vector2 TextureCoordinate;
+		public Color Color2;
+
+		public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration
+		(
+			new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
+			new VertexElement(12, VertexElementFormat.Color, VertexElementUsage.Color, 0),
+			new VertexElement(16, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
+			new VertexElement(24, VertexElementFormat.Color, VertexElementUsage.Color, 1)
+		);
+
+		VertexDeclaration IVertexType.VertexDeclaration {
+			get { return VertexDeclaration; }
+		}
+	}
+
+	// #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
+	//
+
+	/// <summary>Draws batched meshes.</summary>
+	public class MeshBatcher {
+		private readonly List<MeshItem> items;
+		private readonly Queue<MeshItem> freeItems;
+		private VertexPositionColorTextureColor[] vertexArray = { };
+		private short[] triangles = { };
+
+		public MeshBatcher () {
+			items = new List<MeshItem>(256);
+			freeItems = new Queue<MeshItem>(256);
+			EnsureCapacity(256, 512);
+		}
+
+		/// <summary>Returns a pooled MeshItem.</summary>
+		public MeshItem NextItem (int vertexCount, int triangleCount) {
+			MeshItem item = freeItems.Count > 0 ? freeItems.Dequeue() : new MeshItem();
+			if (item.vertices.Length < vertexCount) item.vertices = new VertexPositionColorTextureColor[vertexCount];
+			if (item.triangles.Length < triangleCount) item.triangles = new int[triangleCount];
+			item.vertexCount = vertexCount;
+			item.triangleCount = triangleCount;
+			items.Add(item);
+			return item;
+		}
+
+		private void EnsureCapacity (int vertexCount, int triangleCount) {
+			if (vertexArray.Length < vertexCount) vertexArray = new VertexPositionColorTextureColor[vertexCount];
+			if (triangles.Length < triangleCount) triangles = new short[triangleCount];
+		}
+
+		public void Draw (GraphicsDevice device) {
+			if (items.Count == 0) return;
+
+			int itemCount = items.Count;
+			int vertexCount = 0, triangleCount = 0;
+			for (int i = 0; i < itemCount; i++) {
+				MeshItem item = items[i];
+				vertexCount += item.vertexCount;
+				triangleCount += item.triangleCount;
+			}
+			EnsureCapacity(vertexCount, triangleCount);
+
+			vertexCount = 0;
+			triangleCount = 0;
+			Texture2D lastTexture = null;
+			for (int i = 0; i < itemCount; i++) {
+				MeshItem item = items[i];
+				int itemVertexCount = item.vertexCount;
+
+				if (item.texture != lastTexture || vertexCount + itemVertexCount > short.MaxValue) {
+					FlushVertexArray(device, vertexCount, triangleCount);
+					vertexCount = 0;
+					triangleCount = 0;
+					lastTexture = item.texture;
+					device.Textures[0] = lastTexture;
+					if (item.textureLayers != null) {
+						for (int layer = 1; layer < item.textureLayers.Length; ++layer)
+							device.Textures[layer] = item.textureLayers[layer];
+					}
+				}
+
+				int[] itemTriangles = item.triangles;
+				int itemTriangleCount = item.triangleCount;
+				for (int ii = 0, t = triangleCount; ii < itemTriangleCount; ii++, t++)
+					triangles[t] = (short)(itemTriangles[ii] + vertexCount);
+				triangleCount += itemTriangleCount;
+
+				Array.Copy(item.vertices, 0, vertexArray, vertexCount, itemVertexCount);
+				vertexCount += itemVertexCount;
+			}
+			FlushVertexArray(device, vertexCount, triangleCount);
+		}
+
+		public void AfterLastDrawPass () {
+			int itemCount = items.Count;
+			for (int i = 0; i < itemCount; i++) {
+				var item = items[i];
+				item.texture = null;
+				freeItems.Enqueue(item);
+			}
+			items.Clear();
+		}
+
+		private void FlushVertexArray (GraphicsDevice device, int vertexCount, int triangleCount) {
+			if (vertexCount == 0) return;
+			device.DrawUserIndexedPrimitives(
+				PrimitiveType.TriangleList,
+				vertexArray, 0, vertexCount,
+				triangles, 0, triangleCount / 3,
+				VertexPositionColorTextureColor.VertexDeclaration);
+		}
+	}
+
+	public class MeshItem {
+		public Texture2D texture = null;
+		public Texture2D[] textureLayers = null;
+		public int vertexCount, triangleCount;
+		public VertexPositionColorTextureColor[] vertices = { };
+		public int[] triangles = { };
+	}
+}

+ 79 - 79
spine-xna/src/Util.cs

@@ -1,79 +1,79 @@
-/******************************************************************************
- * Spine Runtimes License Agreement
- * Last updated January 1, 2020. Replaces all prior versions.
- *
- * Copyright (c) 2013-2020, Esoteric Software LLC
- *
- * Integration of the Spine Runtimes into software or otherwise creating
- * derivative works of the Spine Runtimes is permitted under the terms and
- * conditions of Section 2 of the Spine Editor License Agreement:
- * http://esotericsoftware.com/spine-editor-license
- *
- * Otherwise, it is permitted to integrate the Spine Runtimes into software
- * or otherwise create derivative works of the Spine Runtimes (collectively,
- * "Products"), provided that each user of the Products must obtain their own
- * Spine Editor license and redistribution of the Products in any form must
- * include this license and copyright notice.
- *
- * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
- * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-
-using System;
-using System.IO;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
-
-#if WINDOWS_STOREAPP
-using System.Threading.Tasks;
-using Windows.Storage;
-#endif
-
-namespace Spine {
-
-	static public class Util {
-#if WINDOWS_STOREAPP
-		private static async Task<Texture2D> LoadFile(GraphicsDevice device, String path) {
-			var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
-			var file = await folder.GetFileAsync(path).AsTask().ConfigureAwait(false);
-			try {
-				return Util.LoadTexture(device, await file.OpenStreamForReadAsync().ConfigureAwait(false));
-			} catch (Exception ex) {
-				throw new Exception("Error reading texture file: " + path, ex);
-			}
-		}
-
-		static public Texture2D LoadTexture (GraphicsDevice device, String path) {
-			return LoadFile(device, path).Result;
-		}
-#else
-		static public Texture2D LoadTexture (GraphicsDevice device, String path) {
-
-#if WINDOWS_PHONE
-			Stream stream = Microsoft.Xna.Framework.TitleContainer.OpenStream(path);
-			using (Stream input = stream) {
-#else
-			using (Stream input = new FileStream(path, FileMode.Open, FileAccess.Read)) {
-#endif
-				try {
-					return Util.LoadTexture(device, input);
-				} catch (Exception ex) {
-					throw new Exception("Error reading texture file: " + path, ex);
-				}
-			}
-		}
-#endif
-
-		static public Texture2D LoadTexture (GraphicsDevice device, Stream input) {
-			return Texture2D.FromStream(device, input);
-		}
-	}
-}
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated January 1, 2020. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2020, Esoteric Software LLC
+ *
+ * Integration of the Spine Runtimes into software or otherwise creating
+ * derivative works of the Spine Runtimes is permitted under the terms and
+ * conditions of Section 2 of the Spine Editor License Agreement:
+ * http://esotericsoftware.com/spine-editor-license
+ *
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software
+ * or otherwise create derivative works of the Spine Runtimes (collectively,
+ * "Products"), provided that each user of the Products must obtain their own
+ * Spine Editor license and redistribution of the Products in any form must
+ * include this license and copyright notice.
+ *
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+using System;
+using System.IO;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+#if WINDOWS_STOREAPP
+using System.Threading.Tasks;
+using Windows.Storage;
+#endif
+
+namespace Spine {
+
+	static public class Util {
+#if WINDOWS_STOREAPP
+		private static async Task<Texture2D> LoadFile(GraphicsDevice device, String path) {
+			var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
+			var file = await folder.GetFileAsync(path).AsTask().ConfigureAwait(false);
+			try {
+				return Util.LoadTexture(device, await file.OpenStreamForReadAsync().ConfigureAwait(false));
+			} catch (Exception ex) {
+				throw new Exception("Error reading texture file: " + path, ex);
+			}
+		}
+
+		static public Texture2D LoadTexture (GraphicsDevice device, String path) {
+			return LoadFile(device, path).Result;
+		}
+#else
+		static public Texture2D LoadTexture (GraphicsDevice device, String path) {
+
+#if WINDOWS_PHONE
+			Stream stream = Microsoft.Xna.Framework.TitleContainer.OpenStream(path);
+			using (Stream input = stream) {
+#else
+			using (Stream input = new FileStream(path, FileMode.Open, FileAccess.Read)) {
+#endif
+				try {
+					return Util.LoadTexture(device, input);
+				} catch (Exception ex) {
+					throw new Exception("Error reading texture file: " + path, ex);
+				}
+			}
+		}
+#endif
+
+		static public Texture2D LoadTexture (GraphicsDevice device, Stream input) {
+			return Texture2D.FromStream(device, input);
+		}
+	}
+}

+ 94 - 94
spine-xna/src/XnaTextureLoader.cs

@@ -1,94 +1,94 @@
-/******************************************************************************
- * Spine Runtimes License Agreement
- * Last updated January 1, 2020. Replaces all prior versions.
- *
- * Copyright (c) 2013-2020, Esoteric Software LLC
- *
- * Integration of the Spine Runtimes into software or otherwise creating
- * derivative works of the Spine Runtimes is permitted under the terms and
- * conditions of Section 2 of the Spine Editor License Agreement:
- * http://esotericsoftware.com/spine-editor-license
- *
- * Otherwise, it is permitted to integrate the Spine Runtimes into software
- * or otherwise create derivative works of the Spine Runtimes (collectively,
- * "Products"), provided that each user of the Products must obtain their own
- * Spine Editor license and redistribution of the Products in any form must
- * include this license and copyright notice.
- *
- * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
- * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-
-using System;
-using System.IO;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
-
-namespace Spine {
-	public class XnaTextureLoader : TextureLoader {
-		GraphicsDevice device;
-		string[] textureLayerSuffixes = null;
-
-		/// <summary>
-		/// Constructor.
-		/// </summary>
-		/// <param name="device">The graphics device to be used.</param>
-		/// <param name="loadMultipleTextureLayers">If <c>true</c> multiple textures layers
-		/// (e.g. a diffuse/albedo texture and a normal map) are loaded instead of a single texture.
-		/// Names are constructed based on suffixes added according to the <c>textureSuffixes</c> parameter.</param>
-		/// <param name="textureSuffixes">If <c>loadMultipleTextureLayers</c> is <c>true</c>, the strings of this array
-		/// define the path name suffix of each layer to be loaded. Array size must be equal to the number of layers to be loaded.
-		/// The first array entry is the suffix to be <c>replaced</c> (e.g. "_albedo", or "" for a first layer without a suffix),
-		/// subsequent array entries contain the suffix to replace the first entry with (e.g. "_normals").
-		///
-		/// An example would be:
-		/// <code>new string[] { "", "_normals" }</code> for loading a base diffuse texture named "skeletonname.png" and
-		/// a normalmap named "skeletonname_normals.png".</param>
-		public XnaTextureLoader (GraphicsDevice device, bool loadMultipleTextureLayers = false, string[] textureSuffixes = null) {
-			this.device = device;
-			if (loadMultipleTextureLayers)
-				this.textureLayerSuffixes = textureSuffixes;
-		}
-
-		public void Load (AtlasPage page, String path) {
-			Texture2D texture = Util.LoadTexture(device, path);
-			page.width = texture.Width;
-			page.height = texture.Height;
-
-			if (textureLayerSuffixes == null) {
-				page.rendererObject = texture;
-			}
-			else {
-				Texture2D[] textureLayersArray = new Texture2D[textureLayerSuffixes.Length];
-				textureLayersArray[0] = texture;
-				for (int layer = 1; layer < textureLayersArray.Length; ++layer) {
-					string layerPath = GetLayerName(path, textureLayerSuffixes[0], textureLayerSuffixes[layer]);
-					textureLayersArray[layer] = Util.LoadTexture(device, layerPath);
-				}
-				page.rendererObject = textureLayersArray;
-			}
-		}
-
-		public void Unload (Object texture) {
-			((Texture2D)texture).Dispose();
-		}
-
-		private string GetLayerName (string firstLayerPath, string firstLayerSuffix, string replacementSuffix) {
-
-			int suffixLocation = firstLayerPath.LastIndexOf(firstLayerSuffix + ".");
-			if (suffixLocation == -1) {
-				throw new Exception(string.Concat("Error composing texture layer name: first texture layer name '", firstLayerPath,
-								"' does not contain suffix to be replaced: '", firstLayerSuffix, "'"));
-			}
-			return firstLayerPath.Remove(suffixLocation, firstLayerSuffix.Length).Insert(suffixLocation, replacementSuffix);
-		}
-	}
-}
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated January 1, 2020. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2020, Esoteric Software LLC
+ *
+ * Integration of the Spine Runtimes into software or otherwise creating
+ * derivative works of the Spine Runtimes is permitted under the terms and
+ * conditions of Section 2 of the Spine Editor License Agreement:
+ * http://esotericsoftware.com/spine-editor-license
+ *
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software
+ * or otherwise create derivative works of the Spine Runtimes (collectively,
+ * "Products"), provided that each user of the Products must obtain their own
+ * Spine Editor license and redistribution of the Products in any form must
+ * include this license and copyright notice.
+ *
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+using System;
+using System.IO;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace Spine {
+	public class XnaTextureLoader : TextureLoader {
+		GraphicsDevice device;
+		string[] textureLayerSuffixes = null;
+
+		/// <summary>
+		/// Constructor.
+		/// </summary>
+		/// <param name="device">The graphics device to be used.</param>
+		/// <param name="loadMultipleTextureLayers">If <c>true</c> multiple textures layers
+		/// (e.g. a diffuse/albedo texture and a normal map) are loaded instead of a single texture.
+		/// Names are constructed based on suffixes added according to the <c>textureSuffixes</c> parameter.</param>
+		/// <param name="textureSuffixes">If <c>loadMultipleTextureLayers</c> is <c>true</c>, the strings of this array
+		/// define the path name suffix of each layer to be loaded. Array size must be equal to the number of layers to be loaded.
+		/// The first array entry is the suffix to be <c>replaced</c> (e.g. "_albedo", or "" for a first layer without a suffix),
+		/// subsequent array entries contain the suffix to replace the first entry with (e.g. "_normals").
+		///
+		/// An example would be:
+		/// <code>new string[] { "", "_normals" }</code> for loading a base diffuse texture named "skeletonname.png" and
+		/// a normalmap named "skeletonname_normals.png".</param>
+		public XnaTextureLoader (GraphicsDevice device, bool loadMultipleTextureLayers = false, string[] textureSuffixes = null) {
+			this.device = device;
+			if (loadMultipleTextureLayers)
+				this.textureLayerSuffixes = textureSuffixes;
+		}
+
+		public void Load (AtlasPage page, String path) {
+			Texture2D texture = Util.LoadTexture(device, path);
+			page.width = texture.Width;
+			page.height = texture.Height;
+
+			if (textureLayerSuffixes == null) {
+				page.rendererObject = texture;
+			}
+			else {
+				Texture2D[] textureLayersArray = new Texture2D[textureLayerSuffixes.Length];
+				textureLayersArray[0] = texture;
+				for (int layer = 1; layer < textureLayersArray.Length; ++layer) {
+					string layerPath = GetLayerName(path, textureLayerSuffixes[0], textureLayerSuffixes[layer]);
+					textureLayersArray[layer] = Util.LoadTexture(device, layerPath);
+				}
+				page.rendererObject = textureLayersArray;
+			}
+		}
+
+		public void Unload (Object texture) {
+			((Texture2D)texture).Dispose();
+		}
+
+		private string GetLayerName (string firstLayerPath, string firstLayerSuffix, string replacementSuffix) {
+
+			int suffixLocation = firstLayerPath.LastIndexOf(firstLayerSuffix + ".");
+			if (suffixLocation == -1) {
+				throw new Exception(string.Concat("Error composing texture layer name: first texture layer name '", firstLayerPath,
+								"' does not contain suffix to be replaced: '", firstLayerSuffix, "'"));
+			}
+			return firstLayerPath.Remove(suffixLocation, firstLayerSuffix.Length).Insert(suffixLocation, replacementSuffix);
+		}
+	}
+}