Эх сурвалжийг харах

[runtimes] Updated ALL sources to use latest Spine Runtimes License v2.5. Manually checked all the things...

badlogic 9 жил өмнө
parent
commit
5aa27771c3
100 өөрчлөгдсөн 11880 нэмэгдсэн , 11979 устгасан
  1. 93 94
      spine-as3/spine-as3-example/src/spine/examples/Main.as
  2. 43 44
      spine-as3/spine-as3/src/spine/BlendMode.as
  3. 353 354
      spine-as3/spine-as3/src/spine/Bone.as
  4. 72 73
      spine-as3/spine-as3/src/spine/BoneData.as
  5. 52 53
      spine-as3/spine-as3/src/spine/Event.as
  6. 50 51
      spine-as3/spine-as3/src/spine/EventData.as
  7. 227 228
      spine-as3/spine-as3/src/spine/IkConstraint.as
  8. 51 52
      spine-as3/spine-as3/src/spine/IkConstraintData.as
  9. 49 50
      spine-as3/spine-as3/src/spine/MathUtils.as
  10. 416 417
      spine-as3/spine-as3/src/spine/PathConstraint.as
  11. 58 59
      spine-as3/spine-as3/src/spine/PathConstraintData.as
  12. 79 80
      spine-as3/spine-as3/src/spine/Polygon.as
  13. 35 36
      spine-as3/spine-as3/src/spine/PositionMode.as
  14. 36 37
      spine-as3/spine-as3/src/spine/RotateMode.as
  15. 445 446
      spine-as3/spine-as3/src/spine/Skeleton.as
  16. 149 150
      spine-as3/spine-as3/src/spine/SkeletonBounds.as
  17. 177 178
      spine-as3/spine-as3/src/spine/SkeletonData.as
  18. 734 734
      spine-as3/spine-as3/src/spine/SkeletonJson.as
  19. 90 91
      spine-as3/spine-as3/src/spine/Skin.as
  20. 103 104
      spine-as3/spine-as3/src/spine/Slot.as
  21. 67 68
      spine-as3/spine-as3/src/spine/SlotData.as
  22. 36 37
      spine-as3/spine-as3/src/spine/SpacingMode.as
  23. 129 130
      spine-as3/spine-as3/src/spine/TransformConstraint.as
  24. 63 64
      spine-as3/spine-as3/src/spine/TransformConstraintData.as
  25. 34 35
      spine-as3/spine-as3/src/spine/Updatable.as
  26. 130 131
      spine-as3/spine-as3/src/spine/animation/Animation.as
  27. 238 239
      spine-as3/spine-as3/src/spine/animation/AnimationState.as
  28. 65 66
      spine-as3/spine-as3/src/spine/animation/AnimationStateData.as
  29. 67 68
      spine-as3/spine-as3/src/spine/animation/AttachmentTimeline.as
  30. 99 100
      spine-as3/spine-as3/src/spine/animation/ColorTimeline.as
  31. 115 116
      spine-as3/spine-as3/src/spine/animation/CurveTimeline.as
  32. 102 103
      spine-as3/spine-as3/src/spine/animation/DeformTimeline.as
  33. 76 77
      spine-as3/spine-as3/src/spine/animation/DrawOrderTimeline.as
  34. 78 79
      spine-as3/spine-as3/src/spine/animation/EventTimeline.as
  35. 76 77
      spine-as3/spine-as3/src/spine/animation/IkConstraintTimeline.as
  36. 60 61
      spine-as3/spine-as3/src/spine/animation/Listeners.as
  37. 79 80
      spine-as3/spine-as3/src/spine/animation/PathConstraintMixTimeline.as
  38. 74 75
      spine-as3/spine-as3/src/spine/animation/PathConstraintPositionTimeline.as
  39. 58 59
      spine-as3/spine-as3/src/spine/animation/PathConstraintSpacingTimeline.as
  40. 89 90
      spine-as3/spine-as3/src/spine/animation/RotateTimeline.as
  41. 61 62
      spine-as3/spine-as3/src/spine/animation/ScaleTimeline.as
  42. 15 16
      spine-as3/spine-as3/src/spine/animation/ShearTimeline.as
  43. 37 38
      spine-as3/spine-as3/src/spine/animation/Timeline.as
  44. 47 48
      spine-as3/spine-as3/src/spine/animation/TrackEntry.as
  45. 86 87
      spine-as3/spine-as3/src/spine/animation/TransformConstraintTimeline.as
  46. 78 79
      spine-as3/spine-as3/src/spine/animation/TranslateTimeline.as
  47. 207 208
      spine-as3/spine-as3/src/spine/atlas/Atlas.as
  48. 45 46
      spine-as3/spine-as3/src/spine/atlas/AtlasPage.as
  49. 55 56
      spine-as3/spine-as3/src/spine/atlas/AtlasRegion.as
  50. 48 49
      spine-as3/spine-as3/src/spine/atlas/Format.as
  51. 48 49
      spine-as3/spine-as3/src/spine/atlas/TextureFilter.as
  52. 36 37
      spine-as3/spine-as3/src/spine/atlas/TextureLoader.as
  53. 44 45
      spine-as3/spine-as3/src/spine/atlas/TextureWrap.as
  54. 101 102
      spine-as3/spine-as3/src/spine/attachments/AtlasAttachmentLoader.as
  55. 48 49
      spine-as3/spine-as3/src/spine/attachments/Attachment.as
  56. 45 46
      spine-as3/spine-as3/src/spine/attachments/AttachmentLoader.as
  57. 47 48
      spine-as3/spine-as3/src/spine/attachments/AttachmentType.as
  58. 35 36
      spine-as3/spine-as3/src/spine/attachments/BoundingBoxAttachment.as
  59. 107 108
      spine-as3/spine-as3/src/spine/attachments/MeshAttachment.as
  60. 39 40
      spine-as3/spine-as3/src/spine/attachments/PathAttachment.as
  61. 147 148
      spine-as3/spine-as3/src/spine/attachments/RegionAttachment.as
  62. 123 124
      spine-as3/spine-as3/src/spine/attachments/VertexAttachment.as
  63. 82 83
      spine-as3/spine-as3/src/spine/flash/FlashTextureLoader.as
  64. 49 50
      spine-as3/spine-as3/src/spine/flash/SkeletonAnimation.as
  65. 149 150
      spine-as3/spine-as3/src/spine/flash/SkeletonSprite.as
  66. 547 548
      spine-c/include/spine/Animation.h
  67. 148 149
      spine-c/include/spine/AnimationState.h
  68. 73 74
      spine-c/include/spine/AnimationStateData.h
  69. 169 170
      spine-c/include/spine/Atlas.h
  70. 54 55
      spine-c/include/spine/AtlasAttachmentLoader.h
  71. 76 77
      spine-c/include/spine/Attachment.h
  72. 75 76
      spine-c/include/spine/AttachmentLoader.h
  73. 123 124
      spine-c/include/spine/Bone.h
  74. 72 73
      spine-c/include/spine/BoneData.h
  75. 57 58
      spine-c/include/spine/BoundingBoxAttachment.h
  76. 68 69
      spine-c/include/spine/Event.h
  77. 64 65
      spine-c/include/spine/EventData.h
  78. 86 87
      spine-c/include/spine/IkConstraint.h
  79. 72 73
      spine-c/include/spine/IkConstraintData.h
  80. 89 90
      spine-c/include/spine/MeshAttachment.h
  81. 61 62
      spine-c/include/spine/PathAttachment.h
  82. 109 110
      spine-c/include/spine/PathConstraint.h
  83. 92 93
      spine-c/include/spine/PathConstraintData.h
  84. 84 85
      spine-c/include/spine/RegionAttachment.h
  85. 172 173
      spine-c/include/spine/Skeleton.h
  86. 68 69
      spine-c/include/spine/SkeletonBinary.h
  87. 109 110
      spine-c/include/spine/SkeletonBounds.h
  88. 113 114
      spine-c/include/spine/SkeletonData.h
  89. 69 70
      spine-c/include/spine/SkeletonJson.h
  90. 91 92
      spine-c/include/spine/Skin.h
  91. 87 88
      spine-c/include/spine/Slot.h
  92. 83 84
      spine-c/include/spine/SlotData.h
  93. 77 78
      spine-c/include/spine/TransformConstraint.h
  94. 78 79
      spine-c/include/spine/TransformConstraintData.h
  95. 64 65
      spine-c/include/spine/VertexAttachment.h
  96. 55 56
      spine-c/include/spine/spine.h
  97. 1052 1053
      spine-c/src/spine/Animation.c
  98. 319 320
      spine-c/src/spine/AnimationState.c
  99. 148 149
      spine-c/src/spine/AnimationStateData.c
  100. 350 351
      spine-c/src/spine/Atlas.c

+ 93 - 94
spine-as3/spine-as3-example/src/spine/examples/Main.as

@@ -1,97 +1,96 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.examples {
-
-import flash.display.Sprite;
-
-import spine.*;
-import spine.animation.AnimationStateData;
-import spine.atlas.Atlas;
-import spine.attachments.AtlasAttachmentLoader;
-import spine.flash.FlashTextureLoader;
-import spine.flash.SkeletonAnimation;
-
-[SWF(width = "800", height = "600", frameRate = "60", backgroundColor = "#dddddd")]
-public class Main extends Sprite {
-	[Embed(source = "/spineboy.atlas", mimeType = "application/octet-stream")]
-	static public const SpineboyAtlas:Class;
-
-	[Embed(source = "/spineboy.png")]
-	static public const SpineboyAtlasTexture:Class;
-
-	[Embed(source = "/spineboy.json", mimeType = "application/octet-stream")]
-	static public const SpineboyJson:Class;
-
-	private var skeleton:SkeletonAnimation;
-
-	public function Main () {
-		var atlas:Atlas = new Atlas(new SpineboyAtlas(), new FlashTextureLoader(new SpineboyAtlasTexture()));
-		var json:SkeletonJson = new SkeletonJson(new AtlasAttachmentLoader(atlas));
-		json.scale = 0.6;
-		var skeletonData:SkeletonData = json.readSkeletonData(new SpineboyJson());
-
-		var stateData:AnimationStateData = new AnimationStateData(skeletonData);
-		stateData.setMixByName("walk", "jump", 0.2);
-		stateData.setMixByName("jump", "run", 0.4);
-		stateData.setMixByName("jump", "jump", 0.2);
-
-		skeleton = new SkeletonAnimation(skeletonData, stateData);
-		skeleton.x = 400;
-		skeleton.y = 560;
-		
-		skeleton.state.onStart.add(function (trackIndex:int) : void {
-			trace(trackIndex + " fuu start: " + skeleton.state.getCurrent(trackIndex));
-		});
-		skeleton.state.onEnd.add(function (trackIndex:int) : void {
-			trace(trackIndex + " end: " + skeleton.state.getCurrent(trackIndex));
-		});
-		skeleton.state.onComplete.add(function (trackIndex:int, count:int) : void {
-			trace(trackIndex + " complete: " + skeleton.state.getCurrent(trackIndex) + ", " + count);
-		});
-		skeleton.state.onEvent.add(function (trackIndex:int, event:Event) : void {
-			trace(trackIndex + " event: " + skeleton.state.getCurrent(trackIndex) + ", "
-				+ event.data.name + ": " + event.intValue + ", " + event.floatValue + ", " + event.stringValue);
-		});
-		
-		if (false) {
-			skeleton.state.setAnimationByName(0, "test", true);
-		} else {
-			skeleton.state.setAnimationByName(0, "walk", true);
-			skeleton.state.addAnimationByName(0, "jump", false, 3);
-			skeleton.state.addAnimationByName(0, "run", true, 0);
-		}
-
-		addChild(skeleton);
-	}
-}
-
+package spine.examples {
+
+import flash.display.Sprite;
+
+import spine.*;
+import spine.animation.AnimationStateData;
+import spine.atlas.Atlas;
+import spine.attachments.AtlasAttachmentLoader;
+import spine.flash.FlashTextureLoader;
+import spine.flash.SkeletonAnimation;
+
+[SWF(width = "800", height = "600", frameRate = "60", backgroundColor = "#dddddd")]
+public class Main extends Sprite {
+	[Embed(source = "/spineboy.atlas", mimeType = "application/octet-stream")]
+	static public const SpineboyAtlas:Class;
+
+	[Embed(source = "/spineboy.png")]
+	static public const SpineboyAtlasTexture:Class;
+
+	[Embed(source = "/spineboy.json", mimeType = "application/octet-stream")]
+	static public const SpineboyJson:Class;
+
+	private var skeleton:SkeletonAnimation;
+
+	public function Main () {
+		var atlas:Atlas = new Atlas(new SpineboyAtlas(), new FlashTextureLoader(new SpineboyAtlasTexture()));
+		var json:SkeletonJson = new SkeletonJson(new AtlasAttachmentLoader(atlas));
+		json.scale = 0.6;
+		var skeletonData:SkeletonData = json.readSkeletonData(new SpineboyJson());
+
+		var stateData:AnimationStateData = new AnimationStateData(skeletonData);
+		stateData.setMixByName("walk", "jump", 0.2);
+		stateData.setMixByName("jump", "run", 0.4);
+		stateData.setMixByName("jump", "jump", 0.2);
+
+		skeleton = new SkeletonAnimation(skeletonData, stateData);
+		skeleton.x = 400;
+		skeleton.y = 560;
+		
+		skeleton.state.onStart.add(function (trackIndex:int) : void {
+			trace(trackIndex + " fuu start: " + skeleton.state.getCurrent(trackIndex));
+		});
+		skeleton.state.onEnd.add(function (trackIndex:int) : void {
+			trace(trackIndex + " end: " + skeleton.state.getCurrent(trackIndex));
+		});
+		skeleton.state.onComplete.add(function (trackIndex:int, count:int) : void {
+			trace(trackIndex + " complete: " + skeleton.state.getCurrent(trackIndex) + ", " + count);
+		});
+		skeleton.state.onEvent.add(function (trackIndex:int, event:Event) : void {
+			trace(trackIndex + " event: " + skeleton.state.getCurrent(trackIndex) + ", "
+				+ event.data.name + ": " + event.intValue + ", " + event.floatValue + ", " + event.stringValue);
+		});
+		
+		if (false) {
+			skeleton.state.setAnimationByName(0, "test", true);
+		} else {
+			skeleton.state.setAnimationByName(0, "walk", true);
+			skeleton.state.addAnimationByName(0, "jump", false, 3);
+			skeleton.state.addAnimationByName(0, "run", true, 0);
+		}
+
+		addChild(skeleton);
+	}
+}
+
 }

+ 43 - 44
spine-as3/spine-as3/src/spine/BlendMode.as

@@ -1,47 +1,46 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public class BlendMode {
-	public static const normal:BlendMode = new BlendMode(0);
-	public static const additive:BlendMode = new BlendMode(1);
-	public static const multiply:BlendMode = new BlendMode(2);
-	public static const screen:BlendMode = new BlendMode(3);
-
-	public var ordinal:int;
-
-	public function BlendMode (ordinal:int) {
-		this.ordinal = ordinal;
-	}
-}
-
+package spine {
+
+public class BlendMode {
+	public static const normal:BlendMode = new BlendMode(0);
+	public static const additive:BlendMode = new BlendMode(1);
+	public static const multiply:BlendMode = new BlendMode(2);
+	public static const screen:BlendMode = new BlendMode(3);
+
+	public var ordinal:int;
+
+	public function BlendMode (ordinal:int) {
+		this.ordinal = ordinal;
+	}
+}
+
 }

+ 353 - 354
spine-as3/spine-as3/src/spine/Bone.as

@@ -1,357 +1,356 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public class Bone implements Updatable {
-	static public var yDown:Boolean;
-
-	internal var _data:BoneData;
-	internal var _skeleton:Skeleton;
-	internal var _parent:Bone;
-	internal var _children:Vector.<Bone> = new Vector.<Bone>();
-	public var x:Number;
-	public var y:Number;
-	public var rotation:Number;
-	public var scaleX:Number;
-	public var scaleY:Number;
-	public var shearX:Number;
-	public var shearY:Number;
-	public var appliedRotation:Number;	
-
-	internal var _a:Number;
-	internal var _b:Number;
-	internal var _c:Number;
-	internal var _d:Number;
-	internal var _worldX:Number;
-	internal var _worldY:Number;
-	internal var _worldSignX:Number;
-	internal var _worldSignY:Number;
-	
-	internal var _sorted:Boolean;
-
-	/** @param parent May be null. */
-	public function Bone (data:BoneData, skeleton:Skeleton, parent:Bone) {
-		if (data == null) throw new ArgumentError("data cannot be null.");
-		if (skeleton == null) throw new ArgumentError("skeleton cannot be null.");
-		_data = data;
-		_skeleton = skeleton;
-		_parent = parent;
-		setToSetupPose();
-	}
-	
-	/** Same as updateWorldTransform(). This method exists for Bone to implement Updatable. */
-	public function update () : void {
-		updateWorldTransformWith(x, y, rotation, scaleX, scaleY, shearX, shearY);
-	}
-
-	/** Computes the world SRT using the parent bone and this bone's local SRT. */
-	public function updateWorldTransform () : void {
-		updateWorldTransformWith(x, y, rotation, scaleX, scaleY, shearX, shearY);
-	}
-
-	/** Computes the world SRT using the parent bone and the specified local SRT. */
-	public function updateWorldTransformWith (x:Number, y:Number, rotation:Number, scaleX:Number, scaleY:Number, shearX:Number, shearY:Number) : void {
-		appliedRotation = rotation;
-
-		var rotationY:Number = rotation + 90 + shearY;
-		var la:Number = MathUtils.cosDeg(rotation + shearX) * scaleX, lb:Number = MathUtils.cosDeg(rotationY) * scaleY;
-		var lc:Number = MathUtils.sinDeg(rotation + shearX) * scaleX, ld:Number = MathUtils.sinDeg(rotationY) * scaleY;
-		
-		var parent:Bone = _parent;
-		if (!parent) { // Root bone.
-			var skeleton:Skeleton = _skeleton;
-			if (skeleton.flipX) {
-				x = -x;
-				la = -la;
-				lb = -lb;
-			}
-			if (skeleton.flipY != yDown) {
-				y = -y;
-				lc = -lc;
-				ld = -ld;
-			}
-			_a = la;
-			_b = lb;
-			_c = lc;
-			_d = ld;
-			_worldX = x;
-			_worldY = y;
-			_worldSignX = scaleX < 0 ? -1 : 1;
-			_worldSignY = scaleY < 0 ? -1 : 1;
-			return;
-		}
-
-		var pa:Number = parent._a, pb:Number = parent._b, pc:Number = parent._c, pd:Number = parent._d;
-		_worldX = pa * x + pb * y + parent._worldX;
-		_worldY = pc * x + pd * y + parent._worldY;
-		_worldSignX = parent._worldSignX * (scaleX < 0 ? -1 : 1);
-		_worldSignY = parent._worldSignY * (scaleY < 0 ? -1 : 1);
-
-		if (data.inheritRotation && data.inheritScale) {
-			_a = pa * la + pb * lc;
-			_b = pa * lb + pb * ld;
-			_c = pc * la + pd * lc;
-			_d = pc * lb + pd * ld;
-		} else {
-			if (data.inheritRotation) { // No scale inheritance.
-				pa = 1;
-				pb = 0;
-				pc = 0;
-				pd = 1;
-				do {
-					var cos:Number = MathUtils.cosDeg(parent.appliedRotation), sin:Number = MathUtils.sinDeg(parent.appliedRotation);
-					var temp:Number = pa * cos + pb * sin;
-					pb = pb * cos - pa * sin;
-					pa = temp;
-					temp = pc * cos + pd * sin;
-					pd = pd * cos - pc * sin;
-					pc = temp;
-	
-					if (!parent.data.inheritRotation) break;
-					parent = parent.parent;
-				} while (parent != null);
-				_a = pa * la + pb * lc;
-				_b = pa * lb + pb * ld;
-				_c = pc * la + pd * lc;
-				_d = pc * lb + pd * ld;
-			} else if (data.inheritScale) { // No rotation inheritance.
-				pa = 1;
-				pb = 0;
-				pc = 0;
-				pd = 1;
-				do {
-					cos = MathUtils.cosDeg(parent.appliedRotation), sin = MathUtils.sinDeg(parent.appliedRotation);
-					var psx:Number = parent.scaleX, psy:Number = parent.scaleY;
-					var za:Number = cos * psx, zb:Number = sin * psy, zc:Number = sin * psx, zd:Number = cos * psy;
-					temp = pa * za + pb * zc;
-					pb = pb * zd - pa * zb;
-					pa = temp;
-					temp = pc * za + pd * zc;
-					pd = pd * zd - pc * zb;
-					pc = temp;
-
-					if (psx >= 0) sin = -sin;
-					temp = pa * cos + pb * sin;
-					pb = pb * cos - pa * sin;
-					pa = temp;
-					temp = pc * cos + pd * sin;
-					pd = pd * cos - pc * sin;
-					pc = temp;
-	
-					if (!parent.data.inheritScale) break;
-					parent = parent.parent;
-				} while (parent != null);
-				_a = pa * la + pb * lc;
-				_b = pa * lb + pb * ld;
-				_c = pc * la + pd * lc;
-				_d = pc * lb + pd * ld;
-			} else {
-				_a = la;
-				_b = lb;
-				_c = lc;
-				_d = ld;
-			}
-			if (_skeleton.flipX) {
-				_a = -_a;
-				_b = -_b;
-			}
-			if (_skeleton.flipY != yDown) {
-				_c = -_c;
-				_d = -_d;
-			}
-		}
-	}
-
-	public function setToSetupPose () : void {
-		x = _data.x;
-		y = _data.y;
-		rotation = _data.rotation;
-		scaleX = _data.scaleX;
-		scaleY = _data.scaleY;
-		shearX = _data.shearX;
-		shearY = _data.shearY;
-	}
-
-	public function get data () : BoneData {
-		return _data;
-	}
-	
-	public function get skeleton () : Skeleton {
-		return _skeleton;
-	}
-	
-	public function get parent () : Bone {
-		return _parent;
-	}
-	
-	public function get children () : Vector.<Bone> {;
-		return _children;
-	}
-
-	public function get a () : Number {
-		return _a;
-	}
-
-	public function get b () : Number {
-		return _b;
-	}
-
-	public function get c () : Number {
-		return _c;
-	}
-
-	public function get d () : Number {
-		return _d;
-	}
-
-	public function get worldX () : Number {
-		return _worldX;
-	}
-
-	public function get worldY () : Number {
-		return _worldY;
-	}
-
-	public function get worldSignX () : Number {
-		return _worldSignX;
-	}
-
-	public function get worldSignY () : Number {
-		return _worldSignY;
-	}
-
-	public function get worldRotationX () : Number {
-		return Math.atan2(_c, _a) * MathUtils.radDeg;
-	}
-
-	public function get worldRotationY () : Number {
-		return Math.atan2(_d, _b) * MathUtils.radDeg;
-	}
-
-	public function get worldScaleX () : Number {
-		return Math.sqrt(_a * _a + _b * _b) * _worldSignX;
-	}
-
-	public function get worldScaleY () : Number {
-		return Math.sqrt(_c * _c + _d * _d) * _worldSignY;
-	}
-	
-	public function worldToLocalRotationX () : Number {
-		var parent:Bone = _parent;
-		if (parent == null) return rotation;
-		var pa:Number = parent.a, pb:Number = parent.b, pc:Number = parent.c, pd:Number = parent.d, a:Number = this.a, c:Number = this.c;
-		return Math.atan2(pa * c - pc * a, pd * a - pb * c) * MathUtils.radDeg;
-	}
-
-	public function worldToLocalRotationY () : Number {
-		var parent:Bone = _parent;
-		if (parent == null) return rotation;
-		var pa:Number = parent.a, pb:Number = parent.b, pc:Number = parent.c, pd:Number = parent.d, b:Number = this.b, d:Number = this.d;
-		return Math.atan2(pa * d - pc * b, pd * b - pb * d) * MathUtils.radDeg;
-	}
-
-	public function rotateWorld (degrees:Number) : void {
-		var a:Number = this.a, b:Number = this.b, c:Number = this.c, d:Number = this.d;
-		var cos:Number = MathUtils.cosDeg(degrees), sin:Number = MathUtils.sinDeg(degrees);
-		this._a = cos * a - sin * c;
-		this._b = cos * b - sin * d;
-		this._c = sin * a + cos * c;
-		this._d = sin * b + cos * d;
-	}
-
-	/** Computes the local transform from the world transform. This can be useful to perform processing on the local transform
-	 * after the world transform has been modified directly (eg, by a constraint).
-	 * <p>
-	 * Some redundant information is lost by the world transform, such as -1,-1 scale versus 180 rotation. The computed local
-	 * transform values may differ from the original values but are functionally the same. */
-	public function updateLocalTransform () : void {
-		var parent:Bone = this.parent;
-		if (parent == null) {
-			x = worldX;
-			y = worldY;
-			rotation = Math.atan2(c, a) * MathUtils.radDeg;
-			scaleX = Math.sqrt(a * a + c * c);
-			scaleY = Math.sqrt(b * b + d * d);
-			var det:Number = a * d - b * c;
-			shearX = 0;
-			shearY = Math.atan2(a * b + c * d, det) * MathUtils.radDeg;
-			return;
-		}
-		var pa:Number = parent.a, pb:Number = parent.b, pc:Number = parent.c, pd:Number = parent.d;
-		var pid:Number = 1 / (pa * pd - pb * pc);
-		var dx:Number = worldX - parent.worldX, dy:Number = worldY - parent.worldY;
-		x = (dx * pd * pid - dy * pb * pid);
-		y = (dy * pa * pid - dx * pc * pid);
-		var ia:Number = pid * pd;
-		var id:Number = pid * pa;
-		var ib:Number = pid * pb;
-		var ic:Number = pid * pc;
-		var ra:Number = ia * a - ib * c;
-		var rb:Number = ia * b - ib * d;
-		var rc:Number = id * c - ic * a;
-		var rd:Number = id * d - ic * b;
-		shearX = 0;
-		scaleX = Math.sqrt(ra * ra + rc * rc);
-		if (scaleX > 0.0001) {
-			det = ra * rd - rb * rc;
-			scaleY = det / scaleX;
-			shearY = Math.atan2(ra * rb + rc * rd, det) * MathUtils.radDeg;
-			rotation = Math.atan2(rc, ra) * MathUtils.radDeg;
-		} else {
-			scaleX = 0;
-			scaleY = Math.sqrt(rb * rb + rd * rd);
-			shearY = 0;
-			rotation = 90 - Math.atan2(rd, rb) * MathUtils.radDeg;
-		}
-		appliedRotation = rotation;
-	}
-
-	public function worldToLocal (world:Vector.<Number>) : void {
-		var a:Number = _a, b:Number = _b, c:Number = _c, d:Number = _d;
-		var invDet:Number = 1 / (a * d - b * c);
-		var x:Number = world[0] - _worldX, y:Number = world[1] - _worldY;				
-		world[0] = (x * d * invDet - y * b * invDet);
-		world[1] = (y * a * invDet - x * c * invDet);
-	}
-
-	public function localToWorld (local:Vector.<Number>) : void {
-		var localX:Number = local[0], localY:Number = local[1];
-		local[0] = localX * _a + localY * _b + _worldX;
-		local[1] = localX * _c + localY * _d + _worldY;
-	}
-
-	public function toString () : String {
-		return _data._name;
-	}
-}
-
+package spine {
+
+public class Bone implements Updatable {
+	static public var yDown:Boolean;
+
+	internal var _data:BoneData;
+	internal var _skeleton:Skeleton;
+	internal var _parent:Bone;
+	internal var _children:Vector.<Bone> = new Vector.<Bone>();
+	public var x:Number;
+	public var y:Number;
+	public var rotation:Number;
+	public var scaleX:Number;
+	public var scaleY:Number;
+	public var shearX:Number;
+	public var shearY:Number;
+	public var appliedRotation:Number;	
+
+	internal var _a:Number;
+	internal var _b:Number;
+	internal var _c:Number;
+	internal var _d:Number;
+	internal var _worldX:Number;
+	internal var _worldY:Number;
+	internal var _worldSignX:Number;
+	internal var _worldSignY:Number;
+	
+	internal var _sorted:Boolean;
+
+	/** @param parent May be null. */
+	public function Bone (data:BoneData, skeleton:Skeleton, parent:Bone) {
+		if (data == null) throw new ArgumentError("data cannot be null.");
+		if (skeleton == null) throw new ArgumentError("skeleton cannot be null.");
+		_data = data;
+		_skeleton = skeleton;
+		_parent = parent;
+		setToSetupPose();
+	}
+	
+	/** Same as updateWorldTransform(). This method exists for Bone to implement Updatable. */
+	public function update () : void {
+		updateWorldTransformWith(x, y, rotation, scaleX, scaleY, shearX, shearY);
+	}
+
+	/** Computes the world SRT using the parent bone and this bone's local SRT. */
+	public function updateWorldTransform () : void {
+		updateWorldTransformWith(x, y, rotation, scaleX, scaleY, shearX, shearY);
+	}
+
+	/** Computes the world SRT using the parent bone and the specified local SRT. */
+	public function updateWorldTransformWith (x:Number, y:Number, rotation:Number, scaleX:Number, scaleY:Number, shearX:Number, shearY:Number) : void {
+		appliedRotation = rotation;
+
+		var rotationY:Number = rotation + 90 + shearY;
+		var la:Number = MathUtils.cosDeg(rotation + shearX) * scaleX, lb:Number = MathUtils.cosDeg(rotationY) * scaleY;
+		var lc:Number = MathUtils.sinDeg(rotation + shearX) * scaleX, ld:Number = MathUtils.sinDeg(rotationY) * scaleY;
+		
+		var parent:Bone = _parent;
+		if (!parent) { // Root bone.
+			var skeleton:Skeleton = _skeleton;
+			if (skeleton.flipX) {
+				x = -x;
+				la = -la;
+				lb = -lb;
+			}
+			if (skeleton.flipY != yDown) {
+				y = -y;
+				lc = -lc;
+				ld = -ld;
+			}
+			_a = la;
+			_b = lb;
+			_c = lc;
+			_d = ld;
+			_worldX = x;
+			_worldY = y;
+			_worldSignX = scaleX < 0 ? -1 : 1;
+			_worldSignY = scaleY < 0 ? -1 : 1;
+			return;
+		}
+
+		var pa:Number = parent._a, pb:Number = parent._b, pc:Number = parent._c, pd:Number = parent._d;
+		_worldX = pa * x + pb * y + parent._worldX;
+		_worldY = pc * x + pd * y + parent._worldY;
+		_worldSignX = parent._worldSignX * (scaleX < 0 ? -1 : 1);
+		_worldSignY = parent._worldSignY * (scaleY < 0 ? -1 : 1);
+
+		if (data.inheritRotation && data.inheritScale) {
+			_a = pa * la + pb * lc;
+			_b = pa * lb + pb * ld;
+			_c = pc * la + pd * lc;
+			_d = pc * lb + pd * ld;
+		} else {
+			if (data.inheritRotation) { // No scale inheritance.
+				pa = 1;
+				pb = 0;
+				pc = 0;
+				pd = 1;
+				do {
+					var cos:Number = MathUtils.cosDeg(parent.appliedRotation), sin:Number = MathUtils.sinDeg(parent.appliedRotation);
+					var temp:Number = pa * cos + pb * sin;
+					pb = pb * cos - pa * sin;
+					pa = temp;
+					temp = pc * cos + pd * sin;
+					pd = pd * cos - pc * sin;
+					pc = temp;
+	
+					if (!parent.data.inheritRotation) break;
+					parent = parent.parent;
+				} while (parent != null);
+				_a = pa * la + pb * lc;
+				_b = pa * lb + pb * ld;
+				_c = pc * la + pd * lc;
+				_d = pc * lb + pd * ld;
+			} else if (data.inheritScale) { // No rotation inheritance.
+				pa = 1;
+				pb = 0;
+				pc = 0;
+				pd = 1;
+				do {
+					cos = MathUtils.cosDeg(parent.appliedRotation), sin = MathUtils.sinDeg(parent.appliedRotation);
+					var psx:Number = parent.scaleX, psy:Number = parent.scaleY;
+					var za:Number = cos * psx, zb:Number = sin * psy, zc:Number = sin * psx, zd:Number = cos * psy;
+					temp = pa * za + pb * zc;
+					pb = pb * zd - pa * zb;
+					pa = temp;
+					temp = pc * za + pd * zc;
+					pd = pd * zd - pc * zb;
+					pc = temp;
+
+					if (psx >= 0) sin = -sin;
+					temp = pa * cos + pb * sin;
+					pb = pb * cos - pa * sin;
+					pa = temp;
+					temp = pc * cos + pd * sin;
+					pd = pd * cos - pc * sin;
+					pc = temp;
+	
+					if (!parent.data.inheritScale) break;
+					parent = parent.parent;
+				} while (parent != null);
+				_a = pa * la + pb * lc;
+				_b = pa * lb + pb * ld;
+				_c = pc * la + pd * lc;
+				_d = pc * lb + pd * ld;
+			} else {
+				_a = la;
+				_b = lb;
+				_c = lc;
+				_d = ld;
+			}
+			if (_skeleton.flipX) {
+				_a = -_a;
+				_b = -_b;
+			}
+			if (_skeleton.flipY != yDown) {
+				_c = -_c;
+				_d = -_d;
+			}
+		}
+	}
+
+	public function setToSetupPose () : void {
+		x = _data.x;
+		y = _data.y;
+		rotation = _data.rotation;
+		scaleX = _data.scaleX;
+		scaleY = _data.scaleY;
+		shearX = _data.shearX;
+		shearY = _data.shearY;
+	}
+
+	public function get data () : BoneData {
+		return _data;
+	}
+	
+	public function get skeleton () : Skeleton {
+		return _skeleton;
+	}
+	
+	public function get parent () : Bone {
+		return _parent;
+	}
+	
+	public function get children () : Vector.<Bone> {;
+		return _children;
+	}
+
+	public function get a () : Number {
+		return _a;
+	}
+
+	public function get b () : Number {
+		return _b;
+	}
+
+	public function get c () : Number {
+		return _c;
+	}
+
+	public function get d () : Number {
+		return _d;
+	}
+
+	public function get worldX () : Number {
+		return _worldX;
+	}
+
+	public function get worldY () : Number {
+		return _worldY;
+	}
+
+	public function get worldSignX () : Number {
+		return _worldSignX;
+	}
+
+	public function get worldSignY () : Number {
+		return _worldSignY;
+	}
+
+	public function get worldRotationX () : Number {
+		return Math.atan2(_c, _a) * MathUtils.radDeg;
+	}
+
+	public function get worldRotationY () : Number {
+		return Math.atan2(_d, _b) * MathUtils.radDeg;
+	}
+
+	public function get worldScaleX () : Number {
+		return Math.sqrt(_a * _a + _b * _b) * _worldSignX;
+	}
+
+	public function get worldScaleY () : Number {
+		return Math.sqrt(_c * _c + _d * _d) * _worldSignY;
+	}
+	
+	public function worldToLocalRotationX () : Number {
+		var parent:Bone = _parent;
+		if (parent == null) return rotation;
+		var pa:Number = parent.a, pb:Number = parent.b, pc:Number = parent.c, pd:Number = parent.d, a:Number = this.a, c:Number = this.c;
+		return Math.atan2(pa * c - pc * a, pd * a - pb * c) * MathUtils.radDeg;
+	}
+
+	public function worldToLocalRotationY () : Number {
+		var parent:Bone = _parent;
+		if (parent == null) return rotation;
+		var pa:Number = parent.a, pb:Number = parent.b, pc:Number = parent.c, pd:Number = parent.d, b:Number = this.b, d:Number = this.d;
+		return Math.atan2(pa * d - pc * b, pd * b - pb * d) * MathUtils.radDeg;
+	}
+
+	public function rotateWorld (degrees:Number) : void {
+		var a:Number = this.a, b:Number = this.b, c:Number = this.c, d:Number = this.d;
+		var cos:Number = MathUtils.cosDeg(degrees), sin:Number = MathUtils.sinDeg(degrees);
+		this._a = cos * a - sin * c;
+		this._b = cos * b - sin * d;
+		this._c = sin * a + cos * c;
+		this._d = sin * b + cos * d;
+	}
+
+	/** Computes the local transform from the world transform. This can be useful to perform processing on the local transform
+	 * after the world transform has been modified directly (eg, by a constraint).
+	 * <p>
+	 * Some redundant information is lost by the world transform, such as -1,-1 scale versus 180 rotation. The computed local
+	 * transform values may differ from the original values but are functionally the same. */
+	public function updateLocalTransform () : void {
+		var parent:Bone = this.parent;
+		if (parent == null) {
+			x = worldX;
+			y = worldY;
+			rotation = Math.atan2(c, a) * MathUtils.radDeg;
+			scaleX = Math.sqrt(a * a + c * c);
+			scaleY = Math.sqrt(b * b + d * d);
+			var det:Number = a * d - b * c;
+			shearX = 0;
+			shearY = Math.atan2(a * b + c * d, det) * MathUtils.radDeg;
+			return;
+		}
+		var pa:Number = parent.a, pb:Number = parent.b, pc:Number = parent.c, pd:Number = parent.d;
+		var pid:Number = 1 / (pa * pd - pb * pc);
+		var dx:Number = worldX - parent.worldX, dy:Number = worldY - parent.worldY;
+		x = (dx * pd * pid - dy * pb * pid);
+		y = (dy * pa * pid - dx * pc * pid);
+		var ia:Number = pid * pd;
+		var id:Number = pid * pa;
+		var ib:Number = pid * pb;
+		var ic:Number = pid * pc;
+		var ra:Number = ia * a - ib * c;
+		var rb:Number = ia * b - ib * d;
+		var rc:Number = id * c - ic * a;
+		var rd:Number = id * d - ic * b;
+		shearX = 0;
+		scaleX = Math.sqrt(ra * ra + rc * rc);
+		if (scaleX > 0.0001) {
+			det = ra * rd - rb * rc;
+			scaleY = det / scaleX;
+			shearY = Math.atan2(ra * rb + rc * rd, det) * MathUtils.radDeg;
+			rotation = Math.atan2(rc, ra) * MathUtils.radDeg;
+		} else {
+			scaleX = 0;
+			scaleY = Math.sqrt(rb * rb + rd * rd);
+			shearY = 0;
+			rotation = 90 - Math.atan2(rd, rb) * MathUtils.radDeg;
+		}
+		appliedRotation = rotation;
+	}
+
+	public function worldToLocal (world:Vector.<Number>) : void {
+		var a:Number = _a, b:Number = _b, c:Number = _c, d:Number = _d;
+		var invDet:Number = 1 / (a * d - b * c);
+		var x:Number = world[0] - _worldX, y:Number = world[1] - _worldY;				
+		world[0] = (x * d * invDet - y * b * invDet);
+		world[1] = (y * a * invDet - x * c * invDet);
+	}
+
+	public function localToWorld (local:Vector.<Number>) : void {
+		var localX:Number = local[0], localY:Number = local[1];
+		local[0] = localX * _a + localY * _b + _worldX;
+		local[1] = localX * _c + localY * _d + _worldY;
+	}
+
+	public function toString () : String {
+		return _data._name;
+	}
+}
+
 }

+ 72 - 73
spine-as3/spine-as3/src/spine/BoneData.as

@@ -1,76 +1,75 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public class BoneData {
-	internal var _index:int;
-	internal var _name:String;
-	internal var _parent:BoneData;
-	public var length:Number;
-	public var x:Number;
-	public var y:Number;
-	public var rotation:Number;
-	public var scaleX:Number = 1;
-	public var scaleY:Number = 1;
-	public var shearX:Number;
-	public var shearY:Number;	
-	public var inheritRotation:Boolean = true;
-	public var inheritScale:Boolean = true;
-
-	/** @param parent May be null. */
-	public function BoneData (index:int, name:String, parent:BoneData) {
-		if (index < 0) throw new ArgumentError("index must be >= 0");
-		if (name == null) throw new ArgumentError("name cannot be null.");
-		_index = index;
-		_name = name;
-		_parent = parent;
-	}
-	
-	public function get index () : int {
-		return _index;
-	}
-
-	public function get name () : String {
-		return _name;
-	}
-
-	/** @return May be null. */
-	public function get parent () : BoneData {
-		return _parent;
-	}
-
-	public function toString () : String {
-		return _name;
-	}
-}
-
+package spine {
+
+public class BoneData {
+	internal var _index:int;
+	internal var _name:String;
+	internal var _parent:BoneData;
+	public var length:Number;
+	public var x:Number;
+	public var y:Number;
+	public var rotation:Number;
+	public var scaleX:Number = 1;
+	public var scaleY:Number = 1;
+	public var shearX:Number;
+	public var shearY:Number;	
+	public var inheritRotation:Boolean = true;
+	public var inheritScale:Boolean = true;
+
+	/** @param parent May be null. */
+	public function BoneData (index:int, name:String, parent:BoneData) {
+		if (index < 0) throw new ArgumentError("index must be >= 0");
+		if (name == null) throw new ArgumentError("name cannot be null.");
+		_index = index;
+		_name = name;
+		_parent = parent;
+	}
+	
+	public function get index () : int {
+		return _index;
+	}
+
+	public function get name () : String {
+		return _name;
+	}
+
+	/** @return May be null. */
+	public function get parent () : BoneData {
+		return _parent;
+	}
+
+	public function toString () : String {
+		return _name;
+	}
+}
+
 }

+ 52 - 53
spine-as3/spine-as3/src/spine/Event.as

@@ -1,56 +1,55 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public class Event {
-	internal var _data:EventData;
-	public var time:Number;
-	public var intValue:int;
-	public var floatValue:Number;
-	public var stringValue:String;
-
-	public function Event (time:Number, data:EventData) {
-		if (data == null) throw new ArgumentError("data cannot be null.");
-		this.time = time;
-		_data = data;
-	}
-
-	public function get data () : EventData {
-		return _data;
-	}
-
-	public function toString () : String {
-		return _data._name;
-	}
-}
-
+package spine {
+
+public class Event {
+	internal var _data:EventData;
+	public var time:Number;
+	public var intValue:int;
+	public var floatValue:Number;
+	public var stringValue:String;
+
+	public function Event (time:Number, data:EventData) {
+		if (data == null) throw new ArgumentError("data cannot be null.");
+		this.time = time;
+		_data = data;
+	}
+
+	public function get data () : EventData {
+		return _data;
+	}
+
+	public function toString () : String {
+		return _data._name;
+	}
+}
+
 }

+ 50 - 51
spine-as3/spine-as3/src/spine/EventData.as

@@ -1,54 +1,53 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public class EventData {
-	internal var _name:String;
-	public var intValue:int;;
-	public var floatValue:Number;
-	public var stringValue:String;
-	
-	public function EventData (name:String) {
-		if (name == null) throw new ArgumentError("name cannot be null.");
-		_name = name;
-	}
-
-	public function get name () : String {
-		return _name;
-	}
-
-	public function toString () : String {
-		return _name;
-	}
-}
-
+package spine {
+
+public class EventData {
+	internal var _name:String;
+	public var intValue:int;;
+	public var floatValue:Number;
+	public var stringValue:String;
+	
+	public function EventData (name:String) {
+		if (name == null) throw new ArgumentError("name cannot be null.");
+		_name = name;
+	}
+
+	public function get name () : String {
+		return _name;
+	}
+
+	public function toString () : String {
+		return _name;
+	}
+}
+
 }

+ 227 - 228
spine-as3/spine-as3/src/spine/IkConstraint.as

@@ -1,231 +1,230 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public class IkConstraint implements Updatable {
-	internal var _data:IkConstraintData;
-	public var bones:Vector.<Bone>;
-	public var target:Bone;
-	public var mix:Number;
-	public var bendDirection:int;
-	
-	public var level:int;	
-
-	public function IkConstraint (data:IkConstraintData, skeleton:Skeleton) {
-		if (data == null) throw new ArgumentError("data cannot be null.");
-		if (skeleton == null) throw new ArgumentError("skeleton cannot be null.");
-		_data = data;
-		mix = data.mix;
-		bendDirection = data.bendDirection;
-
-		bones = new Vector.<Bone>();
-		for each (var boneData:BoneData in data.bones)
-			bones[bones.length] = skeleton.findBone(boneData.name);
-		target = skeleton.findBone(data.target._name);
-	}
-
-	public function apply () : void {
-		update();
-	}
-
-	public function update () : void {
-		switch (bones.length) {
-		case 1:
-			apply1(bones[0], target._worldX, target._worldY, mix);
-			break;
-		case 2:
-			apply2(bones[0], bones[1], target._worldX, target._worldY, bendDirection, mix);
-			break;
-		}
-	}
-
-	public function get data () : IkConstraintData {
-		return _data;
-	}
-
-	public function toString () : String {
-		return _data._name;
-	}
-	
-	/** Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified in the world
-	 * coordinate system. */
-	static public function apply1 (bone:Bone, targetX:Number, targetY:Number, alpha:Number) : void {
-		var pp:Bone = bone.parent;
-		var id:Number = 1 / (pp.a * pp.d - pp.b * pp.c);
-		var x:Number = targetX - pp.worldX, y:Number = targetY - pp.worldY;
-		var tx:Number = (x * pp.d - y * pp.b) * id - bone.x, ty:Number = (y * pp.a - x * pp.c) * id - bone.y;
-		var rotationIK:Number = Math.atan2(ty, tx) * MathUtils.radDeg - bone.shearX - bone.rotation;
-		if (bone.scaleX < 0) rotationIK += 180;
-		if (rotationIK > 180)
-			rotationIK -= 360;
-		else if (rotationIK < -180) rotationIK += 360;
-		bone.updateWorldTransformWith(bone.x, bone.y, bone.rotation + rotationIK * alpha, bone.scaleX, bone.scaleY, bone.shearX,
-			bone.shearY);
-	}
-
-	/** Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as possible. The
-	 * target is specified in the world coordinate system.
-	 * @param child Any descendant bone of the parent. */
-	static public function apply2 (parent:Bone, child:Bone, targetX:Number, targetY:Number, bendDir:int, alpha:Number) : void {
-		if (alpha == 0) {
-			child.updateWorldTransform();
-			return;
-		}
-		var px:Number = parent.x, py:Number = parent.y, psx:Number = parent.scaleX, psy:Number = parent.scaleY, csx:Number = child.scaleX;;
-		var os1:int, os2:int, s2:int;
-		if (psx < 0) {
-			psx = -psx;
-			os1 = 180;
-			s2 = -1;
-		} else {
-			os1 = 0;
-			s2 = 1;
-		}
-		if (psy < 0) {
-			psy = -psy;
-			s2 = -s2;
-		}
-		if (csx < 0) {
-			csx = -csx;
-			os2 = 180;
-		} else
-			os2 = 0;
-		var cx:Number = child.x, cy:Number, cwx:Number, cwy:Number, a:Number = parent.a, b:Number = parent.b, c:Number = parent.c, d:Number = parent.d;
-		var u:Boolean = Math.abs(psx - psy) <= 0.0001;
-		if (!u) {
-			cy = 0;
-			cwx = a * cx + parent.worldX;
-			cwy = c * cx + parent.worldY;
-		} else {
-			cy = child.y;
-			cwx = a * cx + b * cy + parent.worldX;
-			cwy = c * cx + d * cy + parent.worldY;
-		}
-		var pp:Bone = parent.parent;
-		a = pp.a;
-		b = pp.b;
-		c = pp.c;
-		d = pp.d;
-		var id:Number = 1 / (a * d - b * c), x:Number = targetX - pp.worldX, y:Number = targetY - pp.worldY;
-		var tx:Number = (x * d - y * b) * id - px, ty:Number = (y * a - x * c) * id - py;
-		x = cwx - pp.worldX;
-		y = cwy - pp.worldY;
-		var dx:Number = (x * d - y * b) * id - px, dy:Number = (y * a - x * c) * id - py;
-		var l1:Number = Math.sqrt(dx * dx + dy * dy), l2:Number = child.data.length * csx, a1:Number, a2:Number;
-		outer:
-		if (u) {
-			l2 *= psx;
-			var cos:Number = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2);
-			if (cos < -1) 
-				cos = -1;
-			else if (cos > 1) cos = 1;
-			a2 = Math.acos(cos) * bendDir;
-			a = l1 + l2 * cos;
-			b = l2 * Math.sin(a2);
-			a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b);
-		} else {
-			a = psx * l2;
-			b = psy * l2;
-			var aa:Number = a * a, bb:Number = b * b, dd:Number = tx * tx + ty * ty, ta:Number = Math.atan2(ty, tx);
-			c = bb * l1 * l1 + aa * dd - aa * bb;
-			var c1:Number = -2 * bb * l1, c2:Number = bb - aa;
-			d = c1 * c1 - 4 * c2 * c;
-			if (d >= 0) {
-				var q:Number = Math.sqrt(d);
-				if (c1 < 0) q = -q;
-				q = -(c1 + q) / 2;
-				var r0:Number = q / c2, r1:Number = c / q;
-				var r:Number = Math.abs(r0) < Math.abs(r1) ? r0 : r1;
-				if (r * r <= dd) {
-					y = Math.sqrt(dd - r * r) * bendDir;
-					a1 = ta - Math.atan2(y, r);
-					a2 = Math.atan2(y / psy, (r - l1) / psx);
-					break outer;
-				}
-			}
-			var minAngle:Number = 0, minDist:Number = Number.MAX_VALUE, minX:Number = 0, minY:Number = 0;
-			var maxAngle:Number = 0, maxDist:Number = 0, maxX:Number = 0, maxY:Number = 0;
-			x = l1 + a;
-			d = x * x;
-			if (d > maxDist) {
-				maxAngle = 0;
-				maxDist = d;
-				maxX = x;
-			}
-			x = l1 - a;
-			d = x * x;
-			if (d < minDist) {
-				minAngle = Math.PI;
-				minDist = d;
-				minX = x;
-			}
-			var angle:Number = Math.acos(-a * l1 / (aa - bb));
-			x = a * Math.cos(angle) + l1;
-			y = b * Math.sin(angle);
-			d = x * x + y * y;
-			if (d < minDist) {
-				minAngle = angle;
-				minDist = d;
-				minX = x;
-				minY = y;
-			}
-			if (d > maxDist) {
-				maxAngle = angle;
-				maxDist = d;
-				maxX = x;
-				maxY = y;
-			}
-			if (dd <= (minDist + maxDist) / 2) {
-				a1 = ta - Math.atan2(minY * bendDir, minX);
-				a2 = minAngle * bendDir;
-			} else {
-				a1 = ta - Math.atan2(maxY * bendDir, maxX);
-				a2 = maxAngle * bendDir;
-			}
-		}
-		var os:Number = Math.atan2(cy, cx) * s2;
-		var rotation:Number = parent.rotation;
-		a1 = (a1 - os) * MathUtils.radDeg + os1 - rotation;
-		if (a1 > 180)
-			a1 -= 360;
-		else if (a1 < -180) a1 += 360;
-		parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, parent.scaleX, parent.scaleY, 0, 0);
-		rotation = child.rotation;
-		a2 = ((a2 + os) * MathUtils.radDeg - child.shearX) * s2 + os2 - rotation;
-		if (a2 > 180)
-			a2 -= 360;
-		else if (a2 < -180) a2 += 360;
-		child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.scaleX, child.scaleY, child.shearX, child.shearY);
-	}
-}
-
+package spine {
+
+public class IkConstraint implements Updatable {
+	internal var _data:IkConstraintData;
+	public var bones:Vector.<Bone>;
+	public var target:Bone;
+	public var mix:Number;
+	public var bendDirection:int;
+	
+	public var level:int;	
+
+	public function IkConstraint (data:IkConstraintData, skeleton:Skeleton) {
+		if (data == null) throw new ArgumentError("data cannot be null.");
+		if (skeleton == null) throw new ArgumentError("skeleton cannot be null.");
+		_data = data;
+		mix = data.mix;
+		bendDirection = data.bendDirection;
+
+		bones = new Vector.<Bone>();
+		for each (var boneData:BoneData in data.bones)
+			bones[bones.length] = skeleton.findBone(boneData.name);
+		target = skeleton.findBone(data.target._name);
+	}
+
+	public function apply () : void {
+		update();
+	}
+
+	public function update () : void {
+		switch (bones.length) {
+		case 1:
+			apply1(bones[0], target._worldX, target._worldY, mix);
+			break;
+		case 2:
+			apply2(bones[0], bones[1], target._worldX, target._worldY, bendDirection, mix);
+			break;
+		}
+	}
+
+	public function get data () : IkConstraintData {
+		return _data;
+	}
+
+	public function toString () : String {
+		return _data._name;
+	}
+	
+	/** Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified in the world
+	 * coordinate system. */
+	static public function apply1 (bone:Bone, targetX:Number, targetY:Number, alpha:Number) : void {
+		var pp:Bone = bone.parent;
+		var id:Number = 1 / (pp.a * pp.d - pp.b * pp.c);
+		var x:Number = targetX - pp.worldX, y:Number = targetY - pp.worldY;
+		var tx:Number = (x * pp.d - y * pp.b) * id - bone.x, ty:Number = (y * pp.a - x * pp.c) * id - bone.y;
+		var rotationIK:Number = Math.atan2(ty, tx) * MathUtils.radDeg - bone.shearX - bone.rotation;
+		if (bone.scaleX < 0) rotationIK += 180;
+		if (rotationIK > 180)
+			rotationIK -= 360;
+		else if (rotationIK < -180) rotationIK += 360;
+		bone.updateWorldTransformWith(bone.x, bone.y, bone.rotation + rotationIK * alpha, bone.scaleX, bone.scaleY, bone.shearX,
+			bone.shearY);
+	}
+
+	/** Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as possible. The
+	 * target is specified in the world coordinate system.
+	 * @param child Any descendant bone of the parent. */
+	static public function apply2 (parent:Bone, child:Bone, targetX:Number, targetY:Number, bendDir:int, alpha:Number) : void {
+		if (alpha == 0) {
+			child.updateWorldTransform();
+			return;
+		}
+		var px:Number = parent.x, py:Number = parent.y, psx:Number = parent.scaleX, psy:Number = parent.scaleY, csx:Number = child.scaleX;;
+		var os1:int, os2:int, s2:int;
+		if (psx < 0) {
+			psx = -psx;
+			os1 = 180;
+			s2 = -1;
+		} else {
+			os1 = 0;
+			s2 = 1;
+		}
+		if (psy < 0) {
+			psy = -psy;
+			s2 = -s2;
+		}
+		if (csx < 0) {
+			csx = -csx;
+			os2 = 180;
+		} else
+			os2 = 0;
+		var cx:Number = child.x, cy:Number, cwx:Number, cwy:Number, a:Number = parent.a, b:Number = parent.b, c:Number = parent.c, d:Number = parent.d;
+		var u:Boolean = Math.abs(psx - psy) <= 0.0001;
+		if (!u) {
+			cy = 0;
+			cwx = a * cx + parent.worldX;
+			cwy = c * cx + parent.worldY;
+		} else {
+			cy = child.y;
+			cwx = a * cx + b * cy + parent.worldX;
+			cwy = c * cx + d * cy + parent.worldY;
+		}
+		var pp:Bone = parent.parent;
+		a = pp.a;
+		b = pp.b;
+		c = pp.c;
+		d = pp.d;
+		var id:Number = 1 / (a * d - b * c), x:Number = targetX - pp.worldX, y:Number = targetY - pp.worldY;
+		var tx:Number = (x * d - y * b) * id - px, ty:Number = (y * a - x * c) * id - py;
+		x = cwx - pp.worldX;
+		y = cwy - pp.worldY;
+		var dx:Number = (x * d - y * b) * id - px, dy:Number = (y * a - x * c) * id - py;
+		var l1:Number = Math.sqrt(dx * dx + dy * dy), l2:Number = child.data.length * csx, a1:Number, a2:Number;
+		outer:
+		if (u) {
+			l2 *= psx;
+			var cos:Number = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2);
+			if (cos < -1) 
+				cos = -1;
+			else if (cos > 1) cos = 1;
+			a2 = Math.acos(cos) * bendDir;
+			a = l1 + l2 * cos;
+			b = l2 * Math.sin(a2);
+			a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b);
+		} else {
+			a = psx * l2;
+			b = psy * l2;
+			var aa:Number = a * a, bb:Number = b * b, dd:Number = tx * tx + ty * ty, ta:Number = Math.atan2(ty, tx);
+			c = bb * l1 * l1 + aa * dd - aa * bb;
+			var c1:Number = -2 * bb * l1, c2:Number = bb - aa;
+			d = c1 * c1 - 4 * c2 * c;
+			if (d >= 0) {
+				var q:Number = Math.sqrt(d);
+				if (c1 < 0) q = -q;
+				q = -(c1 + q) / 2;
+				var r0:Number = q / c2, r1:Number = c / q;
+				var r:Number = Math.abs(r0) < Math.abs(r1) ? r0 : r1;
+				if (r * r <= dd) {
+					y = Math.sqrt(dd - r * r) * bendDir;
+					a1 = ta - Math.atan2(y, r);
+					a2 = Math.atan2(y / psy, (r - l1) / psx);
+					break outer;
+				}
+			}
+			var minAngle:Number = 0, minDist:Number = Number.MAX_VALUE, minX:Number = 0, minY:Number = 0;
+			var maxAngle:Number = 0, maxDist:Number = 0, maxX:Number = 0, maxY:Number = 0;
+			x = l1 + a;
+			d = x * x;
+			if (d > maxDist) {
+				maxAngle = 0;
+				maxDist = d;
+				maxX = x;
+			}
+			x = l1 - a;
+			d = x * x;
+			if (d < minDist) {
+				minAngle = Math.PI;
+				minDist = d;
+				minX = x;
+			}
+			var angle:Number = Math.acos(-a * l1 / (aa - bb));
+			x = a * Math.cos(angle) + l1;
+			y = b * Math.sin(angle);
+			d = x * x + y * y;
+			if (d < minDist) {
+				minAngle = angle;
+				minDist = d;
+				minX = x;
+				minY = y;
+			}
+			if (d > maxDist) {
+				maxAngle = angle;
+				maxDist = d;
+				maxX = x;
+				maxY = y;
+			}
+			if (dd <= (minDist + maxDist) / 2) {
+				a1 = ta - Math.atan2(minY * bendDir, minX);
+				a2 = minAngle * bendDir;
+			} else {
+				a1 = ta - Math.atan2(maxY * bendDir, maxX);
+				a2 = maxAngle * bendDir;
+			}
+		}
+		var os:Number = Math.atan2(cy, cx) * s2;
+		var rotation:Number = parent.rotation;
+		a1 = (a1 - os) * MathUtils.radDeg + os1 - rotation;
+		if (a1 > 180)
+			a1 -= 360;
+		else if (a1 < -180) a1 += 360;
+		parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, parent.scaleX, parent.scaleY, 0, 0);
+		rotation = child.rotation;
+		a2 = ((a2 + os) * MathUtils.radDeg - child.shearX) * s2 + os2 - rotation;
+		if (a2 > 180)
+			a2 -= 360;
+		else if (a2 < -180) a2 += 360;
+		child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.scaleX, child.scaleY, child.shearX, child.shearY);
+	}
+}
+
 }

+ 51 - 52
spine-as3/spine-as3/src/spine/IkConstraintData.as

@@ -1,55 +1,54 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public class IkConstraintData {
-	internal var _name:String;
-	public var bones:Vector.<BoneData> = new Vector.<BoneData>();
-	public var target:BoneData;
-	public var bendDirection:int = 1;
-	public var mix:Number = 1;
-
-	public function IkConstraintData (name:String) {
-		if (name == null) throw new ArgumentError("name cannot be null.");
-		_name = name;
-	}
-
-	public function get name () : String {
-		return _name;
-	}
-
-	public function toString () : String {
-		return _name;
-	}
-}
-
+package spine {
+
+public class IkConstraintData {
+	internal var _name:String;
+	public var bones:Vector.<BoneData> = new Vector.<BoneData>();
+	public var target:BoneData;
+	public var bendDirection:int = 1;
+	public var mix:Number = 1;
+
+	public function IkConstraintData (name:String) {
+		if (name == null) throw new ArgumentError("name cannot be null.");
+		_name = name;
+	}
+
+	public function get name () : String {
+		return _name;
+	}
+
+	public function toString () : String {
+		return _name;
+	}
+}
+
 }

+ 49 - 50
spine-as3/spine-as3/src/spine/MathUtils.as

@@ -1,53 +1,52 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public class MathUtils {
-	static public var radDeg:Number = 180 / Math.PI;
-	static public var degRad:Number = Math.PI / 180;
-	
-	static public function cosDeg(degrees:Number): Number {
-		return Math.cos(degrees * degRad);
-	}
-	
-	static public function sinDeg(degrees:Number): Number {
-		return Math.sin(degrees * degRad);
-	}
-	
-	static public function clamp (value:Number, min:Number, max:Number) : Number {
-		if (value < min) return min;
-		if (value > max) return max;
-		return value;
-	}
-}
-
+package spine {
+
+public class MathUtils {
+	static public var radDeg:Number = 180 / Math.PI;
+	static public var degRad:Number = Math.PI / 180;
+	
+	static public function cosDeg(degrees:Number): Number {
+		return Math.cos(degrees * degRad);
+	}
+	
+	static public function sinDeg(degrees:Number): Number {
+		return Math.sin(degrees * degRad);
+	}
+	
+	static public function clamp (value:Number, min:Number, max:Number) : Number {
+		if (value < min) return min;
+		if (value > max) return max;
+		return value;
+	}
+}
+
 }

+ 416 - 417
spine-as3/spine-as3/src/spine/PathConstraint.as

@@ -1,420 +1,419 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-import spine.attachments.PathAttachment;
-
-public class PathConstraint implements Updatable {
-	private static const NONE:int = -1, BEFORE:int = -2, AFTER:int = -3;
-
-	internal var _data:PathConstraintData;
-	internal var _bones:Vector.<Bone>;
-	public var target:Slot;
-	public var position:Number, spacing:Number, rotateMix:Number, translateMix:Number;
-
-	internal const _spaces:Vector.<Number> = new Vector.<Number>();
-	internal const _positions:Vector.<Number> = new Vector.<Number>();
-	internal const _world:Vector.<Number> = new Vector.<Number>();
-	internal const _curves:Vector.<Number> = new Vector.<Number>();
-	internal const _lengths:Vector.<Number> = new Vector.<Number>();
-	internal const _segments:Vector.<Number> = new Vector.<Number>(10);	
-
-	public function PathConstraint (data:PathConstraintData, skeleton:Skeleton) {
-		if (data == null) throw new ArgumentError("data cannot be null.");
-		if (skeleton == null) throw new ArgumentError("skeleton cannot be null.");
-		_data = data;
-		_bones = new Vector.<Bone>();		
-		for each (var boneData:BoneData in data.bones)
-			_bones.push(skeleton.findBone(boneData.name));
-		target = skeleton.findSlot(data.target.name);
-		position = data.position;
-		spacing = data.spacing;
-		rotateMix = data.rotateMix;
-		translateMix = data.translateMix;
-	}
-
-	public function apply () : void {
-		update();
-	}
-	
-	public function update () : void {
-		var attachment:PathAttachment = target.attachment as PathAttachment;
-		if (attachment == null) return;		
-
-		var rotateMix:Number = this.rotateMix, translateMix:Number = this.translateMix;
-		var translate:Boolean = translateMix > 0, rotate:Boolean = rotateMix > 0;
-		if (!translate && !rotate) return;
-
-		var data:PathConstraintData = this._data;
-		var spacingMode:SpacingMode = data.spacingMode;
-		var lengthSpacing:Boolean = spacingMode == SpacingMode.length;
-		var rotateMode:RotateMode = data.rotateMode;
-		var tangents:Boolean = rotateMode == RotateMode.tangent, scale:Boolean = rotateMode == RotateMode.chainScale;
-		var boneCount:int = this._bones.length, spacesCount:int = tangents ? boneCount : boneCount + 1;
-		var bones:Vector.<Bone> = this._bones;
-		this._spaces.length = spacesCount;
-		var spaces:Vector.<Number> = this._spaces, lengths:Vector.<Number> = null;
-		var spacing:Number = this.spacing;
-		if (scale || lengthSpacing) {
-			if (scale) {
-				this._lengths.length = boneCount;
-				lengths = this._lengths;
-			}
-			for (var i:int = 0, n:int = spacesCount - 1; i < n;) {
-				var bone:Bone = bones[i];
-				var length:Number = bone.data.length, x:Number = length * bone.a, y:Number = length * bone.c;
-				length = Math.sqrt(x * x + y * y);
-				if (scale) lengths[i] = length;
-				spaces[++i] = lengthSpacing ? Math.max(0, length + spacing) : spacing;
-			}
-		} else {
-			for (i = 1; i < spacesCount; i++)
-				spaces[i] = spacing;
-		}
-
-		var positions:Vector.<Number> = computeWorldPositions(attachment, spacesCount, tangents,
-			data.positionMode == PositionMode.percent, spacingMode == SpacingMode.percent);
-		var skeleton:Skeleton = target.skeleton;
-		var skeletonX:Number = skeleton.x, skeletonY:Number = skeleton.y;
-		var boneX:Number = positions[0], boneY:Number = positions[1], offsetRotation:Number = data.offsetRotation;
-		var tip:Boolean = rotateMode == RotateMode.chain && offsetRotation == 0;
-		var p:Number;
-		for (i = 0, p = 3; i < boneCount; i++, p += 3) {
-			bone = bones[i];
-			bone._worldX += (boneX - skeletonX - bone.worldX) * translateMix;
-			bone._worldY += (boneY - skeletonY - bone.worldY) * translateMix;
-			x = positions[p]; y = positions[p + 1]; var dx:Number = x - boneX, dy:Number = y - boneY;
-			if (scale) {
-				length = lengths[i];
-				if (length != 0) {
-					var s:Number = (Math.sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1;
-					bone._a *= s;
-					bone._c *= s;
-				}
-			}
-			boneX = x;
-			boneY = y;
-			if (rotate) {
-				var a:Number = bone.a, b:Number = bone.b, c:Number = bone.c, d:Number = bone.d, r:Number, cos:Number, sin:Number;
-				if (tangents)
-					r = positions[p - 1];
-				else if (spaces[i + 1] == 0)
-					r = positions[p + 2];
-				else
-					r = Math.atan2(dy, dx);
-				r -= Math.atan2(c, a) - offsetRotation * MathUtils.degRad;
-				if (tip) {
-					cos = Math.cos(r);
-					sin = Math.sin(r);
-					length = bone.data.length;
-					boneX += (length * (cos * a - sin * c) - dx) * rotateMix;
-					boneY += (length * (sin * a + cos * c) - dy) * rotateMix;
-				}
-				if (r > Math.PI)
-					r -= (Math.PI * 2);
-				else if (r < -Math.PI) //
-					r += (Math.PI * 2);
-				r *= rotateMix;
-				cos = Math.cos(r);
-				sin = Math.sin(r);
-				bone._a = cos * a - sin * c;
-				bone._b = cos * b - sin * d;
-				bone._c = sin * a + cos * c;
-				bone._d = sin * b + cos * d;
-			}
-		}
-	}
-
-	protected function computeWorldPositions (path:PathAttachment, spacesCount:int, tangents:Boolean, percentPosition:Boolean,
-		percentSpacing:Boolean) : Vector.<Number> {
-		var target:Slot = this.target;
-		var position:Number = this.position;
-		var spaces:Vector.<Number> = this._spaces;
-		this._positions.length = spacesCount * 3 + 2;
-		var out:Vector.<Number> = this._positions, world:Vector.<Number>;
-		var closed:Boolean = path.closed;
-		var verticesLength:int = path.worldVerticesLength, curveCount:int = verticesLength / 6, prevCurve:int = NONE;
-
-		if (!path.constantSpeed) {
-			var lengths:Vector.<Number> = path.lengths;
-			curveCount -= closed ? 1 : 2;
-			var pathLength:Number = lengths[curveCount];
-			if (percentPosition) position *= pathLength;
-			if (percentSpacing) {
-				for (var i:int = 0; i < spacesCount; i++)
-					spaces[i] *= pathLength;
-			}
-			this._world.length = 8;
-			world = this._world;
-			var o:int, curve:int; 
-			for (i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) {
-				var space:Number = spaces[i];
-				position += space;
-				var p:Number = position;
-
-				if (closed) {
-					p %= pathLength;
-					if (p < 0) p += pathLength;
-					curve = 0;
-				} else if (p < 0) {
-					if (prevCurve != BEFORE) {
-						prevCurve = BEFORE;
-						path.computeWorldVertices2(target, 2, 4, world, 0);
-					}
-					addBeforePosition(p, world, 0, out, o);
-					continue;
-				} else if (p > pathLength) {
-					if (prevCurve != AFTER) {
-						prevCurve = AFTER;
-						path.computeWorldVertices2(target, verticesLength - 6, 4, world, 0);
-					}
-					addAfterPosition(p - pathLength, world, 0, out, o);
-					continue;
-				}
-
-				// Determine curve containing position.
-				for (;; curve++) {
-					var length:Number = lengths[curve];
-					if (p > length) continue;
-					if (curve == 0)
-						p /= length;
-					else {
-						var prev:Number = lengths[curve - 1];
-						p = (p - prev) / (length - prev);
-					}
-					break;
-				}
-				if (curve != prevCurve) {
-					prevCurve = curve;
-					if (closed && curve == curveCount) {
-						path.computeWorldVertices2(target, verticesLength - 4, 4, world, 0);
-						path.computeWorldVertices2(target, 0, 4, world, 4);
-					} else
-						path.computeWorldVertices2(target, curve * 6 + 2, 8, world, 0);
-				}
-				addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o,
-					tangents || (i > 0 && space == 0));
-			}
-			return out;
-		}
-
-		// World vertices.
-		if (closed) {
-			verticesLength += 2;
-			this._world.length = verticesLength;
-			world = this._world;
-			path.computeWorldVertices2(target, 2, verticesLength - 4, world, 0);
-			path.computeWorldVertices2(target, 0, 2, world, verticesLength - 4);
-			world[verticesLength - 2] = world[0];
-			world[verticesLength - 1] = world[1];
-		} else {
-			curveCount--;
-			verticesLength -= 4;
-			this._world.length = verticesLength;
-			world = this._world;
-			path.computeWorldVertices2(target, 2, verticesLength, world, 0);
-		}
-
-		// Curve lengths.
-		this._curves.length = curveCount;
-		var curves:Vector.<Number> = this._curves;
-		pathLength = 0;
-		var x1:Number = world[0], y1:Number = world[1], cx1:Number = 0, cy1:Number = 0, cx2:Number = 0, cy2:Number = 0, x2:Number = 0, y2:Number = 0;
-		var tmpx:Number, tmpy:Number, dddfx:Number, dddfy:Number, ddfx:Number, ddfy:Number, dfx:Number, dfy:Number;
-		var w:int;
-		for (i = 0, w = 2; i < curveCount; i++, w += 6) {
-			cx1 = world[w];
-			cy1 = world[w + 1];
-			cx2 = world[w + 2];
-			cy2 = world[w + 3];
-			x2 = world[w + 4];
-			y2 = world[w + 5];
-			tmpx = (x1 - cx1 * 2 + cx2) * 0.1875;
-			tmpy = (y1 - cy1 * 2 + cy2) * 0.1875;
-			dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375;
-			dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375;
-			ddfx = tmpx * 2 + dddfx;
-			ddfy = tmpy * 2 + dddfy;
-			dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667;
-			dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667;
-			pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
-			dfx += ddfx;
-			dfy += ddfy;
-			ddfx += dddfx;
-			ddfy += dddfy;
-			pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
-			dfx += ddfx;
-			dfy += ddfy;
-			pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
-			dfx += ddfx + dddfx;
-			dfy += ddfy + dddfy;
-			pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
-			curves[i] = pathLength;
-			x1 = x2;
-			y1 = y2;
-		}
-		if (percentPosition) position *= pathLength;
-		if (percentSpacing) {
-			for (i = 0; i < spacesCount; i++)
-				spaces[i] *= pathLength;
-		}
-
-		var segments:Vector.<Number> = this._segments;
-		var curveLength:Number = 0;
-		var segment:int;
-		for (i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) {
-			space = spaces[i];
-			position += space;
-			p = position;
-
-			if (closed) {
-				p %= pathLength;
-				if (p < 0) p += pathLength;
-				curve = 0;
-			} else if (p < 0) {
-				addBeforePosition(p, world, 0, out, o);
-				continue;
-			} else if (p > pathLength) {
-				addAfterPosition(p - pathLength, world, verticesLength - 4, out, o);
-				continue;
-			}
-
-			// Determine curve containing position.
-			for (;; curve++) {
-				length = curves[curve];
-				if (p > length) continue;
-				if (curve == 0)
-					p /= length;
-				else {
-					prev = curves[curve - 1];
-					p = (p - prev) / (length - prev);
-				}
-				break;
-			}
-
-			// Curve segment lengths.
-			if (curve != prevCurve) {
-				prevCurve = curve;
-				var ii:int = curve * 6;
-				x1 = world[ii];
-				y1 = world[ii + 1];
-				cx1 = world[ii + 2];
-				cy1 = world[ii + 3];
-				cx2 = world[ii + 4];
-				cy2 = world[ii + 5];
-				x2 = world[ii + 6];
-				y2 = world[ii + 7];
-				tmpx = (x1 - cx1 * 2 + cx2) * 0.03;
-				tmpy = (y1 - cy1 * 2 + cy2) * 0.03;
-				dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006;
-				dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006;
-				ddfx = tmpx * 2 + dddfx;
-				ddfy = tmpy * 2 + dddfy;
-				dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667;
-				dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667;
-				curveLength = Math.sqrt(dfx * dfx + dfy * dfy);
-				segments[0] = curveLength;
-				for (ii = 1; ii < 8; ii++) {
-					dfx += ddfx;
-					dfy += ddfy;
-					ddfx += dddfx;
-					ddfy += dddfy;
-					curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
-					segments[ii] = curveLength;
-				}
-				dfx += ddfx;
-				dfy += ddfy;
-				curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
-				segments[8] = curveLength;
-				dfx += ddfx + dddfx;
-				dfy += ddfy + dddfy;
-				curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
-				segments[9] = curveLength;
-				segment = 0;
-			}
-
-			// Weight by segment length.
-			p *= curveLength;
-			for (;; segment++) {
-				length = segments[segment];
-				if (p > length) continue;
-				if (segment == 0)
-					p /= length;
-				else {
-					prev = segments[segment - 1];
-					p = segment + (p - prev) / (length - prev);
-				}
-				break;
-			}
-			addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0));
-		}
-		return out;
-	}
-
-	private function addBeforePosition (p:Number, temp:Vector.<Number>, i:int, out:Vector.<Number>, o:int) : void {
-		var x1:Number = temp[i], y1:Number = temp[i + 1], dx:Number = temp[i + 2] - x1, dy:Number = temp[i + 3] - y1, r:Number = Math.atan2(dy, dx);
-		out[o] = x1 + p * Math.cos(r);
-		out[o + 1] = y1 + p * Math.sin(r);
-		out[o + 2] = r;
-	}
-
-	private function addAfterPosition (p:Number, temp:Vector.<Number>, i:int, out:Vector.<Number>, o:int) : void {
-		var x1:Number = temp[i + 2], y1:Number = temp[i + 3], dx:Number = x1 - temp[i], dy:Number = y1 - temp[i + 1], r:Number = Math.atan2(dy, dx);
-		out[o] = x1 + p * Math.cos(r);
-		out[o + 1] = y1 + p * Math.sin(r);
-		out[o + 2] = r;
-	}
-
-	private function addCurvePosition (p:Number, x1:Number, y1:Number, cx1:Number, cy1:Number, cx2:Number, cy2:Number, x2:Number, y2:Number,
-		out:Vector.<Number>, o:int, tangents:Boolean) : void {
-		if (p == 0) p = 0.0001;
-		var tt:Number = p * p, ttt:Number = tt * p, u:Number = 1 - p, uu:Number = u * u, uuu:Number = uu * u;
-		var ut:Number = u * p, ut3:Number = ut * 3, uut3:Number = u * ut3, utt3:Number = ut3 * p;
-		var x:Number = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y:Number = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt;
-		out[o] = x;
-		out[o + 1] = y;
-		if (tangents) out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
-	}
-
-	public function get bones () : Vector.<Bone> {
-		return _bones;
-	}
-	
-	public function get data () : PathConstraintData {
-		return _data;
-	}
-
-	public function toString () : String {
-		return _data.name;
-	}
-}
-
+package spine {
+import spine.attachments.PathAttachment;
+
+public class PathConstraint implements Updatable {
+	private static const NONE:int = -1, BEFORE:int = -2, AFTER:int = -3;
+
+	internal var _data:PathConstraintData;
+	internal var _bones:Vector.<Bone>;
+	public var target:Slot;
+	public var position:Number, spacing:Number, rotateMix:Number, translateMix:Number;
+
+	internal const _spaces:Vector.<Number> = new Vector.<Number>();
+	internal const _positions:Vector.<Number> = new Vector.<Number>();
+	internal const _world:Vector.<Number> = new Vector.<Number>();
+	internal const _curves:Vector.<Number> = new Vector.<Number>();
+	internal const _lengths:Vector.<Number> = new Vector.<Number>();
+	internal const _segments:Vector.<Number> = new Vector.<Number>(10);	
+
+	public function PathConstraint (data:PathConstraintData, skeleton:Skeleton) {
+		if (data == null) throw new ArgumentError("data cannot be null.");
+		if (skeleton == null) throw new ArgumentError("skeleton cannot be null.");
+		_data = data;
+		_bones = new Vector.<Bone>();		
+		for each (var boneData:BoneData in data.bones)
+			_bones.push(skeleton.findBone(boneData.name));
+		target = skeleton.findSlot(data.target.name);
+		position = data.position;
+		spacing = data.spacing;
+		rotateMix = data.rotateMix;
+		translateMix = data.translateMix;
+	}
+
+	public function apply () : void {
+		update();
+	}
+	
+	public function update () : void {
+		var attachment:PathAttachment = target.attachment as PathAttachment;
+		if (attachment == null) return;		
+
+		var rotateMix:Number = this.rotateMix, translateMix:Number = this.translateMix;
+		var translate:Boolean = translateMix > 0, rotate:Boolean = rotateMix > 0;
+		if (!translate && !rotate) return;
+
+		var data:PathConstraintData = this._data;
+		var spacingMode:SpacingMode = data.spacingMode;
+		var lengthSpacing:Boolean = spacingMode == SpacingMode.length;
+		var rotateMode:RotateMode = data.rotateMode;
+		var tangents:Boolean = rotateMode == RotateMode.tangent, scale:Boolean = rotateMode == RotateMode.chainScale;
+		var boneCount:int = this._bones.length, spacesCount:int = tangents ? boneCount : boneCount + 1;
+		var bones:Vector.<Bone> = this._bones;
+		this._spaces.length = spacesCount;
+		var spaces:Vector.<Number> = this._spaces, lengths:Vector.<Number> = null;
+		var spacing:Number = this.spacing;
+		if (scale || lengthSpacing) {
+			if (scale) {
+				this._lengths.length = boneCount;
+				lengths = this._lengths;
+			}
+			for (var i:int = 0, n:int = spacesCount - 1; i < n;) {
+				var bone:Bone = bones[i];
+				var length:Number = bone.data.length, x:Number = length * bone.a, y:Number = length * bone.c;
+				length = Math.sqrt(x * x + y * y);
+				if (scale) lengths[i] = length;
+				spaces[++i] = lengthSpacing ? Math.max(0, length + spacing) : spacing;
+			}
+		} else {
+			for (i = 1; i < spacesCount; i++)
+				spaces[i] = spacing;
+		}
+
+		var positions:Vector.<Number> = computeWorldPositions(attachment, spacesCount, tangents,
+			data.positionMode == PositionMode.percent, spacingMode == SpacingMode.percent);
+		var skeleton:Skeleton = target.skeleton;
+		var skeletonX:Number = skeleton.x, skeletonY:Number = skeleton.y;
+		var boneX:Number = positions[0], boneY:Number = positions[1], offsetRotation:Number = data.offsetRotation;
+		var tip:Boolean = rotateMode == RotateMode.chain && offsetRotation == 0;
+		var p:Number;
+		for (i = 0, p = 3; i < boneCount; i++, p += 3) {
+			bone = bones[i];
+			bone._worldX += (boneX - skeletonX - bone.worldX) * translateMix;
+			bone._worldY += (boneY - skeletonY - bone.worldY) * translateMix;
+			x = positions[p]; y = positions[p + 1]; var dx:Number = x - boneX, dy:Number = y - boneY;
+			if (scale) {
+				length = lengths[i];
+				if (length != 0) {
+					var s:Number = (Math.sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1;
+					bone._a *= s;
+					bone._c *= s;
+				}
+			}
+			boneX = x;
+			boneY = y;
+			if (rotate) {
+				var a:Number = bone.a, b:Number = bone.b, c:Number = bone.c, d:Number = bone.d, r:Number, cos:Number, sin:Number;
+				if (tangents)
+					r = positions[p - 1];
+				else if (spaces[i + 1] == 0)
+					r = positions[p + 2];
+				else
+					r = Math.atan2(dy, dx);
+				r -= Math.atan2(c, a) - offsetRotation * MathUtils.degRad;
+				if (tip) {
+					cos = Math.cos(r);
+					sin = Math.sin(r);
+					length = bone.data.length;
+					boneX += (length * (cos * a - sin * c) - dx) * rotateMix;
+					boneY += (length * (sin * a + cos * c) - dy) * rotateMix;
+				}
+				if (r > Math.PI)
+					r -= (Math.PI * 2);
+				else if (r < -Math.PI) //
+					r += (Math.PI * 2);
+				r *= rotateMix;
+				cos = Math.cos(r);
+				sin = Math.sin(r);
+				bone._a = cos * a - sin * c;
+				bone._b = cos * b - sin * d;
+				bone._c = sin * a + cos * c;
+				bone._d = sin * b + cos * d;
+			}
+		}
+	}
+
+	protected function computeWorldPositions (path:PathAttachment, spacesCount:int, tangents:Boolean, percentPosition:Boolean,
+		percentSpacing:Boolean) : Vector.<Number> {
+		var target:Slot = this.target;
+		var position:Number = this.position;
+		var spaces:Vector.<Number> = this._spaces;
+		this._positions.length = spacesCount * 3 + 2;
+		var out:Vector.<Number> = this._positions, world:Vector.<Number>;
+		var closed:Boolean = path.closed;
+		var verticesLength:int = path.worldVerticesLength, curveCount:int = verticesLength / 6, prevCurve:int = NONE;
+
+		if (!path.constantSpeed) {
+			var lengths:Vector.<Number> = path.lengths;
+			curveCount -= closed ? 1 : 2;
+			var pathLength:Number = lengths[curveCount];
+			if (percentPosition) position *= pathLength;
+			if (percentSpacing) {
+				for (var i:int = 0; i < spacesCount; i++)
+					spaces[i] *= pathLength;
+			}
+			this._world.length = 8;
+			world = this._world;
+			var o:int, curve:int; 
+			for (i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) {
+				var space:Number = spaces[i];
+				position += space;
+				var p:Number = position;
+
+				if (closed) {
+					p %= pathLength;
+					if (p < 0) p += pathLength;
+					curve = 0;
+				} else if (p < 0) {
+					if (prevCurve != BEFORE) {
+						prevCurve = BEFORE;
+						path.computeWorldVertices2(target, 2, 4, world, 0);
+					}
+					addBeforePosition(p, world, 0, out, o);
+					continue;
+				} else if (p > pathLength) {
+					if (prevCurve != AFTER) {
+						prevCurve = AFTER;
+						path.computeWorldVertices2(target, verticesLength - 6, 4, world, 0);
+					}
+					addAfterPosition(p - pathLength, world, 0, out, o);
+					continue;
+				}
+
+				// Determine curve containing position.
+				for (;; curve++) {
+					var length:Number = lengths[curve];
+					if (p > length) continue;
+					if (curve == 0)
+						p /= length;
+					else {
+						var prev:Number = lengths[curve - 1];
+						p = (p - prev) / (length - prev);
+					}
+					break;
+				}
+				if (curve != prevCurve) {
+					prevCurve = curve;
+					if (closed && curve == curveCount) {
+						path.computeWorldVertices2(target, verticesLength - 4, 4, world, 0);
+						path.computeWorldVertices2(target, 0, 4, world, 4);
+					} else
+						path.computeWorldVertices2(target, curve * 6 + 2, 8, world, 0);
+				}
+				addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o,
+					tangents || (i > 0 && space == 0));
+			}
+			return out;
+		}
+
+		// World vertices.
+		if (closed) {
+			verticesLength += 2;
+			this._world.length = verticesLength;
+			world = this._world;
+			path.computeWorldVertices2(target, 2, verticesLength - 4, world, 0);
+			path.computeWorldVertices2(target, 0, 2, world, verticesLength - 4);
+			world[verticesLength - 2] = world[0];
+			world[verticesLength - 1] = world[1];
+		} else {
+			curveCount--;
+			verticesLength -= 4;
+			this._world.length = verticesLength;
+			world = this._world;
+			path.computeWorldVertices2(target, 2, verticesLength, world, 0);
+		}
+
+		// Curve lengths.
+		this._curves.length = curveCount;
+		var curves:Vector.<Number> = this._curves;
+		pathLength = 0;
+		var x1:Number = world[0], y1:Number = world[1], cx1:Number = 0, cy1:Number = 0, cx2:Number = 0, cy2:Number = 0, x2:Number = 0, y2:Number = 0;
+		var tmpx:Number, tmpy:Number, dddfx:Number, dddfy:Number, ddfx:Number, ddfy:Number, dfx:Number, dfy:Number;
+		var w:int;
+		for (i = 0, w = 2; i < curveCount; i++, w += 6) {
+			cx1 = world[w];
+			cy1 = world[w + 1];
+			cx2 = world[w + 2];
+			cy2 = world[w + 3];
+			x2 = world[w + 4];
+			y2 = world[w + 5];
+			tmpx = (x1 - cx1 * 2 + cx2) * 0.1875;
+			tmpy = (y1 - cy1 * 2 + cy2) * 0.1875;
+			dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375;
+			dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375;
+			ddfx = tmpx * 2 + dddfx;
+			ddfy = tmpy * 2 + dddfy;
+			dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667;
+			dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667;
+			pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
+			dfx += ddfx;
+			dfy += ddfy;
+			ddfx += dddfx;
+			ddfy += dddfy;
+			pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
+			dfx += ddfx;
+			dfy += ddfy;
+			pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
+			dfx += ddfx + dddfx;
+			dfy += ddfy + dddfy;
+			pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
+			curves[i] = pathLength;
+			x1 = x2;
+			y1 = y2;
+		}
+		if (percentPosition) position *= pathLength;
+		if (percentSpacing) {
+			for (i = 0; i < spacesCount; i++)
+				spaces[i] *= pathLength;
+		}
+
+		var segments:Vector.<Number> = this._segments;
+		var curveLength:Number = 0;
+		var segment:int;
+		for (i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) {
+			space = spaces[i];
+			position += space;
+			p = position;
+
+			if (closed) {
+				p %= pathLength;
+				if (p < 0) p += pathLength;
+				curve = 0;
+			} else if (p < 0) {
+				addBeforePosition(p, world, 0, out, o);
+				continue;
+			} else if (p > pathLength) {
+				addAfterPosition(p - pathLength, world, verticesLength - 4, out, o);
+				continue;
+			}
+
+			// Determine curve containing position.
+			for (;; curve++) {
+				length = curves[curve];
+				if (p > length) continue;
+				if (curve == 0)
+					p /= length;
+				else {
+					prev = curves[curve - 1];
+					p = (p - prev) / (length - prev);
+				}
+				break;
+			}
+
+			// Curve segment lengths.
+			if (curve != prevCurve) {
+				prevCurve = curve;
+				var ii:int = curve * 6;
+				x1 = world[ii];
+				y1 = world[ii + 1];
+				cx1 = world[ii + 2];
+				cy1 = world[ii + 3];
+				cx2 = world[ii + 4];
+				cy2 = world[ii + 5];
+				x2 = world[ii + 6];
+				y2 = world[ii + 7];
+				tmpx = (x1 - cx1 * 2 + cx2) * 0.03;
+				tmpy = (y1 - cy1 * 2 + cy2) * 0.03;
+				dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006;
+				dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006;
+				ddfx = tmpx * 2 + dddfx;
+				ddfy = tmpy * 2 + dddfy;
+				dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667;
+				dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667;
+				curveLength = Math.sqrt(dfx * dfx + dfy * dfy);
+				segments[0] = curveLength;
+				for (ii = 1; ii < 8; ii++) {
+					dfx += ddfx;
+					dfy += ddfy;
+					ddfx += dddfx;
+					ddfy += dddfy;
+					curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
+					segments[ii] = curveLength;
+				}
+				dfx += ddfx;
+				dfy += ddfy;
+				curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
+				segments[8] = curveLength;
+				dfx += ddfx + dddfx;
+				dfy += ddfy + dddfy;
+				curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
+				segments[9] = curveLength;
+				segment = 0;
+			}
+
+			// Weight by segment length.
+			p *= curveLength;
+			for (;; segment++) {
+				length = segments[segment];
+				if (p > length) continue;
+				if (segment == 0)
+					p /= length;
+				else {
+					prev = segments[segment - 1];
+					p = segment + (p - prev) / (length - prev);
+				}
+				break;
+			}
+			addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0));
+		}
+		return out;
+	}
+
+	private function addBeforePosition (p:Number, temp:Vector.<Number>, i:int, out:Vector.<Number>, o:int) : void {
+		var x1:Number = temp[i], y1:Number = temp[i + 1], dx:Number = temp[i + 2] - x1, dy:Number = temp[i + 3] - y1, r:Number = Math.atan2(dy, dx);
+		out[o] = x1 + p * Math.cos(r);
+		out[o + 1] = y1 + p * Math.sin(r);
+		out[o + 2] = r;
+	}
+
+	private function addAfterPosition (p:Number, temp:Vector.<Number>, i:int, out:Vector.<Number>, o:int) : void {
+		var x1:Number = temp[i + 2], y1:Number = temp[i + 3], dx:Number = x1 - temp[i], dy:Number = y1 - temp[i + 1], r:Number = Math.atan2(dy, dx);
+		out[o] = x1 + p * Math.cos(r);
+		out[o + 1] = y1 + p * Math.sin(r);
+		out[o + 2] = r;
+	}
+
+	private function addCurvePosition (p:Number, x1:Number, y1:Number, cx1:Number, cy1:Number, cx2:Number, cy2:Number, x2:Number, y2:Number,
+		out:Vector.<Number>, o:int, tangents:Boolean) : void {
+		if (p == 0) p = 0.0001;
+		var tt:Number = p * p, ttt:Number = tt * p, u:Number = 1 - p, uu:Number = u * u, uuu:Number = uu * u;
+		var ut:Number = u * p, ut3:Number = ut * 3, uut3:Number = u * ut3, utt3:Number = ut3 * p;
+		var x:Number = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y:Number = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt;
+		out[o] = x;
+		out[o + 1] = y;
+		if (tangents) out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
+	}
+
+	public function get bones () : Vector.<Bone> {
+		return _bones;
+	}
+	
+	public function get data () : PathConstraintData {
+		return _data;
+	}
+
+	public function toString () : String {
+		return _data.name;
+	}
+}
+
 }

+ 58 - 59
spine-as3/spine-as3/src/spine/PathConstraintData.as

@@ -1,62 +1,61 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public dynamic class PathConstraintData {
-	internal var _name:String;
-	internal var _bones:Vector.<BoneData> = new Vector.<BoneData>();
-	public var target:SlotData;
-	public var positionMode:PositionMode;
-	public var spacingMode:SpacingMode;
-	public var rotateMode:RotateMode;
-	public var offsetRotation:Number;
-	public var position:Number, spacing:Number, rotateMix:Number, translateMix:Number;
-
-	public function PathConstraintData (name:String) {
-		if (name == null) throw new ArgumentError("name cannot be null.");
-		_name = name;
-	}
-
-	public function get bones () : Vector.<BoneData> {
-		return _bones;
-	}
-	
-	public function get name () : String {
-		return _name;
-	}
-
-	public function toString () : String {
-		return name;
-	}
+package spine {
+
+public dynamic class PathConstraintData {
+	internal var _name:String;
+	internal var _bones:Vector.<BoneData> = new Vector.<BoneData>();
+	public var target:SlotData;
+	public var positionMode:PositionMode;
+	public var spacingMode:SpacingMode;
+	public var rotateMode:RotateMode;
+	public var offsetRotation:Number;
+	public var position:Number, spacing:Number, rotateMix:Number, translateMix:Number;
+
+	public function PathConstraintData (name:String) {
+		if (name == null) throw new ArgumentError("name cannot be null.");
+		_name = name;
+	}
+
+	public function get bones () : Vector.<BoneData> {
+		return _bones;
+	}
+	
+	public function get name () : String {
+		return _name;
+	}
+
+	public function toString () : String {
+		return name;
+	}
+}
+
 }
-
-}

+ 79 - 80
spine-as3/spine-as3/src/spine/Polygon.as

@@ -1,83 +1,82 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public class Polygon {
-	public var vertices:Vector.<Number> = new Vector.<Number>();
-	
-	public function Polygon () {		
-	}
-	
-	/** Returns true if the polygon contains the point. */
-	public function containsPoint (x:Number, y:Number) : Boolean {
-		var nn:int = vertices.length;
-		
-		var prevIndex:int = nn - 2;
-		var inside:Boolean = false;
-		for (var ii:int = 0; ii < nn; ii += 2) {
-			var vertexY:Number = vertices[ii + 1];
-			var prevY:Number = vertices[prevIndex + 1];
-			if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) {
-				var vertexX:Number = vertices[ii];
-				if (vertexX + (y - vertexY) / (prevY - vertexY) * (vertices[prevIndex] - vertexX) < x) inside = !inside;
-			}
-			prevIndex = ii;
-		}
-		
-		return inside;
-	}
-
-	/** Returns true if the polygon contains the line segment. */
-	public function intersectsSegment (x1:Number, y1:Number, x2:Number, y2:Number) : Boolean {
-		var nn:int = vertices.length;
-		
-		var width12:Number = x1 - x2, height12:Number = y1 - y2;
-		var det1:Number = x1 * y2 - y1 * x2;
-		var x3:Number = vertices[nn - 2], y3:Number = vertices[nn - 1];
-		for (var ii:int = 0; ii < nn; ii += 2) {
-			var x4:Number = vertices[ii], y4:Number = vertices[ii + 1];
-			var det2:Number = x3 * y4 - y3 * x4;
-			var width34:Number = x3 - x4, height34:Number = y3 - y4;
-			var det3:Number = width12 * height34 - height12 * width34;
-			var x:Number = (det1 * width34 - width12 * det2) / det3;
-			if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) {
-				var y:Number = (det1 * height34 - height12 * det2) / det3;
-				if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1))) return true;
-			}
-			x3 = x4;
-			y3 = y4;
-		}
-		return false;
-	}
-}
-
+package spine {
+
+public class Polygon {
+	public var vertices:Vector.<Number> = new Vector.<Number>();
+	
+	public function Polygon () {		
+	}
+	
+	/** Returns true if the polygon contains the point. */
+	public function containsPoint (x:Number, y:Number) : Boolean {
+		var nn:int = vertices.length;
+		
+		var prevIndex:int = nn - 2;
+		var inside:Boolean = false;
+		for (var ii:int = 0; ii < nn; ii += 2) {
+			var vertexY:Number = vertices[ii + 1];
+			var prevY:Number = vertices[prevIndex + 1];
+			if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) {
+				var vertexX:Number = vertices[ii];
+				if (vertexX + (y - vertexY) / (prevY - vertexY) * (vertices[prevIndex] - vertexX) < x) inside = !inside;
+			}
+			prevIndex = ii;
+		}
+		
+		return inside;
+	}
+
+	/** Returns true if the polygon contains the line segment. */
+	public function intersectsSegment (x1:Number, y1:Number, x2:Number, y2:Number) : Boolean {
+		var nn:int = vertices.length;
+		
+		var width12:Number = x1 - x2, height12:Number = y1 - y2;
+		var det1:Number = x1 * y2 - y1 * x2;
+		var x3:Number = vertices[nn - 2], y3:Number = vertices[nn - 1];
+		for (var ii:int = 0; ii < nn; ii += 2) {
+			var x4:Number = vertices[ii], y4:Number = vertices[ii + 1];
+			var det2:Number = x3 * y4 - y3 * x4;
+			var width34:Number = x3 - x4, height34:Number = y3 - y4;
+			var det3:Number = width12 * height34 - height12 * width34;
+			var x:Number = (det1 * width34 - width12 * det2) / det3;
+			if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) {
+				var y:Number = (det1 * height34 - height12 * det2) / det3;
+				if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1))) return true;
+			}
+			x3 = x4;
+			y3 = y4;
+		}
+		return false;
+	}
+}
+
 }

+ 35 - 36
spine-as3/spine-as3/src/spine/PositionMode.as

@@ -1,39 +1,38 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-	
-public class PositionMode {
-	public static const fixed:PositionMode = new PositionMode();
-	public static const percent:PositionMode = new PositionMode();
+package spine {
+	
+public class PositionMode {
+	public static const fixed:PositionMode = new PositionMode();
+	public static const percent:PositionMode = new PositionMode();
+}
+
 }
-
-}

+ 36 - 37
spine-as3/spine-as3/src/spine/RotateMode.as

@@ -1,40 +1,39 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public class RotateMode {
-	public static const tangent:RotateMode = new RotateMode();
-	public static const chain:RotateMode = new RotateMode();
-	public static const chainScale:RotateMode = new RotateMode();
+package spine {
+
+public class RotateMode {
+	public static const tangent:RotateMode = new RotateMode();
+	public static const chain:RotateMode = new RotateMode();
+	public static const chainScale:RotateMode = new RotateMode();
+}
+
 }
-
-}

+ 445 - 446
spine-as3/spine-as3/src/spine/Skeleton.as

@@ -1,449 +1,448 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-import flash.utils.Dictionary;
-import spine.attachments.PathAttachment;
-import spine.attachments.Attachment;
-
-public class Skeleton {
-	internal var _data:SkeletonData;
-	public var bones:Vector.<Bone>;
-	public var slots:Vector.<Slot>;
-	public var drawOrder:Vector.<Slot>;
-	public var ikConstraints:Vector.<IkConstraint>, ikConstraintsSorted:Vector.<IkConstraint>;
-	public var transformConstraints:Vector.<TransformConstraint>;
-	public var pathConstraints:Vector.<PathConstraint>;
-	private var _updateCache:Vector.<Updatable> = new Vector.<Updatable>();
-	private var _skin:Skin;
-	public var r:Number = 1, g:Number = 1, b:Number = 1, a:Number = 1;
-	public var time:Number = 0;
-	public var flipX:Boolean, flipY:Boolean;
-	public var x:Number = 0, y:Number = 0;
-
-	public function Skeleton (data:SkeletonData) {
-		if (data == null)
-			throw new ArgumentError("data cannot be null.");
-		_data = data;
-
-		bones = new Vector.<Bone>();
-		for each (var boneData:BoneData in data.bones) {
-			var bone:Bone;
-			if (boneData.parent == null)
-				bone = new Bone(boneData, this, null);
-			else {
-				var parent:Bone = bones[boneData.parent.index];
-				bone = new Bone(boneData, this, parent);
-				parent.children.push(bone);
-			}
-			bones.push(bone);
-		}
-
-		slots = new Vector.<Slot>();
-		drawOrder = new Vector.<Slot>();
-		for each (var slotData:SlotData in data.slots) {
-			bone = bones[slotData.boneData.index];
-			var slot:Slot = new Slot(slotData, bone);
-			slots.push(slot);
-			drawOrder[drawOrder.length] = slot;
-		}
-		
-		ikConstraints = new Vector.<IkConstraint>();
-		ikConstraintsSorted = new Vector.<IkConstraint>();
-		for each (var ikConstraintData:IkConstraintData in data.ikConstraints)
-			ikConstraints.push(new IkConstraint(ikConstraintData, this));
-		
-		transformConstraints = new Vector.<TransformConstraint>();
-		for each (var transformConstraintData:TransformConstraintData in data.transformConstraints)
-			transformConstraints.push(new TransformConstraint(transformConstraintData, this));
-
-		pathConstraints = new Vector.<PathConstraint>();
-		for each (var pathConstraintData:PathConstraintData in data.pathConstraints)
-			pathConstraints.push(new PathConstraint(pathConstraintData, this));
-
-		updateCache();
-	}
-
-	/** Caches information about bones and constraints. Must be called if bones, constraints, or weighted path attachments are
-	 * added or removed. */
-	public function updateCache () : void {
-		var updateCache:Vector.<Updatable> = this._updateCache;
-		updateCache.length = 0;
-
-		var bones:Vector.<Bone> = this.bones;
-		for (var i:int = 0, n:int = bones.length; i < n; i++)
-			bones[i]._sorted = false;
-
-		// IK first, lowest hierarchy depth first.
-		var ikConstraints:Vector.<IkConstraint> = this.ikConstraintsSorted;
-		ikConstraints.length = 0;
-		for each (var c:IkConstraint in this.ikConstraints)
-			ikConstraints.push(c);
-		var ikCount:int = ikConstraints.length;
-		var level:int;
-		for (i = 0, n = ikCount; i < n; i++) {
-			var ik:IkConstraint = ikConstraints[i];
-			var bone:Bone = ik.bones[0].parent;
-			for (level = 0; bone != null; level++)
-				bone = bone.parent;
-			ik.level = level;
-		}
-		var ii:int;
-		for (i = 1; i < ikCount; i++) {
-			ik = ikConstraints[i];
-			level = ik.level;
-			for (ii = i - 1; ii >= 0; ii--) {
-				var other:IkConstraint = ikConstraints[ii];
-				if (other.level < level) break;
-				ikConstraints[ii + 1] = other;
-			}
-			ikConstraints[ii + 1] = ik;
-		}
-		for (i = 0, n = ikConstraints.length; i < n; i++) {
-			var ikConstraint:IkConstraint = ikConstraints[i];
-			var target:Bone = ikConstraint.target;
-			sortBone(target);
-
-			var constrained:Vector.<Bone> = ikConstraint.bones;
-			var parent:Bone = constrained[0];
-			sortBone(parent);
-
-			updateCache.push(ikConstraint);
-
-			sortReset(parent.children);
-			constrained[constrained.length - 1]._sorted = true;
-		}
-
-		var pathConstraints:Vector.<PathConstraint> = this.pathConstraints;
-		for (i = 0, n = pathConstraints.length; i < n; i++) {
-			var pathConstraint:PathConstraint = pathConstraints[i];
-
-			var slot:Slot = pathConstraint.target;
-			var slotIndex:int = slot.data.index;
-			var slotBone:Bone = slot.bone;
-			if (skin != null) sortPathConstraintAttachment(skin, slotIndex, slotBone);
-			if (_data.defaultSkin != null && _data.defaultSkin != skin)
-				sortPathConstraintAttachment(_data.defaultSkin, slotIndex, slotBone);
-				
-			var nn:int;
-			for (ii = 0, nn = _data.skins.length; ii < nn; ii++)
-				sortPathConstraintAttachment(_data.skins[ii], slotIndex, slotBone);
-
-			var attachment:PathAttachment = slot.attachment as PathAttachment;
-			if (attachment != null) sortPathConstraintAttachment2(attachment, slotBone);
-
-			constrained = pathConstraint.bones;
-			var boneCount:int = constrained.length;
-			for (ii = 0; ii < boneCount; ii++)
-				sortBone(constrained[ii]);
-
-			updateCache.push(pathConstraint);
-
-			for (ii = 0; ii < boneCount; ii++)
-				sortReset(constrained[ii].children);
-			for (ii = 0; ii < boneCount; ii++)
-				constrained[ii]._sorted = true;
-		}
-
-		var transformConstraints:Vector.<TransformConstraint> = this.transformConstraints;
-		for (i = 0, n = transformConstraints.length; i < n; i++) {
-			var transformConstraint:TransformConstraint = transformConstraints[i];
-
-			sortBone(transformConstraint.target);
-
-			constrained = transformConstraint.bones;
-			boneCount = constrained.length;
-			for (ii = 0; ii < boneCount; ii++)
-				sortBone(constrained[ii]);
-
-			updateCache.push(transformConstraint);
-
-			for (ii = 0; ii < boneCount; ii++)
-				sortReset(constrained[ii].children);
-			for (ii = 0; ii < boneCount; ii++)
-				constrained[ii]._sorted = true;
-		}
-
-		for (i = 0, n = bones.length; i < n; i++)
-			sortBone(bones[i]);
-	}
-	
-	private function sortPathConstraintAttachment (skin:Skin, slotIndex:int, slotBone:Bone) : void {
-		var dict:Dictionary = skin.attachments[slotIndex];
-		if (!dict) return;
-		
-		for each (var value:Attachment in dict) {
-			sortPathConstraintAttachment2(value, slotBone);
-		}
-	}
-
-	private function sortPathConstraintAttachment2 (attachment:Attachment, slotBone:Bone) : void {
-		var pathAttachment:PathAttachment = attachment as PathAttachment;
-		if (!pathAttachment) return;
-		var pathBones:Vector.<int> = pathAttachment.bones;
-		if (pathBones == null)
-			sortBone(slotBone);
-		else {
-			var bones:Vector.<Bone> = this.bones;
-			var i:int = 0;
-			while (i < pathBones.length) {
-				var boneCount:int = pathBones[i++];
-				for (var n:int = i + boneCount; i < n; i++) {				
-					sortBone(bones[pathBones[i]]);
-				}
-			}
-		}
-	}
-
-	private function sortBone (bone:Bone) : void {
-		if (bone._sorted) return;
-		var parent:Bone = bone.parent;
-		if (parent != null) sortBone(parent);
-		bone._sorted = true;
-		_updateCache.push(bone);
-	}
-
-	private function sortReset (bones:Vector.<Bone>) : void {
-		for (var i:int = 0, n:int = bones.length; i < n; i++) {
-			var bone:Bone = bones[i];
-			if (bone._sorted) sortReset(bone.children);
-			bone._sorted = false;
-		}
-	}
-
-	/** Updates the world transform for each bone and applies constraints. */
-	public function updateWorldTransform () : void {
-		for each (var updatable:Updatable in _updateCache)
-			updatable.update();
-	}
-
-	/** Sets the bones, constraints, and slots to their setup pose values. */
-	public function setToSetupPose () : void {
-		setBonesToSetupPose();
-		setSlotsToSetupPose();
-	}
-
-	/** Sets the bones and constraints to their setup pose values. */
-	public function setBonesToSetupPose () : void {
-		for each (var bone:Bone in bones)
-			bone.setToSetupPose();
-
-		for each (var ikConstraint:IkConstraint in ikConstraints) {
-			ikConstraint.bendDirection = ikConstraint._data.bendDirection;
-			ikConstraint.mix = ikConstraint._data.mix;
-		}
-
-		for each (var transformConstraint:TransformConstraint in transformConstraints) {
-			transformConstraint.rotateMix = transformConstraint._data.rotateMix;
-			transformConstraint.translateMix = transformConstraint._data.translateMix;
-			transformConstraint.scaleMix = transformConstraint._data.scaleMix;
-			transformConstraint.shearMix = transformConstraint._data.shearMix;
-		}
-		
-		for each (var pathConstraint:PathConstraint in pathConstraints) {
-			pathConstraint.position = pathConstraint._data.position;
-			pathConstraint.spacing = pathConstraint._data.spacing;
-			pathConstraint.rotateMix = pathConstraint._data.rotateMix;
-			pathConstraint.translateMix = pathConstraint._data.translateMix;
-		}
-	}
-
-	public function setSlotsToSetupPose () : void {
-		var i:int = 0;
-		for each (var slot:Slot in slots) { 
-			drawOrder[i++] = slot;
-			slot.setToSetupPose();
-		}
-	}
-
-	public function get data () : SkeletonData {
-		return _data;
-	}
-	
-	public function get getUpdateCache () : Vector.<Updatable> {
-		return _updateCache;
-	}
-
-	public function get rootBone () : Bone {
-		if (bones.length == 0) return null;
-		return bones[0];
-	}
-
-	/** @return May be null. */
-	public function findBone (boneName:String) : Bone {
-		if (boneName == null)
-			throw new ArgumentError("boneName cannot be null.");
-		for each (var bone:Bone in bones)
-			if (bone._data._name == boneName) return bone;
-		return null;
-	}
-
-	/** @return -1 if the bone was not found. */
-	public function findBoneIndex (boneName:String) : int {
-		if (boneName == null)
-			throw new ArgumentError("boneName cannot be null.");
-		var i:int = 0;
-		for each (var bone:Bone in bones) {
-			if (bone._data._name == boneName) return i;
-			i++;
-		}
-		return -1;
-	}
-
-	/** @return May be null. */
-	public function findSlot (slotName:String) : Slot {
-		if (slotName == null)
-			throw new ArgumentError("slotName cannot be null.");
-		for each (var slot:Slot in slots)
-			if (slot._data._name == slotName) return slot;
-		return null;
-	}
-
-	/** @return -1 if the bone was not found. */
-	public function findSlotIndex (slotName:String) : int {
-		if (slotName == null)
-			throw new ArgumentError("slotName cannot be null.");
-		var i:int = 0;
-		for each (var slot:Slot in slots) {
-			if (slot._data._name == slotName) return i;
-			i++;
-		}
-		return -1;
-	}
-
-	public function get skin () : Skin {
-		return _skin;
-	}
-
-	public function set skinName (skinName:String) : void {
-		var skin:Skin = data.findSkin(skinName);
-		if (skin == null) throw new ArgumentError("Skin not found: " + skinName);
-		this.skin = skin;
-	}
-
-	/** @return May be null. */
-	public function get skinName () : String {
-		return _skin == null ? null : _skin._name;
-	}
-
-	/** Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}. 
-	 * Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was 
-	 * no old skin, each slot's setup mode attachment is attached from the new skin.
-	 * @param newSkin May be null. */
-	public function set skin (newSkin:Skin) : void {
-		if (newSkin) {
-			if (skin)
-				newSkin.attachAll(this, skin);
-			else {
-				var i:int = 0;
-				for each (var slot:Slot in slots) {
-					var name:String = slot._data.attachmentName;
-					if (name) {
-						var attachment:Attachment = newSkin.getAttachment(i, name);
-						if (attachment) slot.attachment = attachment;
-					}
-					i++;
-				}
-			}
-		}
-		_skin = newSkin;
-	}
-
-	/** @return May be null. */
-	public function getAttachmentForSlotName (slotName:String, attachmentName:String) : Attachment {
-		return getAttachmentForSlotIndex(data.findSlotIndex(slotName), attachmentName);
-	}
-
-	/** @return May be null. */
-	public function getAttachmentForSlotIndex (slotIndex:int, attachmentName:String) : Attachment {
-		if (attachmentName == null) throw new ArgumentError("attachmentName cannot be null.");
-		if (skin != null) {
-			var attachment:Attachment = skin.getAttachment(slotIndex, attachmentName);
-			if (attachment != null) return attachment;
-		}
-		if (data.defaultSkin != null) return data.defaultSkin.getAttachment(slotIndex, attachmentName);
-		return null;
-	}
-
-	/** @param attachmentName May be null. */
-	public function setAttachment (slotName:String, attachmentName:String) : void {
-		if (slotName == null) throw new ArgumentError("slotName cannot be null.");
-		var i:int = 0;
-		for each (var slot:Slot in slots) {
-			if (slot._data._name == slotName) {
-				var attachment:Attachment = null;
-				if (attachmentName != null) {
-					attachment = getAttachmentForSlotIndex(i, attachmentName);
-					if (attachment == null)
-						throw new ArgumentError("Attachment not found: " + attachmentName + ", for slot: " + slotName);
-				}
-				slot.attachment = attachment;
-				return;
-			}
-			i++;
-		}
-		throw new ArgumentError("Slot not found: " + slotName);
-	}
-
-	/** @return May be null. */
-	public function findIkConstraint (constraintName:String) : IkConstraint {
-		if (constraintName == null) throw new ArgumentError("constraintName cannot be null.");
-		for each (var ikConstraint:IkConstraint in ikConstraints)
-			if (ikConstraint._data._name == constraintName) return ikConstraint;
-		return null;
-	}
-
-	/** @return May be null. */
-	public function findTransformConstraint (constraintName:String) : TransformConstraint {
-		if (constraintName == null) throw new ArgumentError("constraintName cannot be null.");
-		for each (var transformConstraint:TransformConstraint in transformConstraints)
-			if (transformConstraint._data._name == constraintName) return transformConstraint;
-		return null;
-	}
-	
-	/** @return May be null. */
-	public function findPathConstraint (constraintName:String) : PathConstraint {
-		if (constraintName == null) throw new ArgumentError("constraintName cannot be null.");
-		for each (var pathConstraint:PathConstraint in pathConstraints)
-			if (pathConstraint._data._name == constraintName) return pathConstraint;
-		return null;
-	}
-
-	public function update (delta:Number) : void {
-		time += delta;
-	}
-
-	public function toString () : String {
-		return _data.name != null ? _data.name : super.toString();
-	}
-}
-
+package spine {
+import flash.utils.Dictionary;
+import spine.attachments.PathAttachment;
+import spine.attachments.Attachment;
+
+public class Skeleton {
+	internal var _data:SkeletonData;
+	public var bones:Vector.<Bone>;
+	public var slots:Vector.<Slot>;
+	public var drawOrder:Vector.<Slot>;
+	public var ikConstraints:Vector.<IkConstraint>, ikConstraintsSorted:Vector.<IkConstraint>;
+	public var transformConstraints:Vector.<TransformConstraint>;
+	public var pathConstraints:Vector.<PathConstraint>;
+	private var _updateCache:Vector.<Updatable> = new Vector.<Updatable>();
+	private var _skin:Skin;
+	public var r:Number = 1, g:Number = 1, b:Number = 1, a:Number = 1;
+	public var time:Number = 0;
+	public var flipX:Boolean, flipY:Boolean;
+	public var x:Number = 0, y:Number = 0;
+
+	public function Skeleton (data:SkeletonData) {
+		if (data == null)
+			throw new ArgumentError("data cannot be null.");
+		_data = data;
+
+		bones = new Vector.<Bone>();
+		for each (var boneData:BoneData in data.bones) {
+			var bone:Bone;
+			if (boneData.parent == null)
+				bone = new Bone(boneData, this, null);
+			else {
+				var parent:Bone = bones[boneData.parent.index];
+				bone = new Bone(boneData, this, parent);
+				parent.children.push(bone);
+			}
+			bones.push(bone);
+		}
+
+		slots = new Vector.<Slot>();
+		drawOrder = new Vector.<Slot>();
+		for each (var slotData:SlotData in data.slots) {
+			bone = bones[slotData.boneData.index];
+			var slot:Slot = new Slot(slotData, bone);
+			slots.push(slot);
+			drawOrder[drawOrder.length] = slot;
+		}
+		
+		ikConstraints = new Vector.<IkConstraint>();
+		ikConstraintsSorted = new Vector.<IkConstraint>();
+		for each (var ikConstraintData:IkConstraintData in data.ikConstraints)
+			ikConstraints.push(new IkConstraint(ikConstraintData, this));
+		
+		transformConstraints = new Vector.<TransformConstraint>();
+		for each (var transformConstraintData:TransformConstraintData in data.transformConstraints)
+			transformConstraints.push(new TransformConstraint(transformConstraintData, this));
+
+		pathConstraints = new Vector.<PathConstraint>();
+		for each (var pathConstraintData:PathConstraintData in data.pathConstraints)
+			pathConstraints.push(new PathConstraint(pathConstraintData, this));
+
+		updateCache();
+	}
+
+	/** Caches information about bones and constraints. Must be called if bones, constraints, or weighted path attachments are
+	 * added or removed. */
+	public function updateCache () : void {
+		var updateCache:Vector.<Updatable> = this._updateCache;
+		updateCache.length = 0;
+
+		var bones:Vector.<Bone> = this.bones;
+		for (var i:int = 0, n:int = bones.length; i < n; i++)
+			bones[i]._sorted = false;
+
+		// IK first, lowest hierarchy depth first.
+		var ikConstraints:Vector.<IkConstraint> = this.ikConstraintsSorted;
+		ikConstraints.length = 0;
+		for each (var c:IkConstraint in this.ikConstraints)
+			ikConstraints.push(c);
+		var ikCount:int = ikConstraints.length;
+		var level:int;
+		for (i = 0, n = ikCount; i < n; i++) {
+			var ik:IkConstraint = ikConstraints[i];
+			var bone:Bone = ik.bones[0].parent;
+			for (level = 0; bone != null; level++)
+				bone = bone.parent;
+			ik.level = level;
+		}
+		var ii:int;
+		for (i = 1; i < ikCount; i++) {
+			ik = ikConstraints[i];
+			level = ik.level;
+			for (ii = i - 1; ii >= 0; ii--) {
+				var other:IkConstraint = ikConstraints[ii];
+				if (other.level < level) break;
+				ikConstraints[ii + 1] = other;
+			}
+			ikConstraints[ii + 1] = ik;
+		}
+		for (i = 0, n = ikConstraints.length; i < n; i++) {
+			var ikConstraint:IkConstraint = ikConstraints[i];
+			var target:Bone = ikConstraint.target;
+			sortBone(target);
+
+			var constrained:Vector.<Bone> = ikConstraint.bones;
+			var parent:Bone = constrained[0];
+			sortBone(parent);
+
+			updateCache.push(ikConstraint);
+
+			sortReset(parent.children);
+			constrained[constrained.length - 1]._sorted = true;
+		}
+
+		var pathConstraints:Vector.<PathConstraint> = this.pathConstraints;
+		for (i = 0, n = pathConstraints.length; i < n; i++) {
+			var pathConstraint:PathConstraint = pathConstraints[i];
+
+			var slot:Slot = pathConstraint.target;
+			var slotIndex:int = slot.data.index;
+			var slotBone:Bone = slot.bone;
+			if (skin != null) sortPathConstraintAttachment(skin, slotIndex, slotBone);
+			if (_data.defaultSkin != null && _data.defaultSkin != skin)
+				sortPathConstraintAttachment(_data.defaultSkin, slotIndex, slotBone);
+				
+			var nn:int;
+			for (ii = 0, nn = _data.skins.length; ii < nn; ii++)
+				sortPathConstraintAttachment(_data.skins[ii], slotIndex, slotBone);
+
+			var attachment:PathAttachment = slot.attachment as PathAttachment;
+			if (attachment != null) sortPathConstraintAttachment2(attachment, slotBone);
+
+			constrained = pathConstraint.bones;
+			var boneCount:int = constrained.length;
+			for (ii = 0; ii < boneCount; ii++)
+				sortBone(constrained[ii]);
+
+			updateCache.push(pathConstraint);
+
+			for (ii = 0; ii < boneCount; ii++)
+				sortReset(constrained[ii].children);
+			for (ii = 0; ii < boneCount; ii++)
+				constrained[ii]._sorted = true;
+		}
+
+		var transformConstraints:Vector.<TransformConstraint> = this.transformConstraints;
+		for (i = 0, n = transformConstraints.length; i < n; i++) {
+			var transformConstraint:TransformConstraint = transformConstraints[i];
+
+			sortBone(transformConstraint.target);
+
+			constrained = transformConstraint.bones;
+			boneCount = constrained.length;
+			for (ii = 0; ii < boneCount; ii++)
+				sortBone(constrained[ii]);
+
+			updateCache.push(transformConstraint);
+
+			for (ii = 0; ii < boneCount; ii++)
+				sortReset(constrained[ii].children);
+			for (ii = 0; ii < boneCount; ii++)
+				constrained[ii]._sorted = true;
+		}
+
+		for (i = 0, n = bones.length; i < n; i++)
+			sortBone(bones[i]);
+	}
+	
+	private function sortPathConstraintAttachment (skin:Skin, slotIndex:int, slotBone:Bone) : void {
+		var dict:Dictionary = skin.attachments[slotIndex];
+		if (!dict) return;
+		
+		for each (var value:Attachment in dict) {
+			sortPathConstraintAttachment2(value, slotBone);
+		}
+	}
+
+	private function sortPathConstraintAttachment2 (attachment:Attachment, slotBone:Bone) : void {
+		var pathAttachment:PathAttachment = attachment as PathAttachment;
+		if (!pathAttachment) return;
+		var pathBones:Vector.<int> = pathAttachment.bones;
+		if (pathBones == null)
+			sortBone(slotBone);
+		else {
+			var bones:Vector.<Bone> = this.bones;
+			var i:int = 0;
+			while (i < pathBones.length) {
+				var boneCount:int = pathBones[i++];
+				for (var n:int = i + boneCount; i < n; i++) {				
+					sortBone(bones[pathBones[i]]);
+				}
+			}
+		}
+	}
+
+	private function sortBone (bone:Bone) : void {
+		if (bone._sorted) return;
+		var parent:Bone = bone.parent;
+		if (parent != null) sortBone(parent);
+		bone._sorted = true;
+		_updateCache.push(bone);
+	}
+
+	private function sortReset (bones:Vector.<Bone>) : void {
+		for (var i:int = 0, n:int = bones.length; i < n; i++) {
+			var bone:Bone = bones[i];
+			if (bone._sorted) sortReset(bone.children);
+			bone._sorted = false;
+		}
+	}
+
+	/** Updates the world transform for each bone and applies constraints. */
+	public function updateWorldTransform () : void {
+		for each (var updatable:Updatable in _updateCache)
+			updatable.update();
+	}
+
+	/** Sets the bones, constraints, and slots to their setup pose values. */
+	public function setToSetupPose () : void {
+		setBonesToSetupPose();
+		setSlotsToSetupPose();
+	}
+
+	/** Sets the bones and constraints to their setup pose values. */
+	public function setBonesToSetupPose () : void {
+		for each (var bone:Bone in bones)
+			bone.setToSetupPose();
+
+		for each (var ikConstraint:IkConstraint in ikConstraints) {
+			ikConstraint.bendDirection = ikConstraint._data.bendDirection;
+			ikConstraint.mix = ikConstraint._data.mix;
+		}
+
+		for each (var transformConstraint:TransformConstraint in transformConstraints) {
+			transformConstraint.rotateMix = transformConstraint._data.rotateMix;
+			transformConstraint.translateMix = transformConstraint._data.translateMix;
+			transformConstraint.scaleMix = transformConstraint._data.scaleMix;
+			transformConstraint.shearMix = transformConstraint._data.shearMix;
+		}
+		
+		for each (var pathConstraint:PathConstraint in pathConstraints) {
+			pathConstraint.position = pathConstraint._data.position;
+			pathConstraint.spacing = pathConstraint._data.spacing;
+			pathConstraint.rotateMix = pathConstraint._data.rotateMix;
+			pathConstraint.translateMix = pathConstraint._data.translateMix;
+		}
+	}
+
+	public function setSlotsToSetupPose () : void {
+		var i:int = 0;
+		for each (var slot:Slot in slots) { 
+			drawOrder[i++] = slot;
+			slot.setToSetupPose();
+		}
+	}
+
+	public function get data () : SkeletonData {
+		return _data;
+	}
+	
+	public function get getUpdateCache () : Vector.<Updatable> {
+		return _updateCache;
+	}
+
+	public function get rootBone () : Bone {
+		if (bones.length == 0) return null;
+		return bones[0];
+	}
+
+	/** @return May be null. */
+	public function findBone (boneName:String) : Bone {
+		if (boneName == null)
+			throw new ArgumentError("boneName cannot be null.");
+		for each (var bone:Bone in bones)
+			if (bone._data._name == boneName) return bone;
+		return null;
+	}
+
+	/** @return -1 if the bone was not found. */
+	public function findBoneIndex (boneName:String) : int {
+		if (boneName == null)
+			throw new ArgumentError("boneName cannot be null.");
+		var i:int = 0;
+		for each (var bone:Bone in bones) {
+			if (bone._data._name == boneName) return i;
+			i++;
+		}
+		return -1;
+	}
+
+	/** @return May be null. */
+	public function findSlot (slotName:String) : Slot {
+		if (slotName == null)
+			throw new ArgumentError("slotName cannot be null.");
+		for each (var slot:Slot in slots)
+			if (slot._data._name == slotName) return slot;
+		return null;
+	}
+
+	/** @return -1 if the bone was not found. */
+	public function findSlotIndex (slotName:String) : int {
+		if (slotName == null)
+			throw new ArgumentError("slotName cannot be null.");
+		var i:int = 0;
+		for each (var slot:Slot in slots) {
+			if (slot._data._name == slotName) return i;
+			i++;
+		}
+		return -1;
+	}
+
+	public function get skin () : Skin {
+		return _skin;
+	}
+
+	public function set skinName (skinName:String) : void {
+		var skin:Skin = data.findSkin(skinName);
+		if (skin == null) throw new ArgumentError("Skin not found: " + skinName);
+		this.skin = skin;
+	}
+
+	/** @return May be null. */
+	public function get skinName () : String {
+		return _skin == null ? null : _skin._name;
+	}
+
+	/** Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}. 
+	 * Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was 
+	 * no old skin, each slot's setup mode attachment is attached from the new skin.
+	 * @param newSkin May be null. */
+	public function set skin (newSkin:Skin) : void {
+		if (newSkin) {
+			if (skin)
+				newSkin.attachAll(this, skin);
+			else {
+				var i:int = 0;
+				for each (var slot:Slot in slots) {
+					var name:String = slot._data.attachmentName;
+					if (name) {
+						var attachment:Attachment = newSkin.getAttachment(i, name);
+						if (attachment) slot.attachment = attachment;
+					}
+					i++;
+				}
+			}
+		}
+		_skin = newSkin;
+	}
+
+	/** @return May be null. */
+	public function getAttachmentForSlotName (slotName:String, attachmentName:String) : Attachment {
+		return getAttachmentForSlotIndex(data.findSlotIndex(slotName), attachmentName);
+	}
+
+	/** @return May be null. */
+	public function getAttachmentForSlotIndex (slotIndex:int, attachmentName:String) : Attachment {
+		if (attachmentName == null) throw new ArgumentError("attachmentName cannot be null.");
+		if (skin != null) {
+			var attachment:Attachment = skin.getAttachment(slotIndex, attachmentName);
+			if (attachment != null) return attachment;
+		}
+		if (data.defaultSkin != null) return data.defaultSkin.getAttachment(slotIndex, attachmentName);
+		return null;
+	}
+
+	/** @param attachmentName May be null. */
+	public function setAttachment (slotName:String, attachmentName:String) : void {
+		if (slotName == null) throw new ArgumentError("slotName cannot be null.");
+		var i:int = 0;
+		for each (var slot:Slot in slots) {
+			if (slot._data._name == slotName) {
+				var attachment:Attachment = null;
+				if (attachmentName != null) {
+					attachment = getAttachmentForSlotIndex(i, attachmentName);
+					if (attachment == null)
+						throw new ArgumentError("Attachment not found: " + attachmentName + ", for slot: " + slotName);
+				}
+				slot.attachment = attachment;
+				return;
+			}
+			i++;
+		}
+		throw new ArgumentError("Slot not found: " + slotName);
+	}
+
+	/** @return May be null. */
+	public function findIkConstraint (constraintName:String) : IkConstraint {
+		if (constraintName == null) throw new ArgumentError("constraintName cannot be null.");
+		for each (var ikConstraint:IkConstraint in ikConstraints)
+			if (ikConstraint._data._name == constraintName) return ikConstraint;
+		return null;
+	}
+
+	/** @return May be null. */
+	public function findTransformConstraint (constraintName:String) : TransformConstraint {
+		if (constraintName == null) throw new ArgumentError("constraintName cannot be null.");
+		for each (var transformConstraint:TransformConstraint in transformConstraints)
+			if (transformConstraint._data._name == constraintName) return transformConstraint;
+		return null;
+	}
+	
+	/** @return May be null. */
+	public function findPathConstraint (constraintName:String) : PathConstraint {
+		if (constraintName == null) throw new ArgumentError("constraintName cannot be null.");
+		for each (var pathConstraint:PathConstraint in pathConstraints)
+			if (pathConstraint._data._name == constraintName) return pathConstraint;
+		return null;
+	}
+
+	public function update (delta:Number) : void {
+		time += delta;
+	}
+
+	public function toString () : String {
+		return _data.name != null ? _data.name : super.toString();
+	}
+}
+
 }

+ 149 - 150
spine-as3/spine-as3/src/spine/SkeletonBounds.as

@@ -1,153 +1,152 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-import spine.attachments.BoundingBoxAttachment;
-
-public class SkeletonBounds {
-	private var polygonPool:Vector.<Polygon> = new Vector.<Polygon>();
-
-	public var boundingBoxes:Vector.<BoundingBoxAttachment> = new Vector.<BoundingBoxAttachment>();
-	public var polygons:Vector.<Polygon> = new Vector.<Polygon>();
-	public var minX:Number, minY:Number, maxX:Number, maxY:Number;
-	
-	public function SkeletonBounds () {		
-	}
-
-	public function update (skeleton:Skeleton, updateAabb:Boolean) : void {
-		var slots:Vector.<Slot> = skeleton.slots;
-		var slotCount:int = slots.length;		
-
-		boundingBoxes.length = 0;
-		for each (var polygon:Polygon in polygons)
-			polygonPool[polygonPool.length] = polygon;
-		polygons.length = 0;
-
-		for (var i:int = 0; i < slotCount; i++) {
-			var slot:Slot = slots[i];
-			var boundingBox:BoundingBoxAttachment = slot.attachment as BoundingBoxAttachment;
-			if (boundingBox == null) continue;
-			boundingBoxes[boundingBoxes.length] = boundingBox;
-
-			var poolCount:int = polygonPool.length;
-			if (poolCount > 0) {
-				polygon = polygonPool[poolCount - 1];
-				polygonPool.splice(poolCount - 1, 1);
-			} else
-				polygon = new Polygon();
-			polygons[polygons.length] = polygon;
-
-			polygon.vertices.length = boundingBox.worldVerticesLength;
-			boundingBox.computeWorldVertices(slot, polygon.vertices);
-		}
-
-		if (updateAabb) aabbCompute();
-	}
-
-	private function aabbCompute () : void {
-		var minX:Number = Number.MAX_VALUE, minY:Number = Number.MAX_VALUE;
-		var maxX:Number = -Number.MAX_VALUE, maxY:Number = -Number.MAX_VALUE;
-		for (var i:int = 0, n:int = polygons.length; i < n; i++) {
-			var polygon:Polygon = polygons[i];
-			var vertices:Vector.<Number> = polygon.vertices;
-			for (var ii:int = 0, nn:int = vertices.length; ii < nn; ii += 2) {
-				var x:Number = vertices[ii];
-				var y:Number = vertices[ii + 1];
-				minX = Math.min(minX, x);
-				minY = Math.min(minY, y);
-				maxX = Math.max(maxX, x);
-				maxY = Math.max(maxY, y);
-			}
-		}
-		this.minX = minX;
-		this.minY = minY;
-		this.maxX = maxX;
-		this.maxY = maxY;
-	}
-	
-	
-	/** Returns true if the axis aligned bounding box contains the point. */
-	public function aabbContainsPoint (x:Number, y:Number) : Boolean {
-		return x >= minX && x <= maxX && y >= minY && y <= maxY;
-	}
-	
-	/** Returns true if the axis aligned bounding box intersects the line segment. */
-	public function aabbIntersectsSegment (x1:Number, y1:Number, x2:Number, y2:Number) : Boolean {
-		if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY))
-			return false;
-		var m:Number = (y2 - y1) / (x2 - x1);
-		var y:Number = m * (minX - x1) + y1;
-		if (y > minY && y < maxY) return true;
-		y = m * (maxX - x1) + y1;
-		if (y > minY && y < maxY) return true;
-		var x:Number = (minY - y1) / m + x1;
-		if (x > minX && x < maxX) return true;
-		x = (maxY - y1) / m + x1;
-		if (x > minX && x < maxX) return true;
-		return false;
-	}
-	
-	/** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */
-	public function aabbIntersectsSkeleton (bounds:SkeletonBounds) : Boolean {
-		return minX < bounds.maxX && maxX > bounds.minX && minY < bounds.maxY && maxY > bounds.minY;
-	}
-	
-	/** Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more
-	 * efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true. */
-	public function containsPoint (x:Number, y:Number) : BoundingBoxAttachment {
-		for (var i:int = 0, n:int = polygons.length; i < n; i++)
-			if (polygons[i].containsPoint(x, y)) return boundingBoxes[i];
-		return null;
-	}
-	
-	/** Returns the first bounding box attachment that contains the line segment, or null. When doing many checks, it is usually
-	 * more efficient to only call this method if {@link #aabbIntersectsSegment(float, float, float, float)} returns true. */
-	public function intersectsSegment (x1:Number, y1:Number, x2:Number, y2:Number) : BoundingBoxAttachment {
-		for (var i:int = 0, n:int = polygons.length; i < n; i++)
-			if (polygons[i].intersectsSegment(x1, y1, x2, y2)) return boundingBoxes[i];
-		return null;
-	}
-
-	public function getPolygon (attachment:BoundingBoxAttachment) : Polygon {
-		var index:int = boundingBoxes.indexOf(attachment);
-		return index == -1 ? null : polygons[index];
-	}
-
-	public function get width () : Number {
-		return maxX - minX;
-	}
-	
-	public function get height () : Number {
-		return maxY - minY;
-	}
-}
-
+package spine {
+import spine.attachments.BoundingBoxAttachment;
+
+public class SkeletonBounds {
+	private var polygonPool:Vector.<Polygon> = new Vector.<Polygon>();
+
+	public var boundingBoxes:Vector.<BoundingBoxAttachment> = new Vector.<BoundingBoxAttachment>();
+	public var polygons:Vector.<Polygon> = new Vector.<Polygon>();
+	public var minX:Number, minY:Number, maxX:Number, maxY:Number;
+	
+	public function SkeletonBounds () {		
+	}
+
+	public function update (skeleton:Skeleton, updateAabb:Boolean) : void {
+		var slots:Vector.<Slot> = skeleton.slots;
+		var slotCount:int = slots.length;		
+
+		boundingBoxes.length = 0;
+		for each (var polygon:Polygon in polygons)
+			polygonPool[polygonPool.length] = polygon;
+		polygons.length = 0;
+
+		for (var i:int = 0; i < slotCount; i++) {
+			var slot:Slot = slots[i];
+			var boundingBox:BoundingBoxAttachment = slot.attachment as BoundingBoxAttachment;
+			if (boundingBox == null) continue;
+			boundingBoxes[boundingBoxes.length] = boundingBox;
+
+			var poolCount:int = polygonPool.length;
+			if (poolCount > 0) {
+				polygon = polygonPool[poolCount - 1];
+				polygonPool.splice(poolCount - 1, 1);
+			} else
+				polygon = new Polygon();
+			polygons[polygons.length] = polygon;
+
+			polygon.vertices.length = boundingBox.worldVerticesLength;
+			boundingBox.computeWorldVertices(slot, polygon.vertices);
+		}
+
+		if (updateAabb) aabbCompute();
+	}
+
+	private function aabbCompute () : void {
+		var minX:Number = Number.MAX_VALUE, minY:Number = Number.MAX_VALUE;
+		var maxX:Number = -Number.MAX_VALUE, maxY:Number = -Number.MAX_VALUE;
+		for (var i:int = 0, n:int = polygons.length; i < n; i++) {
+			var polygon:Polygon = polygons[i];
+			var vertices:Vector.<Number> = polygon.vertices;
+			for (var ii:int = 0, nn:int = vertices.length; ii < nn; ii += 2) {
+				var x:Number = vertices[ii];
+				var y:Number = vertices[ii + 1];
+				minX = Math.min(minX, x);
+				minY = Math.min(minY, y);
+				maxX = Math.max(maxX, x);
+				maxY = Math.max(maxY, y);
+			}
+		}
+		this.minX = minX;
+		this.minY = minY;
+		this.maxX = maxX;
+		this.maxY = maxY;
+	}
+	
+	
+	/** Returns true if the axis aligned bounding box contains the point. */
+	public function aabbContainsPoint (x:Number, y:Number) : Boolean {
+		return x >= minX && x <= maxX && y >= minY && y <= maxY;
+	}
+	
+	/** Returns true if the axis aligned bounding box intersects the line segment. */
+	public function aabbIntersectsSegment (x1:Number, y1:Number, x2:Number, y2:Number) : Boolean {
+		if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY))
+			return false;
+		var m:Number = (y2 - y1) / (x2 - x1);
+		var y:Number = m * (minX - x1) + y1;
+		if (y > minY && y < maxY) return true;
+		y = m * (maxX - x1) + y1;
+		if (y > minY && y < maxY) return true;
+		var x:Number = (minY - y1) / m + x1;
+		if (x > minX && x < maxX) return true;
+		x = (maxY - y1) / m + x1;
+		if (x > minX && x < maxX) return true;
+		return false;
+	}
+	
+	/** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */
+	public function aabbIntersectsSkeleton (bounds:SkeletonBounds) : Boolean {
+		return minX < bounds.maxX && maxX > bounds.minX && minY < bounds.maxY && maxY > bounds.minY;
+	}
+	
+	/** Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more
+	 * efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true. */
+	public function containsPoint (x:Number, y:Number) : BoundingBoxAttachment {
+		for (var i:int = 0, n:int = polygons.length; i < n; i++)
+			if (polygons[i].containsPoint(x, y)) return boundingBoxes[i];
+		return null;
+	}
+	
+	/** Returns the first bounding box attachment that contains the line segment, or null. When doing many checks, it is usually
+	 * more efficient to only call this method if {@link #aabbIntersectsSegment(float, float, float, float)} returns true. */
+	public function intersectsSegment (x1:Number, y1:Number, x2:Number, y2:Number) : BoundingBoxAttachment {
+		for (var i:int = 0, n:int = polygons.length; i < n; i++)
+			if (polygons[i].intersectsSegment(x1, y1, x2, y2)) return boundingBoxes[i];
+		return null;
+	}
+
+	public function getPolygon (attachment:BoundingBoxAttachment) : Polygon {
+		var index:int = boundingBoxes.indexOf(attachment);
+		return index == -1 ? null : polygons[index];
+	}
+
+	public function get width () : Number {
+		return maxX - minX;
+	}
+	
+	public function get height () : Number {
+		return maxY - minY;
+	}
+}
+
 }

+ 177 - 178
spine-as3/spine-as3/src/spine/SkeletonData.as

@@ -1,181 +1,180 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-import spine.animation.Animation;
-
-public class SkeletonData {
-	/** May be null. */
-	public var name:String;
-	public var bones:Vector.<BoneData> = new Vector.<BoneData>(); // Ordered parents first.
-	public var slots:Vector.<SlotData> = new Vector.<SlotData>(); // Setup pose draw order.
-	public var skins:Vector.<Skin> = new Vector.<Skin>();
-	public var defaultSkin:Skin;
-	public var events:Vector.<EventData> = new Vector.<EventData>();
-	public var animations:Vector.<Animation> = new Vector.<Animation>();
-	public var ikConstraints:Vector.<IkConstraintData> = new Vector.<IkConstraintData>();
-	public var transformConstraints:Vector.<TransformConstraintData> = new Vector.<TransformConstraintData>();
-	public var pathConstraints:Vector.<PathConstraintData> = new Vector.<PathConstraintData>();
-	public var width:Number, height:Number;
-	public var version:String, hash:String;
-	
-	public function SkeletonData () {		
-	}
-
-	// --- Bones.
-
-	/** @return May be null. */
-	public function findBone (boneName:String) : BoneData {
-		if (boneName == null) throw new ArgumentError("boneName cannot be null.");
-		for (var i:int = 0, n:int = bones.length; i < n; i++) {
-			var bone:BoneData = bones[i];
-			if (bone._name == boneName) return bone;
-		}
-		return null;
-	}
-
-	/** @return -1 if the bone was not found. */
-	public function findBoneIndex (boneName:String) : int {
-		if (boneName == null) throw new ArgumentError("boneName cannot be null.");
-		for (var i:int = 0, n:int = bones.length; i < n; i++)
-			if (bones[i]._name == boneName) return i;
-		return -1;
-	}
-
-	// --- Slots.
-
-	/** @return May be null. */
-	public function findSlot (slotName:String) : SlotData {
-		if (slotName == null) throw new ArgumentError("slotName cannot be null.");
-		for (var i:int = 0, n:int = slots.length; i < n; i++) {
-			var slot:SlotData = slots[i];
-			if (slot._name == slotName) return slot;
-		}
-		return null;
-	}
-
-	/** @return -1 if the bone was not found. */
-	public function findSlotIndex (slotName:String) : int {
-		if (slotName == null) throw new ArgumentError("slotName cannot be null.");
-		for (var i:int = 0, n:int = slots.length; i < n; i++)
-			if (slots[i]._name == slotName) return i;
-		return -1;
-	}
-
-	// --- Skins.
-
-	/** @return May be null. */
-	public function findSkin (skinName:String) : Skin {
-		if (skinName == null) throw new ArgumentError("skinName cannot be null.");
-		for each (var skin:Skin in skins)
-			if (skin._name == skinName) return skin;
-		return null;
-	}
-	
-	// --- Events.
-	
-	/** @return May be null. */
-	public function findEvent (eventName:String) : EventData {
-		if (eventName == null) throw new ArgumentError("eventName cannot be null.");
-		for each (var eventData:EventData in events)
-			if (eventData._name == eventName) return eventData;
-		return null;
-	}
-	
-	// --- Animations.
-	
-	/** @return May be null. */
-	public function findAnimation (animationName:String) : Animation {
-		if (animationName == null) throw new ArgumentError("animationName cannot be null.");
-		for each (var animation:Animation in animations)
-			if (animation.name == animationName) return animation;
-		return null;
-	}
-	
-	// --- IK constraints.
-
-	/** @return May be null. */
-	public function findIkConstraint (constraintName:String) : IkConstraintData {
-		if (constraintName == null) throw new ArgumentError("constraintName cannot be null.");
-		for each (var ikConstraintData:IkConstraintData in ikConstraints)
-			if (ikConstraintData._name == constraintName) return ikConstraintData;
-		return null;
-	}
-	
-	// --- Transform constraints.
-
-	/** @return May be null. */
-	public function findTransformConstraint (constraintName:String) : TransformConstraintData {
-		if (constraintName == null) throw new ArgumentError("constraintName cannot be null.");
-		for each (var transformConstraintData:TransformConstraintData in transformConstraints)
-			if (transformConstraintData._name == constraintName) return transformConstraintData;
-		return null;
-	}
-	
-	/** @return -1 if the transform constraint was not found. */
-	public function findTransformConstraintIndex (transformConstraintName:String) : int {
-		if (transformConstraintName == null) throw new ArgumentError("transformConstraintName cannot be null.");
-		var transformConstraints:Vector.<TransformConstraintData> = this.transformConstraints;
-		for (var i:int = 0, n:int = transformConstraints.length; i < n; i++)
-			if (transformConstraints[i].name == transformConstraintName) return i;
-		return -1;
-	}
-	
-	// --- Path constraints.
-	
-		/** @return May be null. */
-	public function findPathConstraint (constraintName:String) : PathConstraintData {
-		if (constraintName == null) throw new ArgumentError("constraintName cannot be null.");
-		var pathConstraints:Vector.<PathConstraintData> = this.pathConstraints;
-		for (var i:int = 0, n:int = pathConstraints.length; i < n; i++) {
-			var constraint:PathConstraintData = pathConstraints[i];
-			if (constraint.name == constraintName) return constraint;
-		}
-		return null;
-	}
-
-	/** @return -1 if the path constraint was not found. */
-	public function findPathConstraintIndex (pathConstraintName:String) : int {
-		if (pathConstraintName == null) throw new ArgumentError("pathConstraintName cannot be null.");
-		var pathConstraints:Vector.<PathConstraintData> = this.pathConstraints;
-		for (var i:int = 0, n:int = pathConstraints.length; i < n; i++)
-			if (pathConstraints[i].name == pathConstraintName) return i;
-		return -1;
-	}
-
-	// ---
-
-	public function toString () : String {
-		return name != null ? name : super.toString();
-	}
-}
-
+package spine {
+import spine.animation.Animation;
+
+public class SkeletonData {
+	/** May be null. */
+	public var name:String;
+	public var bones:Vector.<BoneData> = new Vector.<BoneData>(); // Ordered parents first.
+	public var slots:Vector.<SlotData> = new Vector.<SlotData>(); // Setup pose draw order.
+	public var skins:Vector.<Skin> = new Vector.<Skin>();
+	public var defaultSkin:Skin;
+	public var events:Vector.<EventData> = new Vector.<EventData>();
+	public var animations:Vector.<Animation> = new Vector.<Animation>();
+	public var ikConstraints:Vector.<IkConstraintData> = new Vector.<IkConstraintData>();
+	public var transformConstraints:Vector.<TransformConstraintData> = new Vector.<TransformConstraintData>();
+	public var pathConstraints:Vector.<PathConstraintData> = new Vector.<PathConstraintData>();
+	public var width:Number, height:Number;
+	public var version:String, hash:String;
+	
+	public function SkeletonData () {		
+	}
+
+	// --- Bones.
+
+	/** @return May be null. */
+	public function findBone (boneName:String) : BoneData {
+		if (boneName == null) throw new ArgumentError("boneName cannot be null.");
+		for (var i:int = 0, n:int = bones.length; i < n; i++) {
+			var bone:BoneData = bones[i];
+			if (bone._name == boneName) return bone;
+		}
+		return null;
+	}
+
+	/** @return -1 if the bone was not found. */
+	public function findBoneIndex (boneName:String) : int {
+		if (boneName == null) throw new ArgumentError("boneName cannot be null.");
+		for (var i:int = 0, n:int = bones.length; i < n; i++)
+			if (bones[i]._name == boneName) return i;
+		return -1;
+	}
+
+	// --- Slots.
+
+	/** @return May be null. */
+	public function findSlot (slotName:String) : SlotData {
+		if (slotName == null) throw new ArgumentError("slotName cannot be null.");
+		for (var i:int = 0, n:int = slots.length; i < n; i++) {
+			var slot:SlotData = slots[i];
+			if (slot._name == slotName) return slot;
+		}
+		return null;
+	}
+
+	/** @return -1 if the bone was not found. */
+	public function findSlotIndex (slotName:String) : int {
+		if (slotName == null) throw new ArgumentError("slotName cannot be null.");
+		for (var i:int = 0, n:int = slots.length; i < n; i++)
+			if (slots[i]._name == slotName) return i;
+		return -1;
+	}
+
+	// --- Skins.
+
+	/** @return May be null. */
+	public function findSkin (skinName:String) : Skin {
+		if (skinName == null) throw new ArgumentError("skinName cannot be null.");
+		for each (var skin:Skin in skins)
+			if (skin._name == skinName) return skin;
+		return null;
+	}
+	
+	// --- Events.
+	
+	/** @return May be null. */
+	public function findEvent (eventName:String) : EventData {
+		if (eventName == null) throw new ArgumentError("eventName cannot be null.");
+		for each (var eventData:EventData in events)
+			if (eventData._name == eventName) return eventData;
+		return null;
+	}
+	
+	// --- Animations.
+	
+	/** @return May be null. */
+	public function findAnimation (animationName:String) : Animation {
+		if (animationName == null) throw new ArgumentError("animationName cannot be null.");
+		for each (var animation:Animation in animations)
+			if (animation.name == animationName) return animation;
+		return null;
+	}
+	
+	// --- IK constraints.
+
+	/** @return May be null. */
+	public function findIkConstraint (constraintName:String) : IkConstraintData {
+		if (constraintName == null) throw new ArgumentError("constraintName cannot be null.");
+		for each (var ikConstraintData:IkConstraintData in ikConstraints)
+			if (ikConstraintData._name == constraintName) return ikConstraintData;
+		return null;
+	}
+	
+	// --- Transform constraints.
+
+	/** @return May be null. */
+	public function findTransformConstraint (constraintName:String) : TransformConstraintData {
+		if (constraintName == null) throw new ArgumentError("constraintName cannot be null.");
+		for each (var transformConstraintData:TransformConstraintData in transformConstraints)
+			if (transformConstraintData._name == constraintName) return transformConstraintData;
+		return null;
+	}
+	
+	/** @return -1 if the transform constraint was not found. */
+	public function findTransformConstraintIndex (transformConstraintName:String) : int {
+		if (transformConstraintName == null) throw new ArgumentError("transformConstraintName cannot be null.");
+		var transformConstraints:Vector.<TransformConstraintData> = this.transformConstraints;
+		for (var i:int = 0, n:int = transformConstraints.length; i < n; i++)
+			if (transformConstraints[i].name == transformConstraintName) return i;
+		return -1;
+	}
+	
+	// --- Path constraints.
+	
+		/** @return May be null. */
+	public function findPathConstraint (constraintName:String) : PathConstraintData {
+		if (constraintName == null) throw new ArgumentError("constraintName cannot be null.");
+		var pathConstraints:Vector.<PathConstraintData> = this.pathConstraints;
+		for (var i:int = 0, n:int = pathConstraints.length; i < n; i++) {
+			var constraint:PathConstraintData = pathConstraints[i];
+			if (constraint.name == constraintName) return constraint;
+		}
+		return null;
+	}
+
+	/** @return -1 if the path constraint was not found. */
+	public function findPathConstraintIndex (pathConstraintName:String) : int {
+		if (pathConstraintName == null) throw new ArgumentError("pathConstraintName cannot be null.");
+		var pathConstraints:Vector.<PathConstraintData> = this.pathConstraints;
+		for (var i:int = 0, n:int = pathConstraints.length; i < n; i++)
+			if (pathConstraints[i].name == pathConstraintName) return i;
+		return -1;
+	}
+
+	// ---
+
+	public function toString () : String {
+		return name != null ? name : super.toString();
+	}
+}
+
 }

+ 734 - 734
spine-as3/spine-as3/src/spine/SkeletonJson.as

@@ -1,737 +1,737 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
-package spine {
-import spine.animation.PathConstraintMixTimeline;
-import spine.animation.PathConstraintSpacingTimeline;
-import spine.animation.PathConstraintPositionTimeline;
-import spine.animation.TransformConstraintTimeline;
-import spine.animation.ShearTimeline;
-import spine.attachments.PathAttachment;
-import spine.attachments.VertexAttachment;
-import flash.utils.ByteArray;
 
-import spine.animation.Animation;
-import spine.animation.AttachmentTimeline;
-import spine.animation.ColorTimeline;
-import spine.animation.CurveTimeline;
-import spine.animation.DrawOrderTimeline;
-import spine.animation.EventTimeline;
-import spine.animation.DeformTimeline;
-import spine.animation.IkConstraintTimeline;
-import spine.animation.RotateTimeline;
-import spine.animation.ScaleTimeline;
-import spine.animation.Timeline;
-import spine.animation.TranslateTimeline;
-import spine.attachments.Attachment;
-import spine.attachments.AttachmentLoader;
-import spine.attachments.AttachmentType;
-import spine.attachments.BoundingBoxAttachment;
-import spine.attachments.MeshAttachment;
-import spine.attachments.RegionAttachment;
-
-public class SkeletonJson {
-	public var attachmentLoader:AttachmentLoader;
-	public var scale:Number = 1;
-	private var linkedMeshes:Vector.<LinkedMesh> = new Vector.<LinkedMesh>();
-
-	public function SkeletonJson (attachmentLoader:AttachmentLoader = null) {
-		this.attachmentLoader = attachmentLoader;
-	}
-
-	/** @param object A String or ByteArray. */
-	public function readSkeletonData (object:*, name:String = null) : SkeletonData {
-		if (object == null) throw new ArgumentError("object cannot be null.");
-
-		var root:Object;
-		if (object is String)
-			root = JSON.parse(String(object));
-		else if (object is ByteArray)
-			root = JSON.parse(ByteArray(object).readUTFBytes(ByteArray(object).length));
-		else if (object is Object)
-			root = object;
-		else
-			throw new ArgumentError("object must be a String, ByteArray or Object.");
-
-		var skeletonData:SkeletonData = new SkeletonData();
-		skeletonData.name = name;
-
-		// Skeleton.
-		var skeletonMap:Object = root["skeleton"];
-		if (skeletonMap) {
-			skeletonData.hash = skeletonMap["hash"];
-			skeletonData.version = skeletonMap["spine"];
-			skeletonData.width = skeletonMap["width"] || 0;
-			skeletonData.height = skeletonMap["height"] || 0;			
-		}			
-
-		// Bones.
-		var boneData:BoneData;
-		for each (var boneMap:Object in root["bones"]) {
-			var parent:BoneData = null;
-			var parentName:String = boneMap["parent"];
-			if (parentName) {
-				parent = skeletonData.findBone(parentName);
-				if (!parent) throw new Error("Parent bone not found: " + parentName);
-			}
-			boneData = new BoneData(skeletonData.bones.length, boneMap["name"], parent);
-			boneData.length = Number(boneMap["length"] || 0) * scale;
-			boneData.x = Number(boneMap["x"] || 0) * scale;
-			boneData.y = Number(boneMap["y"] || 0) * scale;
-			boneData.rotation = (boneMap["rotation"] || 0);
-			boneData.scaleX = boneMap.hasOwnProperty("scaleX") ? boneMap["scaleX"] : 1;
-			boneData.scaleY = boneMap.hasOwnProperty("scaleY") ? boneMap["scaleY"] : 1;
-			boneData.shearX = Number(boneMap["shearX"] || 0);
-			boneData.shearY = Number(boneMap["shearY"] || 0);
-			boneData.inheritRotation = boneMap.hasOwnProperty("inheritRotation") ? Boolean(boneMap["inheritRotation"]) : true;
-			boneData.inheritScale = boneMap.hasOwnProperty("inheritScale") ? Boolean(boneMap["inheritScale"]) : true;			
-			skeletonData.bones.push(boneData);
-		}
-		
-		// Slots.
-		for each (var slotMap:Object in root["slots"]) {
-			var slotName:String = slotMap["name"];
-			var boneName:String = slotMap["bone"];
-			boneData = skeletonData.findBone(boneName);
-			if (!boneData) throw new Error("Slot bone not found: " + boneName);
-			var slotData:SlotData = new SlotData(skeletonData.slots.length, slotName, boneData);
-
-			var color:String = slotMap["color"];
-			if (color) {
-				slotData.r = toColor(color, 0);
-				slotData.g = toColor(color, 1);
-				slotData.b = toColor(color, 2);
-				slotData.a = toColor(color, 3);
-			}
-
-			slotData.attachmentName = slotMap["attachment"];
-			slotData.blendMode = BlendMode[slotMap["blend"] || "normal"];
-			skeletonData.slots.push(slotData);
-		}
-
-		// IK constraints.
-		for each (var constraintMap:Object in root["ik"]) {
-			var ikConstraintData:IkConstraintData = new IkConstraintData(constraintMap["name"]);
-
-			for each (boneName in constraintMap["bones"]) {
-				var bone:BoneData = skeletonData.findBone(boneName);
-				if (!bone) throw new Error("IK constraint bone not found: " + boneName);
-				ikConstraintData.bones.push(bone);
-			}
-
-			ikConstraintData.target = skeletonData.findBone(constraintMap["target"]);
-			if (!ikConstraintData.target) throw new Error("Target bone not found: " + constraintMap["target"]);
-
-			ikConstraintData.bendDirection = (!constraintMap.hasOwnProperty("bendPositive") || constraintMap["bendPositive"]) ? 1 : -1;
-			ikConstraintData.mix = constraintMap.hasOwnProperty("mix") ? constraintMap["mix"] : 1;
-
-			skeletonData.ikConstraints.push(ikConstraintData);
-		}
-
-		// Transform constraints.
-		for each (constraintMap in root["transform"]) {
-			var transformConstraintData:TransformConstraintData = new TransformConstraintData(constraintMap["name"]);
-
-			for each (boneName in constraintMap["bones"]) {
-				bone = skeletonData.findBone(boneName);
-				if (!bone) throw new Error("Transform constraint bone not found: " + boneName);
-				transformConstraintData.bones.push(bone);
-			}
-		
-			transformConstraintData.target = skeletonData.findBone(constraintMap["target"]);
-			if (!transformConstraintData.target) throw new Error("Target bone not found: " + constraintMap["target"]);
-			
-			transformConstraintData.offsetRotation = Number(constraintMap["rotation"] || 0);
-			transformConstraintData.offsetX = Number(constraintMap["x"] || 0) * scale;
-			transformConstraintData.offsetY = Number(constraintMap["y"] || 0) * scale;
-			transformConstraintData.offsetScaleX = Number(constraintMap["scaleX"] || 0);
-			transformConstraintData.offsetScaleY = Number(constraintMap["scaleY"] || 0);
-			transformConstraintData.offsetShearY = Number(constraintMap["shearY"] || 0);
-			
-			transformConstraintData.rotateMix = constraintMap.hasOwnProperty("rotateMix") ? constraintMap["rotateMix"] : 1;
-			transformConstraintData.translateMix = constraintMap.hasOwnProperty("translateMix") ? constraintMap["translateMix"] : 1;
-			transformConstraintData.scaleMix = constraintMap.hasOwnProperty("scaleMix") ? constraintMap["scaleMix"] : 1;
-			transformConstraintData.shearMix = constraintMap.hasOwnProperty("shearMix") ? constraintMap["shearMix"] : 1;
-
-			skeletonData.transformConstraints.push(transformConstraintData);
-		}
-		
-		// Path constraints.
-		for each (constraintMap in root["path"]) {
-			var pathConstraintData:PathConstraintData = new PathConstraintData(constraintMap["name"]);
-
-			for each (boneName in constraintMap["bones"]) {
-				bone = skeletonData.findBone(boneName);
-				if (!bone) throw new Error("Path constraint bone not found: " + boneName);
-				pathConstraintData.bones.push(bone);
-			}
-		
-			pathConstraintData.target = skeletonData.findSlot(constraintMap["target"]);
-			if (!pathConstraintData.target) throw new Error("Path target slot not found: " + constraintMap["target"]);
-
-			pathConstraintData.positionMode = PositionMode[constraintMap["positionMode"] || "percent"];
-			pathConstraintData.spacingMode = SpacingMode[constraintMap["spacingMode"] || "length"];
-			pathConstraintData.rotateMode = RotateMode[constraintMap["rotateMode"] || "tangent"];
-			pathConstraintData.offsetRotation = Number(constraintMap["rotation"] || 0);
-			pathConstraintData.position = Number(constraintMap["position"] || 0);
-			if (pathConstraintData.positionMode == PositionMode.fixed) pathConstraintData.position *= scale;
-			pathConstraintData.spacing = Number(constraintMap["spacing"] || 0);
-			if (pathConstraintData.spacingMode == SpacingMode.length || pathConstraintData.spacingMode == SpacingMode.fixed) pathConstraintData.spacing *= scale;
-			pathConstraintData.rotateMix = constraintMap.hasOwnProperty("rotateMix") ? constraintMap["rotateMix"] : 1;
-			pathConstraintData.translateMix = constraintMap.hasOwnProperty("translateMix") ? constraintMap["translateMix"] : 1;
-
-			skeletonData.pathConstraints.push(pathConstraintData);
-		}
-
-		// Skins.
-		var skins:Object = root["skins"];
-		for (var skinName:String in skins) {
-			var skinMap:Object = skins[skinName];
-			var skin:Skin = new Skin(skinName);
-			for (slotName in skinMap) {
-				var slotIndex:int = skeletonData.findSlotIndex(slotName);
-				var slotEntry:Object = skinMap[slotName];
-				for (var attachmentName:String in slotEntry) {
-					var attachment:Attachment = readAttachment(slotEntry[attachmentName], skin, slotIndex, attachmentName);
-					if (attachment != null)
-						skin.addAttachment(slotIndex, attachmentName, attachment);
-				}
-			}
-			skeletonData.skins[skeletonData.skins.length] = skin;
-			if (skin.name == "default")
-				skeletonData.defaultSkin = skin;
-		}
-
-		// Linked meshes.
-		var linkedMeshes:Vector.<LinkedMesh> = this.linkedMeshes;
-		for each (var linkedMesh:LinkedMesh in linkedMeshes) {
-			var parentSkin:Skin = !linkedMesh.skin ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin);
-			if (!parentSkin) throw new Error("Skin not found: " + linkedMesh.skin);
-			var parentMesh:Attachment = parentSkin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);
-			if (!parentMesh) throw new Error("Parent mesh not found: " + linkedMesh.parent);
-			linkedMesh.mesh.parentMesh = MeshAttachment(parentMesh);
-			linkedMesh.mesh.updateUVs();
-		}
-		linkedMeshes.length = 0;
-
-		// Events.
-		var events:Object = root["events"];
-		if (events) {
-			for (var eventName:String in events) {
-				var eventMap:Object = events[eventName];
-				var eventData:EventData = new EventData(eventName);
-				eventData.intValue = eventMap["int"] || 0;
-				eventData.floatValue = eventMap["float"] || 0;
-				eventData.stringValue = eventMap["string"] || null;
-				skeletonData.events.push(eventData);
-			}
-		}
-
-		// Animations.
-		var animations:Object = root["animations"];
-		for (var animationName:String in animations)
-			readAnimation(animations[animationName], animationName, skeletonData);
-
-		return skeletonData;
-	}
-
-	private function readAttachment (map:Object, skin:Skin, slotIndex:int, name:String) : Attachment {
-		name = map["name"] || name;
-
-		var typeName:String = map["type"] || "region";		
-		var type:AttachmentType = AttachmentType[typeName];		
-
-		var scale:Number = this.scale;
-		var color:String;
-		switch (type) {
-			case AttachmentType.region:
-				var region:RegionAttachment = attachmentLoader.newRegionAttachment(skin, name, map["path"] || name);
-				if (!region) return null;
-				region.path = map["path"] || name;
-				region.x = Number(map["x"] || 0) * scale;
-				region.y = Number(map["y"] || 0) * scale;
-				region.scaleX = map.hasOwnProperty("scaleX") ? map["scaleX"] : 1;
-				region.scaleY = map.hasOwnProperty("scaleY") ? map["scaleY"] : 1;
-				region.rotation = map["rotation"] || 0;
-				region.width = Number(map["width"] || 0) * scale;
-				region.height = Number(map["height"] || 0) * scale;
-				color = map["color"];
-				if (color) {
-					region.r = toColor(color, 0);
-					region.g = toColor(color, 1);
-					region.b = toColor(color, 2);
-					region.a = toColor(color, 3);
-				}
-				region.updateOffset();
-				return region;
-			case AttachmentType.mesh:
-			case AttachmentType.linkedmesh:
-				var mesh:MeshAttachment = attachmentLoader.newMeshAttachment(skin, name, map["path"] || name);
-				if (!mesh) return null;
-				mesh.path = map["path"] || name;
-
-				color = map["color"];
-				if (color) {
-					mesh.r = toColor(color, 0);
-					mesh.g = toColor(color, 1);
-					mesh.b = toColor(color, 2);
-					mesh.a = toColor(color, 3);
-				}
-
-				mesh.width = Number(map["width"] || 0) * scale;
-				mesh.height = Number(map["height"] || 0) * scale;
-
-				if (map["parent"]) {
-					mesh.inheritDeform = map.hasOwnProperty("deform") ? Boolean(map["deform"]) : true;
-					linkedMeshes.push(new LinkedMesh(mesh, map["skin"], slotIndex, map["parent"]));
-					return mesh;
-				}
-				
-				var uvs:Vector.<Number> = getFloatArray(map, "uvs", 1);
-				readVertices(map, mesh, uvs.length);			
-				mesh.triangles = getUintArray(map, "triangles");	
-				mesh.regionUVs = uvs;									
-				mesh.updateUVs();
-
-				mesh.hullLength = int(map["hull"] || 0) * 2;
-				if (map["edges"]) mesh.edges = getIntArray(map, "edges");
-				return mesh;			
-			case AttachmentType.boundingbox:
-				var box:BoundingBoxAttachment = attachmentLoader.newBoundingBoxAttachment(skin, name);
-				if (!box) return null;
-				readVertices(map, box, int(map["vertexCount"]) << 1);								
-				return box;
-			case AttachmentType.path:
-				var path:PathAttachment = attachmentLoader.newPathAttachment(skin, name);
-				if (!path) return null;
-				path.closed = map.hasOwnProperty("closed") ? Boolean(map["closed"]) : false;
-				path.constantSpeed = map.hasOwnProperty("constantSpeed") ? Boolean(map["constantSpeed"]) : true;
-				
-				var vertexCount:int = int(map["vertexCount"]);
-				readVertices(map, path, vertexCount << 1);
-				
-				var lengths:Vector.<Number> = new Vector.<Number>();							
-				for each (var curves:Object in map["lengths"]) {
-					lengths.push(Number(curves) * scale);
-				}
-				path.lengths = lengths;				
-				return path;
-		}
-
-		return null;
-	}
-	
-	private function readVertices(map:Object, attachment:VertexAttachment, verticesLength:int) : void {
-		attachment.worldVerticesLength = verticesLength;
-		var vertices:Vector.<Number> = getFloatArray(map, "vertices", 1);
-		if (verticesLength == vertices.length) {
-			if (scale != 1) {
-				for (var i:int = 0, n:int = vertices.length; i < n; i++) {
-					vertices[i] *= scale;
-				}
-			}
-			attachment.vertices = vertices;
-			return;
-		}
-		
-		var weights:Vector.<Number> = new Vector.<Number>(verticesLength * 3 * 3);
-		weights.length = 0;
-		var bones:Vector.<int> = new Vector.<int>(verticesLength * 3);
-		bones.length = 0;
-		for (i = 0, n = vertices.length; i < n;) {
-			 var boneCount:int = int(vertices[i++]);
-			 bones.push(boneCount);
-			 for (var nn:int = i + boneCount * 4; i < nn; i+=4) {
-				bones.push(int(vertices[i]));
-				weights.push(vertices[i + 1] * scale);
-				weights.push(vertices[i + 2] * scale);
-				weights.push(vertices[i + 3]);
-			 }
-		}
-		attachment.bones = bones;
-		attachment.vertices = weights;
-	}
-
-	private function readAnimation (map:Object, name:String, skeletonData:SkeletonData) : void {
-		var scale:Number = this.scale;
-		var timelines:Vector.<Timeline> = new Vector.<Timeline>();
-		var duration:Number = 0;
-
-		var slotMap:Object, slotIndex:int, slotName:String;
-		var values:Array, valueMap:Object, frameIndex:int;
-		var i:int;
-		var timelineName:String;
-
-		var slots:Object = map["slots"];
-		for (slotName in slots) {
-			slotMap = slots[slotName];
-			slotIndex = skeletonData.findSlotIndex(slotName);
-
-			for (timelineName in slotMap) {
-				values = slotMap[timelineName];
-				if (timelineName == "color") {
-					var colorTimeline:ColorTimeline = new ColorTimeline(values.length);
-					colorTimeline.slotIndex = slotIndex;
-
-					frameIndex = 0;
-					for each (valueMap in values) {
-						var color:String = valueMap["color"];
-						var r:Number = toColor(color, 0);
-						var g:Number = toColor(color, 1);
-						var b:Number = toColor(color, 2);
-						var a:Number = toColor(color, 3);
-						colorTimeline.setFrame(frameIndex, valueMap["time"], r, g, b, a);
-						readCurve(valueMap, colorTimeline, frameIndex);
-						frameIndex++;
-					}
-					timelines[timelines.length] = colorTimeline;
-					duration = Math.max(duration, colorTimeline.frames[(colorTimeline.frameCount - 1) * ColorTimeline.ENTRIES]);
-				} else if (timelineName == "attachment") {
-					var attachmentTimeline:AttachmentTimeline = new AttachmentTimeline(values.length);
-					attachmentTimeline.slotIndex = slotIndex;
-
-					frameIndex = 0;
-					for each (valueMap in values)
-						attachmentTimeline.setFrame(frameIndex++, valueMap["time"], valueMap["name"]);
-					timelines[timelines.length] = attachmentTimeline;
-					duration = Math.max(duration, attachmentTimeline.frames[attachmentTimeline.frameCount - 1]);
-				} else
-					throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
-			}
-		}
-
-		var bones:Object = map["bones"];
-		for (var boneName:String in bones) {
-			var boneIndex:int = skeletonData.findBoneIndex(boneName);
-			if (boneIndex == -1) throw new Error("Bone not found: " + boneName);
-			var boneMap:Object = bones[boneName];
-
-			for (timelineName in boneMap) {
-				values = boneMap[timelineName];
-				if (timelineName == "rotate") {
-					var rotateTimeline:RotateTimeline = new RotateTimeline(values.length);
-					rotateTimeline.boneIndex = boneIndex;
-
-					frameIndex = 0;
-					for each (valueMap in values) {
-						rotateTimeline.setFrame(frameIndex, valueMap["time"], valueMap["angle"]);
-						readCurve(valueMap, rotateTimeline, frameIndex);
-						frameIndex++;
-					}
-					timelines[timelines.length] = rotateTimeline;
-					duration = Math.max(duration, rotateTimeline.frames[(rotateTimeline.frameCount - 1) * RotateTimeline.ENTRIES]);
-				} else if (timelineName == "translate" || timelineName == "scale" || timelineName == "shear") {
-					var translateTimeline:TranslateTimeline;
-					var timelineScale:Number = 1;
-					if (timelineName == "scale")
-						translateTimeline = new ScaleTimeline(values.length);
-					else if (timelineName == "shear")
-						translateTimeline = new ShearTimeline(values.length);
-					else {
-						translateTimeline = new TranslateTimeline(values.length);
-						timelineScale = scale;
-					}
-					translateTimeline.boneIndex = boneIndex;
-
-					frameIndex = 0;
-					for each (valueMap in values) {
-						var x:Number = Number(valueMap["x"] || 0) * timelineScale;
-						var y:Number = Number(valueMap["y"] || 0) * timelineScale;
-						translateTimeline.setFrame(frameIndex, valueMap["time"], x, y);
-						readCurve(valueMap, translateTimeline, frameIndex);
-						frameIndex++;
-					}
-					timelines[timelines.length] = translateTimeline;
-					duration = Math.max(duration, translateTimeline.frames[(translateTimeline.frameCount - 1) * TranslateTimeline.ENTRIES]);
-				} else
-					throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
-			}
-		}
-
-		var ikMap:Object = map["ik"];
-		for (var ikConstraintName:String in ikMap) {
-			var ikConstraint:IkConstraintData = skeletonData.findIkConstraint(ikConstraintName);
-			values = ikMap[ikConstraintName];
-			var ikTimeline:IkConstraintTimeline = new IkConstraintTimeline(values.length);
-			ikTimeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(ikConstraint);
-			frameIndex = 0;
-			for each (valueMap in values) {
-				var mix:Number = valueMap.hasOwnProperty("mix") ? valueMap["mix"] : 1;
-				var bendDirection:int = (!valueMap.hasOwnProperty("bendPositive") || valueMap["bendPositive"]) ? 1 : -1;
-				ikTimeline.setFrame(frameIndex, valueMap["time"], mix, bendDirection);
-				readCurve(valueMap, ikTimeline, frameIndex);
-				frameIndex++;
-			}
-			timelines[timelines.length] = ikTimeline;
-			duration = Math.max(duration, ikTimeline.frames[(ikTimeline.frameCount - 1) * IkConstraintTimeline.ENTRIES]);
-		}
-		
-		var transformMap:Object = map["transform"];
-		for (var transformName:String in transformMap) {
-			var transformConstraint:TransformConstraintData = skeletonData.findTransformConstraint(transformName);
-			values = transformMap[transformName];
-			var transformTimeline:TransformConstraintTimeline = new TransformConstraintTimeline(values.length);
-			transformTimeline.transformConstraintIndex = skeletonData.transformConstraints.indexOf(transformConstraint);
-			frameIndex = 0;
-			for each (valueMap in values) {
-				var rotateMix:Number = valueMap.hasOwnProperty("rotateMix") ? valueMap["rotateMix"] : 1;
-				var translateMix:Number = valueMap.hasOwnProperty("translateMix") ? valueMap["translateMix"] : 1;
-				var scaleMix:Number = valueMap.hasOwnProperty("scaleMix") ? valueMap["scaleMix"] : 1;
-				var shearMix:Number = valueMap.hasOwnProperty("shearMix") ? valueMap["shearMix"] : 1;
-				transformTimeline.setFrame(frameIndex, valueMap["time"], rotateMix, translateMix, scaleMix, shearMix);
-				readCurve(valueMap, transformTimeline, frameIndex);
-				frameIndex++;
-			}
-			timelines.push(transformTimeline);
-			duration = Math.max(duration, transformTimeline.frames[(transformTimeline.frameCount - 1) * TransformConstraintTimeline.ENTRIES]);
-		}
-				
-		// Path constraint timelines.
-		var paths:Object = map["paths"];
-		for (var pathName:String in paths) {
-			var index:int = skeletonData.findPathConstraintIndex(pathName);
-			if (index == -1) throw new Error("Path constraint not found: " + pathName);
-			var data:PathConstraintData = skeletonData.pathConstraints[index];
-			
-			var pathMap:Object = paths[pathName];
-			for (timelineName in pathMap) {
-				values = pathMap[timelineName];
-				
-				if (timelineName == "position" || timelineName == "spacing") {
-					var pathTimeline:PathConstraintPositionTimeline;
-					timelineScale = 1;
-					if (timelineName == "spacing") {
-						pathTimeline = new PathConstraintSpacingTimeline(values.length);
-						if (data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed) timelineScale = scale;
-					} else {
-						pathTimeline = new PathConstraintPositionTimeline(values.length);
-						if (data.positionMode == PositionMode.fixed) timelineScale = scale;
-					}
-					pathTimeline.pathConstraintIndex = index;
-					frameIndex = 0;
-					for each (valueMap in values) {
-						var value:Number = valueMap[timelineName] || 0;
-						pathTimeline.setFrame(frameIndex, valueMap["time"], value * timelineScale);
-						readCurve(valueMap, pathTimeline, frameIndex);
-						frameIndex++;
-					}
-					timelines.push(pathTimeline);
-					duration = Math.max(duration,
-						pathTimeline.frames[(pathTimeline.frameCount - 1) * PathConstraintPositionTimeline.ENTRIES]);
-				} else if (timelineName == "mix") {
-					var pathMixTimeline:PathConstraintMixTimeline = new PathConstraintMixTimeline(values.length);
-					pathMixTimeline.pathConstraintIndex = index;
-					frameIndex = 0;
-					for each (valueMap in values) {
-						rotateMix = valueMap.hasOwnProperty("rotateMix") ? valueMap["rotateMix"] : 1;
-						translateMix = valueMap.hasOwnProperty("translateMix") ? valueMap["translateMix"] : 1;
-						pathMixTimeline.setFrame(frameIndex, valueMap["time"], rotateMix, translateMix);
-						readCurve(valueMap, pathMixTimeline, frameIndex);
-						frameIndex++;
-					}
-					timelines.push(pathMixTimeline);
-					duration = Math.max(duration,
-						pathMixTimeline.frames[(pathMixTimeline.frameCount - 1) * PathConstraintMixTimeline.ENTRIES]);
-				}
-			}
-		}
-		
-		var deformMap:Object = map["deform"];
-		for (var skinName:String in deformMap) {
-			var skin:Skin = skeletonData.findSkin(skinName);
-			slotMap = deformMap[skinName];
-			for (slotName in slotMap) {
-				slotIndex = skeletonData.findSlotIndex(slotName);
-				var timelineMap:Object = slotMap[slotName];
-				for (timelineName in timelineMap) {
-					values = timelineMap[timelineName];
-
-					var attachment:VertexAttachment = skin.getAttachment(slotIndex, timelineName) as VertexAttachment;
-					if (attachment == null) throw new Error("Deform attachment not found: " + timelineName);
-					var weighted:Boolean = attachment.bones != null;
-					var vertices:Vector.<Number> = attachment.vertices;
-					var deformLength:int = weighted ? vertices.length / 3 * 2 : vertices.length;
-
-					var deformTimeline:DeformTimeline = new DeformTimeline(values.length);
-					deformTimeline.slotIndex = slotIndex;
-					deformTimeline.attachment = attachment;
-
-					frameIndex = 0;
-					for each (valueMap in values) {
-						var deform:Vector.<Number>;
-						var verticesValue:Object = valueMap["vertices"];
-						if (verticesValue == null)
-							deform = weighted ? new Vector.<Number>(deformLength, true) : vertices;
-						else {
-							deform = new Vector.<Number>(deformLength, true);
-							var start:int = Number(valueMap["offset"] || 0);
-							var temp:Vector.<Number> = getFloatArray(valueMap, "vertices", 1);
-							for (i = 0; i < temp.length; i++) {
-								deform[start + i] = temp[i];
-							}							
-							if (scale != 1) {
-								var n:int;
-								for (i = start, n = i + temp.length; i < n; i++)
-									deform[i] *= scale;
-							}
-							if (!weighted) {
-								for (i = 0; i < deformLength; i++)
-									deform[i] += vertices[i];
-							}
-						}
-
-						deformTimeline.setFrame(frameIndex, valueMap["time"], deform);
-						readCurve(valueMap, deformTimeline, frameIndex);
-						frameIndex++;
-					}
-					timelines[timelines.length] = deformTimeline;
-					duration = Math.max(duration, deformTimeline.frames[deformTimeline.frameCount - 1]);
-				}
-			}
-		}
-
-		var drawOrderValues:Array = map["drawOrder"];
-		if (!drawOrderValues) drawOrderValues = map["draworder"];
-		if (drawOrderValues) {
-			var drawOrderTimeline:DrawOrderTimeline = new DrawOrderTimeline(drawOrderValues.length);
-			var slotCount:int = skeletonData.slots.length;
-			frameIndex = 0;
-			for each (var drawOrderMap:Object in drawOrderValues) {
-				var drawOrder:Vector.<int> = null;
-				if (drawOrderMap["offsets"]) {
-					drawOrder = new Vector.<int>(slotCount);
-					for (i = slotCount - 1; i >= 0; i--)
-						drawOrder[i] = -1;
-					var offsets:Array = drawOrderMap["offsets"];
-					var unchanged:Vector.<int> = new Vector.<int>(slotCount - offsets.length);
-					var originalIndex:int = 0, unchangedIndex:int = 0;
-					for each (var offsetMap:Object in offsets) {
-						slotIndex = skeletonData.findSlotIndex(offsetMap["slot"]);
-						if (slotIndex == -1) throw new Error("Slot not found: " + offsetMap["slot"]);
-						// Collect unchanged items.
-						while (originalIndex != slotIndex)
-							unchanged[unchangedIndex++] = originalIndex++;
-						// Set changed items.
-						drawOrder[originalIndex + offsetMap["offset"]] = originalIndex++;
-					}
-					// Collect remaining unchanged items.
-					while (originalIndex < slotCount)
-						unchanged[unchangedIndex++] = originalIndex++;
-					// Fill in unchanged items.
-					for (i = slotCount - 1; i >= 0; i--)
-						if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex];
-				}
-				drawOrderTimeline.setFrame(frameIndex++, drawOrderMap["time"], drawOrder);
-			}
-			timelines[timelines.length] = drawOrderTimeline;
-			duration = Math.max(duration, drawOrderTimeline.frames[drawOrderTimeline.frameCount - 1]);
-		}
-
-		var eventsMap:Array = map["events"];
-		if (eventsMap) {
-			var eventTimeline:EventTimeline = new EventTimeline(eventsMap.length);
-			frameIndex = 0;
-			for each (var eventMap:Object in eventsMap) {
-				var eventData:EventData = skeletonData.findEvent(eventMap["name"]);
-				if (!eventData) throw new Error("Event not found: " + eventMap["name"]);
-				var event:Event = new Event(eventMap["time"], eventData);
-				event.intValue = eventMap.hasOwnProperty("int") ? eventMap["int"] : eventData.intValue;
-				event.floatValue = eventMap.hasOwnProperty("float") ? eventMap["float"] : eventData.floatValue;
-				event.stringValue = eventMap.hasOwnProperty("string") ? eventMap["string"] : eventData.stringValue;
-				eventTimeline.setFrame(frameIndex++, event);
-			}
-			timelines[timelines.length] = eventTimeline;
-			duration = Math.max(duration, eventTimeline.frames[eventTimeline.frameCount - 1]);
-		}
-
-		skeletonData.animations[skeletonData.animations.length] = new Animation(name, timelines, duration);
-	}
-
-	static private function readCurve (map:Object, timeline:CurveTimeline, frameIndex:int) : void {
-		var curve:Object = map["curve"];
-		if (!curve) return;
-		if (curve == "stepped")
-			timeline.setStepped(frameIndex);
-		else if (curve is Array)
-			timeline.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]);
-	}
-
-	static private function toColor (hexString:String, colorIndex:int) : Number {
-		if (hexString.length != 8) throw new ArgumentError("Color hexidecimal length must be 8, recieved: " + hexString);
-		return parseInt(hexString.substring(colorIndex * 2, colorIndex * 2 + 2), 16) / 255;
-	}
-
-	static private function getFloatArray (map:Object, name:String, scale:Number) : Vector.<Number> {
-		var list:Array = map[name];
-		var values:Vector.<Number> = new Vector.<Number>(list.length, true);
-		var i:int = 0, n:int = list.length;
-		if (scale == 1) {
-			for (; i < n; i++)
-				values[i] = list[i];
-		} else {
-			for (; i < n; i++)
-				values[i] = list[i] * scale;
-		}
-		return values;
-	}
-
-	static private function getIntArray (map:Object, name:String) : Vector.<int> {
-		var list:Array = map[name];
-		var values:Vector.<int> = new Vector.<int>(list.length, true);
-		for (var i:int = 0, n:int = list.length; i < n; i++)
-			values[i] = int(list[i]);
-		return values;
-	}
-
-	static private function getUintArray (map:Object, name:String) : Vector.<uint> {
-		var list:Array = map[name];
-		var values:Vector.<uint> = new Vector.<uint>(list.length, true);
-		for (var i:int = 0, n:int = list.length; i < n; i++)
-			values[i] = int(list[i]);
-		return values;
-	}
-}
-
-}
-
-import spine.attachments.MeshAttachment;
-
-internal class LinkedMesh {
-	internal var parent:String, skin:String;
-	internal var slotIndex:int;
-	internal var mesh:MeshAttachment;
-
-	public function LinkedMesh (mesh:MeshAttachment, skin:String, slotIndex:int, parent:String) {
-		this.mesh = mesh;
-		this.skin = skin;
-		this.slotIndex = slotIndex;
-		this.parent = parent;
-	}
+package spine {
+import spine.animation.PathConstraintMixTimeline;
+import spine.animation.PathConstraintSpacingTimeline;
+import spine.animation.PathConstraintPositionTimeline;
+import spine.animation.TransformConstraintTimeline;
+import spine.animation.ShearTimeline;
+import spine.attachments.PathAttachment;
+import spine.attachments.VertexAttachment;
+import flash.utils.ByteArray;
+
+import spine.animation.Animation;
+import spine.animation.AttachmentTimeline;
+import spine.animation.ColorTimeline;
+import spine.animation.CurveTimeline;
+import spine.animation.DrawOrderTimeline;
+import spine.animation.EventTimeline;
+import spine.animation.DeformTimeline;
+import spine.animation.IkConstraintTimeline;
+import spine.animation.RotateTimeline;
+import spine.animation.ScaleTimeline;
+import spine.animation.Timeline;
+import spine.animation.TranslateTimeline;
+import spine.attachments.Attachment;
+import spine.attachments.AttachmentLoader;
+import spine.attachments.AttachmentType;
+import spine.attachments.BoundingBoxAttachment;
+import spine.attachments.MeshAttachment;
+import spine.attachments.RegionAttachment;
+
+public class SkeletonJson {
+	public var attachmentLoader:AttachmentLoader;
+	public var scale:Number = 1;
+	private var linkedMeshes:Vector.<LinkedMesh> = new Vector.<LinkedMesh>();
+
+	public function SkeletonJson (attachmentLoader:AttachmentLoader = null) {
+		this.attachmentLoader = attachmentLoader;
+	}
+
+	/** @param object A String or ByteArray. */
+	public function readSkeletonData (object:*, name:String = null) : SkeletonData {
+		if (object == null) throw new ArgumentError("object cannot be null.");
+
+		var root:Object;
+		if (object is String)
+			root = JSON.parse(String(object));
+		else if (object is ByteArray)
+			root = JSON.parse(ByteArray(object).readUTFBytes(ByteArray(object).length));
+		else if (object is Object)
+			root = object;
+		else
+			throw new ArgumentError("object must be a String, ByteArray or Object.");
+
+		var skeletonData:SkeletonData = new SkeletonData();
+		skeletonData.name = name;
+
+		// Skeleton.
+		var skeletonMap:Object = root["skeleton"];
+		if (skeletonMap) {
+			skeletonData.hash = skeletonMap["hash"];
+			skeletonData.version = skeletonMap["spine"];
+			skeletonData.width = skeletonMap["width"] || 0;
+			skeletonData.height = skeletonMap["height"] || 0;			
+		}			
+
+		// Bones.
+		var boneData:BoneData;
+		for each (var boneMap:Object in root["bones"]) {
+			var parent:BoneData = null;
+			var parentName:String = boneMap["parent"];
+			if (parentName) {
+				parent = skeletonData.findBone(parentName);
+				if (!parent) throw new Error("Parent bone not found: " + parentName);
+			}
+			boneData = new BoneData(skeletonData.bones.length, boneMap["name"], parent);
+			boneData.length = Number(boneMap["length"] || 0) * scale;
+			boneData.x = Number(boneMap["x"] || 0) * scale;
+			boneData.y = Number(boneMap["y"] || 0) * scale;
+			boneData.rotation = (boneMap["rotation"] || 0);
+			boneData.scaleX = boneMap.hasOwnProperty("scaleX") ? boneMap["scaleX"] : 1;
+			boneData.scaleY = boneMap.hasOwnProperty("scaleY") ? boneMap["scaleY"] : 1;
+			boneData.shearX = Number(boneMap["shearX"] || 0);
+			boneData.shearY = Number(boneMap["shearY"] || 0);
+			boneData.inheritRotation = boneMap.hasOwnProperty("inheritRotation") ? Boolean(boneMap["inheritRotation"]) : true;
+			boneData.inheritScale = boneMap.hasOwnProperty("inheritScale") ? Boolean(boneMap["inheritScale"]) : true;			
+			skeletonData.bones.push(boneData);
+		}
+		
+		// Slots.
+		for each (var slotMap:Object in root["slots"]) {
+			var slotName:String = slotMap["name"];
+			var boneName:String = slotMap["bone"];
+			boneData = skeletonData.findBone(boneName);
+			if (!boneData) throw new Error("Slot bone not found: " + boneName);
+			var slotData:SlotData = new SlotData(skeletonData.slots.length, slotName, boneData);
+
+			var color:String = slotMap["color"];
+			if (color) {
+				slotData.r = toColor(color, 0);
+				slotData.g = toColor(color, 1);
+				slotData.b = toColor(color, 2);
+				slotData.a = toColor(color, 3);
+			}
+
+			slotData.attachmentName = slotMap["attachment"];
+			slotData.blendMode = BlendMode[slotMap["blend"] || "normal"];
+			skeletonData.slots.push(slotData);
+		}
+
+		// IK constraints.
+		for each (var constraintMap:Object in root["ik"]) {
+			var ikConstraintData:IkConstraintData = new IkConstraintData(constraintMap["name"]);
+
+			for each (boneName in constraintMap["bones"]) {
+				var bone:BoneData = skeletonData.findBone(boneName);
+				if (!bone) throw new Error("IK constraint bone not found: " + boneName);
+				ikConstraintData.bones.push(bone);
+			}
+
+			ikConstraintData.target = skeletonData.findBone(constraintMap["target"]);
+			if (!ikConstraintData.target) throw new Error("Target bone not found: " + constraintMap["target"]);
+
+			ikConstraintData.bendDirection = (!constraintMap.hasOwnProperty("bendPositive") || constraintMap["bendPositive"]) ? 1 : -1;
+			ikConstraintData.mix = constraintMap.hasOwnProperty("mix") ? constraintMap["mix"] : 1;
+
+			skeletonData.ikConstraints.push(ikConstraintData);
+		}
+
+		// Transform constraints.
+		for each (constraintMap in root["transform"]) {
+			var transformConstraintData:TransformConstraintData = new TransformConstraintData(constraintMap["name"]);
+
+			for each (boneName in constraintMap["bones"]) {
+				bone = skeletonData.findBone(boneName);
+				if (!bone) throw new Error("Transform constraint bone not found: " + boneName);
+				transformConstraintData.bones.push(bone);
+			}
+		
+			transformConstraintData.target = skeletonData.findBone(constraintMap["target"]);
+			if (!transformConstraintData.target) throw new Error("Target bone not found: " + constraintMap["target"]);
+			
+			transformConstraintData.offsetRotation = Number(constraintMap["rotation"] || 0);
+			transformConstraintData.offsetX = Number(constraintMap["x"] || 0) * scale;
+			transformConstraintData.offsetY = Number(constraintMap["y"] || 0) * scale;
+			transformConstraintData.offsetScaleX = Number(constraintMap["scaleX"] || 0);
+			transformConstraintData.offsetScaleY = Number(constraintMap["scaleY"] || 0);
+			transformConstraintData.offsetShearY = Number(constraintMap["shearY"] || 0);
+			
+			transformConstraintData.rotateMix = constraintMap.hasOwnProperty("rotateMix") ? constraintMap["rotateMix"] : 1;
+			transformConstraintData.translateMix = constraintMap.hasOwnProperty("translateMix") ? constraintMap["translateMix"] : 1;
+			transformConstraintData.scaleMix = constraintMap.hasOwnProperty("scaleMix") ? constraintMap["scaleMix"] : 1;
+			transformConstraintData.shearMix = constraintMap.hasOwnProperty("shearMix") ? constraintMap["shearMix"] : 1;
+
+			skeletonData.transformConstraints.push(transformConstraintData);
+		}
+		
+		// Path constraints.
+		for each (constraintMap in root["path"]) {
+			var pathConstraintData:PathConstraintData = new PathConstraintData(constraintMap["name"]);
+
+			for each (boneName in constraintMap["bones"]) {
+				bone = skeletonData.findBone(boneName);
+				if (!bone) throw new Error("Path constraint bone not found: " + boneName);
+				pathConstraintData.bones.push(bone);
+			}
+		
+			pathConstraintData.target = skeletonData.findSlot(constraintMap["target"]);
+			if (!pathConstraintData.target) throw new Error("Path target slot not found: " + constraintMap["target"]);
+
+			pathConstraintData.positionMode = PositionMode[constraintMap["positionMode"] || "percent"];
+			pathConstraintData.spacingMode = SpacingMode[constraintMap["spacingMode"] || "length"];
+			pathConstraintData.rotateMode = RotateMode[constraintMap["rotateMode"] || "tangent"];
+			pathConstraintData.offsetRotation = Number(constraintMap["rotation"] || 0);
+			pathConstraintData.position = Number(constraintMap["position"] || 0);
+			if (pathConstraintData.positionMode == PositionMode.fixed) pathConstraintData.position *= scale;
+			pathConstraintData.spacing = Number(constraintMap["spacing"] || 0);
+			if (pathConstraintData.spacingMode == SpacingMode.length || pathConstraintData.spacingMode == SpacingMode.fixed) pathConstraintData.spacing *= scale;
+			pathConstraintData.rotateMix = constraintMap.hasOwnProperty("rotateMix") ? constraintMap["rotateMix"] : 1;
+			pathConstraintData.translateMix = constraintMap.hasOwnProperty("translateMix") ? constraintMap["translateMix"] : 1;
+
+			skeletonData.pathConstraints.push(pathConstraintData);
+		}
+
+		// Skins.
+		var skins:Object = root["skins"];
+		for (var skinName:String in skins) {
+			var skinMap:Object = skins[skinName];
+			var skin:Skin = new Skin(skinName);
+			for (slotName in skinMap) {
+				var slotIndex:int = skeletonData.findSlotIndex(slotName);
+				var slotEntry:Object = skinMap[slotName];
+				for (var attachmentName:String in slotEntry) {
+					var attachment:Attachment = readAttachment(slotEntry[attachmentName], skin, slotIndex, attachmentName);
+					if (attachment != null)
+						skin.addAttachment(slotIndex, attachmentName, attachment);
+				}
+			}
+			skeletonData.skins[skeletonData.skins.length] = skin;
+			if (skin.name == "default")
+				skeletonData.defaultSkin = skin;
+		}
+
+		// Linked meshes.
+		var linkedMeshes:Vector.<LinkedMesh> = this.linkedMeshes;
+		for each (var linkedMesh:LinkedMesh in linkedMeshes) {
+			var parentSkin:Skin = !linkedMesh.skin ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin);
+			if (!parentSkin) throw new Error("Skin not found: " + linkedMesh.skin);
+			var parentMesh:Attachment = parentSkin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);
+			if (!parentMesh) throw new Error("Parent mesh not found: " + linkedMesh.parent);
+			linkedMesh.mesh.parentMesh = MeshAttachment(parentMesh);
+			linkedMesh.mesh.updateUVs();
+		}
+		linkedMeshes.length = 0;
+
+		// Events.
+		var events:Object = root["events"];
+		if (events) {
+			for (var eventName:String in events) {
+				var eventMap:Object = events[eventName];
+				var eventData:EventData = new EventData(eventName);
+				eventData.intValue = eventMap["int"] || 0;
+				eventData.floatValue = eventMap["float"] || 0;
+				eventData.stringValue = eventMap["string"] || null;
+				skeletonData.events.push(eventData);
+			}
+		}
+
+		// Animations.
+		var animations:Object = root["animations"];
+		for (var animationName:String in animations)
+			readAnimation(animations[animationName], animationName, skeletonData);
+
+		return skeletonData;
+	}
+
+	private function readAttachment (map:Object, skin:Skin, slotIndex:int, name:String) : Attachment {
+		name = map["name"] || name;
+
+		var typeName:String = map["type"] || "region";		
+		var type:AttachmentType = AttachmentType[typeName];		
+
+		var scale:Number = this.scale;
+		var color:String;
+		switch (type) {
+			case AttachmentType.region:
+				var region:RegionAttachment = attachmentLoader.newRegionAttachment(skin, name, map["path"] || name);
+				if (!region) return null;
+				region.path = map["path"] || name;
+				region.x = Number(map["x"] || 0) * scale;
+				region.y = Number(map["y"] || 0) * scale;
+				region.scaleX = map.hasOwnProperty("scaleX") ? map["scaleX"] : 1;
+				region.scaleY = map.hasOwnProperty("scaleY") ? map["scaleY"] : 1;
+				region.rotation = map["rotation"] || 0;
+				region.width = Number(map["width"] || 0) * scale;
+				region.height = Number(map["height"] || 0) * scale;
+				color = map["color"];
+				if (color) {
+					region.r = toColor(color, 0);
+					region.g = toColor(color, 1);
+					region.b = toColor(color, 2);
+					region.a = toColor(color, 3);
+				}
+				region.updateOffset();
+				return region;
+			case AttachmentType.mesh:
+			case AttachmentType.linkedmesh:
+				var mesh:MeshAttachment = attachmentLoader.newMeshAttachment(skin, name, map["path"] || name);
+				if (!mesh) return null;
+				mesh.path = map["path"] || name;
+
+				color = map["color"];
+				if (color) {
+					mesh.r = toColor(color, 0);
+					mesh.g = toColor(color, 1);
+					mesh.b = toColor(color, 2);
+					mesh.a = toColor(color, 3);
+				}
+
+				mesh.width = Number(map["width"] || 0) * scale;
+				mesh.height = Number(map["height"] || 0) * scale;
+
+				if (map["parent"]) {
+					mesh.inheritDeform = map.hasOwnProperty("deform") ? Boolean(map["deform"]) : true;
+					linkedMeshes.push(new LinkedMesh(mesh, map["skin"], slotIndex, map["parent"]));
+					return mesh;
+				}
+				
+				var uvs:Vector.<Number> = getFloatArray(map, "uvs", 1);
+				readVertices(map, mesh, uvs.length);			
+				mesh.triangles = getUintArray(map, "triangles");	
+				mesh.regionUVs = uvs;									
+				mesh.updateUVs();
+
+				mesh.hullLength = int(map["hull"] || 0) * 2;
+				if (map["edges"]) mesh.edges = getIntArray(map, "edges");
+				return mesh;			
+			case AttachmentType.boundingbox:
+				var box:BoundingBoxAttachment = attachmentLoader.newBoundingBoxAttachment(skin, name);
+				if (!box) return null;
+				readVertices(map, box, int(map["vertexCount"]) << 1);								
+				return box;
+			case AttachmentType.path:
+				var path:PathAttachment = attachmentLoader.newPathAttachment(skin, name);
+				if (!path) return null;
+				path.closed = map.hasOwnProperty("closed") ? Boolean(map["closed"]) : false;
+				path.constantSpeed = map.hasOwnProperty("constantSpeed") ? Boolean(map["constantSpeed"]) : true;
+				
+				var vertexCount:int = int(map["vertexCount"]);
+				readVertices(map, path, vertexCount << 1);
+				
+				var lengths:Vector.<Number> = new Vector.<Number>();							
+				for each (var curves:Object in map["lengths"]) {
+					lengths.push(Number(curves) * scale);
+				}
+				path.lengths = lengths;				
+				return path;
+		}
+
+		return null;
+	}
+	
+	private function readVertices(map:Object, attachment:VertexAttachment, verticesLength:int) : void {
+		attachment.worldVerticesLength = verticesLength;
+		var vertices:Vector.<Number> = getFloatArray(map, "vertices", 1);
+		if (verticesLength == vertices.length) {
+			if (scale != 1) {
+				for (var i:int = 0, n:int = vertices.length; i < n; i++) {
+					vertices[i] *= scale;
+				}
+			}
+			attachment.vertices = vertices;
+			return;
+		}
+		
+		var weights:Vector.<Number> = new Vector.<Number>(verticesLength * 3 * 3);
+		weights.length = 0;
+		var bones:Vector.<int> = new Vector.<int>(verticesLength * 3);
+		bones.length = 0;
+		for (i = 0, n = vertices.length; i < n;) {
+			 var boneCount:int = int(vertices[i++]);
+			 bones.push(boneCount);
+			 for (var nn:int = i + boneCount * 4; i < nn; i+=4) {
+				bones.push(int(vertices[i]));
+				weights.push(vertices[i + 1] * scale);
+				weights.push(vertices[i + 2] * scale);
+				weights.push(vertices[i + 3]);
+			 }
+		}
+		attachment.bones = bones;
+		attachment.vertices = weights;
+	}
+
+	private function readAnimation (map:Object, name:String, skeletonData:SkeletonData) : void {
+		var scale:Number = this.scale;
+		var timelines:Vector.<Timeline> = new Vector.<Timeline>();
+		var duration:Number = 0;
+
+		var slotMap:Object, slotIndex:int, slotName:String;
+		var values:Array, valueMap:Object, frameIndex:int;
+		var i:int;
+		var timelineName:String;
+
+		var slots:Object = map["slots"];
+		for (slotName in slots) {
+			slotMap = slots[slotName];
+			slotIndex = skeletonData.findSlotIndex(slotName);
+
+			for (timelineName in slotMap) {
+				values = slotMap[timelineName];
+				if (timelineName == "color") {
+					var colorTimeline:ColorTimeline = new ColorTimeline(values.length);
+					colorTimeline.slotIndex = slotIndex;
+
+					frameIndex = 0;
+					for each (valueMap in values) {
+						var color:String = valueMap["color"];
+						var r:Number = toColor(color, 0);
+						var g:Number = toColor(color, 1);
+						var b:Number = toColor(color, 2);
+						var a:Number = toColor(color, 3);
+						colorTimeline.setFrame(frameIndex, valueMap["time"], r, g, b, a);
+						readCurve(valueMap, colorTimeline, frameIndex);
+						frameIndex++;
+					}
+					timelines[timelines.length] = colorTimeline;
+					duration = Math.max(duration, colorTimeline.frames[(colorTimeline.frameCount - 1) * ColorTimeline.ENTRIES]);
+				} else if (timelineName == "attachment") {
+					var attachmentTimeline:AttachmentTimeline = new AttachmentTimeline(values.length);
+					attachmentTimeline.slotIndex = slotIndex;
+
+					frameIndex = 0;
+					for each (valueMap in values)
+						attachmentTimeline.setFrame(frameIndex++, valueMap["time"], valueMap["name"]);
+					timelines[timelines.length] = attachmentTimeline;
+					duration = Math.max(duration, attachmentTimeline.frames[attachmentTimeline.frameCount - 1]);
+				} else
+					throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
+			}
+		}
+
+		var bones:Object = map["bones"];
+		for (var boneName:String in bones) {
+			var boneIndex:int = skeletonData.findBoneIndex(boneName);
+			if (boneIndex == -1) throw new Error("Bone not found: " + boneName);
+			var boneMap:Object = bones[boneName];
+
+			for (timelineName in boneMap) {
+				values = boneMap[timelineName];
+				if (timelineName == "rotate") {
+					var rotateTimeline:RotateTimeline = new RotateTimeline(values.length);
+					rotateTimeline.boneIndex = boneIndex;
+
+					frameIndex = 0;
+					for each (valueMap in values) {
+						rotateTimeline.setFrame(frameIndex, valueMap["time"], valueMap["angle"]);
+						readCurve(valueMap, rotateTimeline, frameIndex);
+						frameIndex++;
+					}
+					timelines[timelines.length] = rotateTimeline;
+					duration = Math.max(duration, rotateTimeline.frames[(rotateTimeline.frameCount - 1) * RotateTimeline.ENTRIES]);
+				} else if (timelineName == "translate" || timelineName == "scale" || timelineName == "shear") {
+					var translateTimeline:TranslateTimeline;
+					var timelineScale:Number = 1;
+					if (timelineName == "scale")
+						translateTimeline = new ScaleTimeline(values.length);
+					else if (timelineName == "shear")
+						translateTimeline = new ShearTimeline(values.length);
+					else {
+						translateTimeline = new TranslateTimeline(values.length);
+						timelineScale = scale;
+					}
+					translateTimeline.boneIndex = boneIndex;
+
+					frameIndex = 0;
+					for each (valueMap in values) {
+						var x:Number = Number(valueMap["x"] || 0) * timelineScale;
+						var y:Number = Number(valueMap["y"] || 0) * timelineScale;
+						translateTimeline.setFrame(frameIndex, valueMap["time"], x, y);
+						readCurve(valueMap, translateTimeline, frameIndex);
+						frameIndex++;
+					}
+					timelines[timelines.length] = translateTimeline;
+					duration = Math.max(duration, translateTimeline.frames[(translateTimeline.frameCount - 1) * TranslateTimeline.ENTRIES]);
+				} else
+					throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
+			}
+		}
+
+		var ikMap:Object = map["ik"];
+		for (var ikConstraintName:String in ikMap) {
+			var ikConstraint:IkConstraintData = skeletonData.findIkConstraint(ikConstraintName);
+			values = ikMap[ikConstraintName];
+			var ikTimeline:IkConstraintTimeline = new IkConstraintTimeline(values.length);
+			ikTimeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(ikConstraint);
+			frameIndex = 0;
+			for each (valueMap in values) {
+				var mix:Number = valueMap.hasOwnProperty("mix") ? valueMap["mix"] : 1;
+				var bendDirection:int = (!valueMap.hasOwnProperty("bendPositive") || valueMap["bendPositive"]) ? 1 : -1;
+				ikTimeline.setFrame(frameIndex, valueMap["time"], mix, bendDirection);
+				readCurve(valueMap, ikTimeline, frameIndex);
+				frameIndex++;
+			}
+			timelines[timelines.length] = ikTimeline;
+			duration = Math.max(duration, ikTimeline.frames[(ikTimeline.frameCount - 1) * IkConstraintTimeline.ENTRIES]);
+		}
+		
+		var transformMap:Object = map["transform"];
+		for (var transformName:String in transformMap) {
+			var transformConstraint:TransformConstraintData = skeletonData.findTransformConstraint(transformName);
+			values = transformMap[transformName];
+			var transformTimeline:TransformConstraintTimeline = new TransformConstraintTimeline(values.length);
+			transformTimeline.transformConstraintIndex = skeletonData.transformConstraints.indexOf(transformConstraint);
+			frameIndex = 0;
+			for each (valueMap in values) {
+				var rotateMix:Number = valueMap.hasOwnProperty("rotateMix") ? valueMap["rotateMix"] : 1;
+				var translateMix:Number = valueMap.hasOwnProperty("translateMix") ? valueMap["translateMix"] : 1;
+				var scaleMix:Number = valueMap.hasOwnProperty("scaleMix") ? valueMap["scaleMix"] : 1;
+				var shearMix:Number = valueMap.hasOwnProperty("shearMix") ? valueMap["shearMix"] : 1;
+				transformTimeline.setFrame(frameIndex, valueMap["time"], rotateMix, translateMix, scaleMix, shearMix);
+				readCurve(valueMap, transformTimeline, frameIndex);
+				frameIndex++;
+			}
+			timelines.push(transformTimeline);
+			duration = Math.max(duration, transformTimeline.frames[(transformTimeline.frameCount - 1) * TransformConstraintTimeline.ENTRIES]);
+		}
+				
+		// Path constraint timelines.
+		var paths:Object = map["paths"];
+		for (var pathName:String in paths) {
+			var index:int = skeletonData.findPathConstraintIndex(pathName);
+			if (index == -1) throw new Error("Path constraint not found: " + pathName);
+			var data:PathConstraintData = skeletonData.pathConstraints[index];
+			
+			var pathMap:Object = paths[pathName];
+			for (timelineName in pathMap) {
+				values = pathMap[timelineName];
+				
+				if (timelineName == "position" || timelineName == "spacing") {
+					var pathTimeline:PathConstraintPositionTimeline;
+					timelineScale = 1;
+					if (timelineName == "spacing") {
+						pathTimeline = new PathConstraintSpacingTimeline(values.length);
+						if (data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed) timelineScale = scale;
+					} else {
+						pathTimeline = new PathConstraintPositionTimeline(values.length);
+						if (data.positionMode == PositionMode.fixed) timelineScale = scale;
+					}
+					pathTimeline.pathConstraintIndex = index;
+					frameIndex = 0;
+					for each (valueMap in values) {
+						var value:Number = valueMap[timelineName] || 0;
+						pathTimeline.setFrame(frameIndex, valueMap["time"], value * timelineScale);
+						readCurve(valueMap, pathTimeline, frameIndex);
+						frameIndex++;
+					}
+					timelines.push(pathTimeline);
+					duration = Math.max(duration,
+						pathTimeline.frames[(pathTimeline.frameCount - 1) * PathConstraintPositionTimeline.ENTRIES]);
+				} else if (timelineName == "mix") {
+					var pathMixTimeline:PathConstraintMixTimeline = new PathConstraintMixTimeline(values.length);
+					pathMixTimeline.pathConstraintIndex = index;
+					frameIndex = 0;
+					for each (valueMap in values) {
+						rotateMix = valueMap.hasOwnProperty("rotateMix") ? valueMap["rotateMix"] : 1;
+						translateMix = valueMap.hasOwnProperty("translateMix") ? valueMap["translateMix"] : 1;
+						pathMixTimeline.setFrame(frameIndex, valueMap["time"], rotateMix, translateMix);
+						readCurve(valueMap, pathMixTimeline, frameIndex);
+						frameIndex++;
+					}
+					timelines.push(pathMixTimeline);
+					duration = Math.max(duration,
+						pathMixTimeline.frames[(pathMixTimeline.frameCount - 1) * PathConstraintMixTimeline.ENTRIES]);
+				}
+			}
+		}
+		
+		var deformMap:Object = map["deform"];
+		for (var skinName:String in deformMap) {
+			var skin:Skin = skeletonData.findSkin(skinName);
+			slotMap = deformMap[skinName];
+			for (slotName in slotMap) {
+				slotIndex = skeletonData.findSlotIndex(slotName);
+				var timelineMap:Object = slotMap[slotName];
+				for (timelineName in timelineMap) {
+					values = timelineMap[timelineName];
+
+					var attachment:VertexAttachment = skin.getAttachment(slotIndex, timelineName) as VertexAttachment;
+					if (attachment == null) throw new Error("Deform attachment not found: " + timelineName);
+					var weighted:Boolean = attachment.bones != null;
+					var vertices:Vector.<Number> = attachment.vertices;
+					var deformLength:int = weighted ? vertices.length / 3 * 2 : vertices.length;
+
+					var deformTimeline:DeformTimeline = new DeformTimeline(values.length);
+					deformTimeline.slotIndex = slotIndex;
+					deformTimeline.attachment = attachment;
+
+					frameIndex = 0;
+					for each (valueMap in values) {
+						var deform:Vector.<Number>;
+						var verticesValue:Object = valueMap["vertices"];
+						if (verticesValue == null)
+							deform = weighted ? new Vector.<Number>(deformLength, true) : vertices;
+						else {
+							deform = new Vector.<Number>(deformLength, true);
+							var start:int = Number(valueMap["offset"] || 0);
+							var temp:Vector.<Number> = getFloatArray(valueMap, "vertices", 1);
+							for (i = 0; i < temp.length; i++) {
+								deform[start + i] = temp[i];
+							}							
+							if (scale != 1) {
+								var n:int;
+								for (i = start, n = i + temp.length; i < n; i++)
+									deform[i] *= scale;
+							}
+							if (!weighted) {
+								for (i = 0; i < deformLength; i++)
+									deform[i] += vertices[i];
+							}
+						}
+
+						deformTimeline.setFrame(frameIndex, valueMap["time"], deform);
+						readCurve(valueMap, deformTimeline, frameIndex);
+						frameIndex++;
+					}
+					timelines[timelines.length] = deformTimeline;
+					duration = Math.max(duration, deformTimeline.frames[deformTimeline.frameCount - 1]);
+				}
+			}
+		}
+
+		var drawOrderValues:Array = map["drawOrder"];
+		if (!drawOrderValues) drawOrderValues = map["draworder"];
+		if (drawOrderValues) {
+			var drawOrderTimeline:DrawOrderTimeline = new DrawOrderTimeline(drawOrderValues.length);
+			var slotCount:int = skeletonData.slots.length;
+			frameIndex = 0;
+			for each (var drawOrderMap:Object in drawOrderValues) {
+				var drawOrder:Vector.<int> = null;
+				if (drawOrderMap["offsets"]) {
+					drawOrder = new Vector.<int>(slotCount);
+					for (i = slotCount - 1; i >= 0; i--)
+						drawOrder[i] = -1;
+					var offsets:Array = drawOrderMap["offsets"];
+					var unchanged:Vector.<int> = new Vector.<int>(slotCount - offsets.length);
+					var originalIndex:int = 0, unchangedIndex:int = 0;
+					for each (var offsetMap:Object in offsets) {
+						slotIndex = skeletonData.findSlotIndex(offsetMap["slot"]);
+						if (slotIndex == -1) throw new Error("Slot not found: " + offsetMap["slot"]);
+						// Collect unchanged items.
+						while (originalIndex != slotIndex)
+							unchanged[unchangedIndex++] = originalIndex++;
+						// Set changed items.
+						drawOrder[originalIndex + offsetMap["offset"]] = originalIndex++;
+					}
+					// Collect remaining unchanged items.
+					while (originalIndex < slotCount)
+						unchanged[unchangedIndex++] = originalIndex++;
+					// Fill in unchanged items.
+					for (i = slotCount - 1; i >= 0; i--)
+						if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex];
+				}
+				drawOrderTimeline.setFrame(frameIndex++, drawOrderMap["time"], drawOrder);
+			}
+			timelines[timelines.length] = drawOrderTimeline;
+			duration = Math.max(duration, drawOrderTimeline.frames[drawOrderTimeline.frameCount - 1]);
+		}
+
+		var eventsMap:Array = map["events"];
+		if (eventsMap) {
+			var eventTimeline:EventTimeline = new EventTimeline(eventsMap.length);
+			frameIndex = 0;
+			for each (var eventMap:Object in eventsMap) {
+				var eventData:EventData = skeletonData.findEvent(eventMap["name"]);
+				if (!eventData) throw new Error("Event not found: " + eventMap["name"]);
+				var event:Event = new Event(eventMap["time"], eventData);
+				event.intValue = eventMap.hasOwnProperty("int") ? eventMap["int"] : eventData.intValue;
+				event.floatValue = eventMap.hasOwnProperty("float") ? eventMap["float"] : eventData.floatValue;
+				event.stringValue = eventMap.hasOwnProperty("string") ? eventMap["string"] : eventData.stringValue;
+				eventTimeline.setFrame(frameIndex++, event);
+			}
+			timelines[timelines.length] = eventTimeline;
+			duration = Math.max(duration, eventTimeline.frames[eventTimeline.frameCount - 1]);
+		}
+
+		skeletonData.animations[skeletonData.animations.length] = new Animation(name, timelines, duration);
+	}
+
+	static private function readCurve (map:Object, timeline:CurveTimeline, frameIndex:int) : void {
+		var curve:Object = map["curve"];
+		if (!curve) return;
+		if (curve == "stepped")
+			timeline.setStepped(frameIndex);
+		else if (curve is Array)
+			timeline.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]);
+	}
+
+	static private function toColor (hexString:String, colorIndex:int) : Number {
+		if (hexString.length != 8) throw new ArgumentError("Color hexidecimal length must be 8, recieved: " + hexString);
+		return parseInt(hexString.substring(colorIndex * 2, colorIndex * 2 + 2), 16) / 255;
+	}
+
+	static private function getFloatArray (map:Object, name:String, scale:Number) : Vector.<Number> {
+		var list:Array = map[name];
+		var values:Vector.<Number> = new Vector.<Number>(list.length, true);
+		var i:int = 0, n:int = list.length;
+		if (scale == 1) {
+			for (; i < n; i++)
+				values[i] = list[i];
+		} else {
+			for (; i < n; i++)
+				values[i] = list[i] * scale;
+		}
+		return values;
+	}
+
+	static private function getIntArray (map:Object, name:String) : Vector.<int> {
+		var list:Array = map[name];
+		var values:Vector.<int> = new Vector.<int>(list.length, true);
+		for (var i:int = 0, n:int = list.length; i < n; i++)
+			values[i] = int(list[i]);
+		return values;
+	}
+
+	static private function getUintArray (map:Object, name:String) : Vector.<uint> {
+		var list:Array = map[name];
+		var values:Vector.<uint> = new Vector.<uint>(list.length, true);
+		for (var i:int = 0, n:int = list.length; i < n; i++)
+			values[i] = int(list[i]);
+		return values;
+	}
+}
+
+}
+
+import spine.attachments.MeshAttachment;
+
+internal class LinkedMesh {
+	internal var parent:String, skin:String;
+	internal var slotIndex:int;
+	internal var mesh:MeshAttachment;
+
+	public function LinkedMesh (mesh:MeshAttachment, skin:String, slotIndex:int, parent:String) {
+		this.mesh = mesh;
+		this.skin = skin;
+		this.slotIndex = slotIndex;
+		this.parent = parent;
+	}
 }

+ 90 - 91
spine-as3/spine-as3/src/spine/Skin.as

@@ -1,94 +1,93 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-import flash.utils.Dictionary;
-
-import spine.attachments.Attachment;
-
-/** Stores attachments by slot index and attachment name. */
-public class Skin {
-	internal var _name:String;
-	private var _attachments:Vector.<Dictionary> = new Vector.<Dictionary>();
-
-	public function Skin (name:String) {
-		if (name == null) throw new ArgumentError("name cannot be null.");
-		_name = name;
-	}
-
-	public function addAttachment (slotIndex:int, name:String, attachment:Attachment) : void {
-		if (attachment == null) throw new ArgumentError("attachment cannot be null.");
-		if (slotIndex >= attachments.length) attachments.length = slotIndex + 1;
-		if (!attachments[slotIndex]) attachments[slotIndex] = new Dictionary();
-		attachments[slotIndex][name] = attachment;
-	}
-
-	/** @return May be null. */
-	public function getAttachment (slotIndex:int, name:String) : Attachment {
-		if (slotIndex >= attachments.length) return null;
-		var dictionary:Dictionary = attachments[slotIndex];
-		return dictionary ? dictionary[name] : null;
-	}
-
-	public function get attachments () : Vector.<Dictionary> {
-		return _attachments;
-	}
-
-	public function get name () : String {
-		return _name;
-	}
-
-	public function toString () : String {
-		return _name;
-	}
-
-	/** Attach each attachment in this skin if the corresponding attachment in the old skin is currently attached. */
-	public function attachAll (skeleton:Skeleton, oldSkin:Skin) : void {
-		var slotIndex:int = 0;
-		for each (var slot:Slot in skeleton.slots) {
-			var slotAttachment:Attachment = slot.attachment;
-			if (slotAttachment && slotIndex < oldSkin.attachments.length) {
-				var dictionary:Dictionary = oldSkin.attachments[slotIndex];
-				for (var name:String in dictionary) {
-					var skinAttachment:Attachment = dictionary[name];
-					if (slotAttachment == skinAttachment) {
-						var attachment:Attachment = getAttachment(slotIndex, name);
-						if (attachment != null) slot.attachment = attachment;
-						break;
-					}
-				}
-			}
-			slotIndex++;
-		}
-	}
-}
-
+package spine {
+import flash.utils.Dictionary;
+
+import spine.attachments.Attachment;
+
+/** Stores attachments by slot index and attachment name. */
+public class Skin {
+	internal var _name:String;
+	private var _attachments:Vector.<Dictionary> = new Vector.<Dictionary>();
+
+	public function Skin (name:String) {
+		if (name == null) throw new ArgumentError("name cannot be null.");
+		_name = name;
+	}
+
+	public function addAttachment (slotIndex:int, name:String, attachment:Attachment) : void {
+		if (attachment == null) throw new ArgumentError("attachment cannot be null.");
+		if (slotIndex >= attachments.length) attachments.length = slotIndex + 1;
+		if (!attachments[slotIndex]) attachments[slotIndex] = new Dictionary();
+		attachments[slotIndex][name] = attachment;
+	}
+
+	/** @return May be null. */
+	public function getAttachment (slotIndex:int, name:String) : Attachment {
+		if (slotIndex >= attachments.length) return null;
+		var dictionary:Dictionary = attachments[slotIndex];
+		return dictionary ? dictionary[name] : null;
+	}
+
+	public function get attachments () : Vector.<Dictionary> {
+		return _attachments;
+	}
+
+	public function get name () : String {
+		return _name;
+	}
+
+	public function toString () : String {
+		return _name;
+	}
+
+	/** Attach each attachment in this skin if the corresponding attachment in the old skin is currently attached. */
+	public function attachAll (skeleton:Skeleton, oldSkin:Skin) : void {
+		var slotIndex:int = 0;
+		for each (var slot:Slot in skeleton.slots) {
+			var slotAttachment:Attachment = slot.attachment;
+			if (slotAttachment && slotIndex < oldSkin.attachments.length) {
+				var dictionary:Dictionary = oldSkin.attachments[slotIndex];
+				for (var name:String in dictionary) {
+					var skinAttachment:Attachment = dictionary[name];
+					if (slotAttachment == skinAttachment) {
+						var attachment:Attachment = getAttachment(slotIndex, name);
+						if (attachment != null) slot.attachment = attachment;
+						break;
+					}
+				}
+			}
+			slotIndex++;
+		}
+	}
+}
+
 }

+ 103 - 104
spine-as3/spine-as3/src/spine/Slot.as

@@ -1,107 +1,106 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-import spine.attachments.Attachment;
-
-public class Slot {
-	internal var _data:SlotData;
-	internal var _bone:Bone;
-	public var r:Number;
-	public var g:Number;
-	public var b:Number;
-	public var a:Number;
-	internal var _attachment:Attachment;
-	private var _attachmentTime:Number;
-	public var attachmentVertices:Vector.<Number> = new Vector.<Number>();
-
-	public function Slot (data:SlotData, bone:Bone) {
-		if (data == null) throw new ArgumentError("data cannot be null.");
-		if (bone == null) throw new ArgumentError("bone cannot be null.");
-		_data = data;
-		_bone = bone;
-		setToSetupPose();
-	}
-
-	public function get data () : SlotData {
-		return _data;
-	}
-	
-	public function get bone () : Bone {
-		return _bone;
-	}
-	
-	public function get skeleton () : Skeleton {
-		return _bone._skeleton;
-	}
-
-	/** @return May be null. */
-	public function get attachment () : Attachment {
-		return _attachment;
-	}
-
-	/** Sets the attachment and resets {@link #getAttachmentTime()}.
-	 * @param attachment May be null. */
-	public function set attachment (attachment:Attachment) : void {
-		if (_attachment == attachment) return;
-		_attachment = attachment;
-		_attachmentTime = _bone._skeleton.time;
-		attachmentVertices.length = 0;
-	}
-
-	public function set attachmentTime (time:Number) : void {
-		_attachmentTime = _bone._skeleton.time - time;
-	}
-
-	/** Returns the time since the attachment was set. */
-	public function get attachmentTime () : Number {
-		return _bone._skeleton.time - _attachmentTime;
-	}
-
-	public function setToSetupPose () : void {		
-		r = _data.r;
-		g = _data.g;
-		b = _data.b;
-		a = _data.a;
-		if (_data.attachmentName == null)
-			attachment = null;
-		else {
-			_attachment = null;
-			attachment = _bone._skeleton.getAttachmentForSlotIndex(data.index, data.attachmentName);
-		}
-	}
-
-	public function toString () : String {
-		return _data.name;
-	}
-}
-
+package spine {
+import spine.attachments.Attachment;
+
+public class Slot {
+	internal var _data:SlotData;
+	internal var _bone:Bone;
+	public var r:Number;
+	public var g:Number;
+	public var b:Number;
+	public var a:Number;
+	internal var _attachment:Attachment;
+	private var _attachmentTime:Number;
+	public var attachmentVertices:Vector.<Number> = new Vector.<Number>();
+
+	public function Slot (data:SlotData, bone:Bone) {
+		if (data == null) throw new ArgumentError("data cannot be null.");
+		if (bone == null) throw new ArgumentError("bone cannot be null.");
+		_data = data;
+		_bone = bone;
+		setToSetupPose();
+	}
+
+	public function get data () : SlotData {
+		return _data;
+	}
+	
+	public function get bone () : Bone {
+		return _bone;
+	}
+	
+	public function get skeleton () : Skeleton {
+		return _bone._skeleton;
+	}
+
+	/** @return May be null. */
+	public function get attachment () : Attachment {
+		return _attachment;
+	}
+
+	/** Sets the attachment and resets {@link #getAttachmentTime()}.
+	 * @param attachment May be null. */
+	public function set attachment (attachment:Attachment) : void {
+		if (_attachment == attachment) return;
+		_attachment = attachment;
+		_attachmentTime = _bone._skeleton.time;
+		attachmentVertices.length = 0;
+	}
+
+	public function set attachmentTime (time:Number) : void {
+		_attachmentTime = _bone._skeleton.time - time;
+	}
+
+	/** Returns the time since the attachment was set. */
+	public function get attachmentTime () : Number {
+		return _bone._skeleton.time - _attachmentTime;
+	}
+
+	public function setToSetupPose () : void {		
+		r = _data.r;
+		g = _data.g;
+		b = _data.b;
+		a = _data.a;
+		if (_data.attachmentName == null)
+			attachment = null;
+		else {
+			_attachment = null;
+			attachment = _bone._skeleton.getAttachmentForSlotIndex(data.index, data.attachmentName);
+		}
+	}
+
+	public function toString () : String {
+		return _data.name;
+	}
+}
+
 }

+ 67 - 68
spine-as3/spine-as3/src/spine/SlotData.as

@@ -1,71 +1,70 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public class SlotData {
-	internal var _index:int;
-	internal var _name:String;
-	internal var _boneData:BoneData;
-	public var r:Number = 1;
-	public var g:Number = 1;
-	public var b:Number = 1;
-	public var a:Number = 1;
-	public var attachmentName:String;
-	public var blendMode:BlendMode;
-
-	public function SlotData (index:int, name:String, boneData:BoneData) {
-		if (index < 0) throw new ArgumentError("index must be >= 0.");
-		if (name == null) throw new ArgumentError("name cannot be null.");
-		if (boneData == null) throw new ArgumentError("boneData cannot be null.");
-		_index = index;
-		_name = name;
-		_boneData = boneData;
-	}
-	
-	public function get index () : int {
-		return _index;
-	}
-
-	public function get name () : String {
-		return _name;
-	}
-
-	public function get boneData () : BoneData {
-		return _boneData;
-	}
-
-	public function toString () : String {
-		return _name;
-	}
-}
-
+package spine {
+
+public class SlotData {
+	internal var _index:int;
+	internal var _name:String;
+	internal var _boneData:BoneData;
+	public var r:Number = 1;
+	public var g:Number = 1;
+	public var b:Number = 1;
+	public var a:Number = 1;
+	public var attachmentName:String;
+	public var blendMode:BlendMode;
+
+	public function SlotData (index:int, name:String, boneData:BoneData) {
+		if (index < 0) throw new ArgumentError("index must be >= 0.");
+		if (name == null) throw new ArgumentError("name cannot be null.");
+		if (boneData == null) throw new ArgumentError("boneData cannot be null.");
+		_index = index;
+		_name = name;
+		_boneData = boneData;
+	}
+	
+	public function get index () : int {
+		return _index;
+	}
+
+	public function get name () : String {
+		return _name;
+	}
+
+	public function get boneData () : BoneData {
+		return _boneData;
+	}
+
+	public function toString () : String {
+		return _name;
+	}
+}
+
 }

+ 36 - 37
spine-as3/spine-as3/src/spine/SpacingMode.as

@@ -1,40 +1,39 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public class SpacingMode {
-	public static const length:SpacingMode = new SpacingMode();
-	public static const fixed:SpacingMode = new SpacingMode();
-	public static const percent:SpacingMode = new SpacingMode();
+package spine {
+
+public class SpacingMode {
+	public static const length:SpacingMode = new SpacingMode();
+	public static const fixed:SpacingMode = new SpacingMode();
+	public static const percent:SpacingMode = new SpacingMode();
+}
+
 }
-
-}

+ 129 - 130
spine-as3/spine-as3/src/spine/TransformConstraint.as

@@ -1,133 +1,132 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public class TransformConstraint implements Updatable {
-	internal var _data:TransformConstraintData;
-	internal var _bones:Vector.<Bone>;
-	public var target:Bone;
-	public var rotateMix:Number;	
-	public var translateMix:Number;
-	public var scaleMix:Number;
-	public var shearMix:Number;
-	internal var _temp:Vector.<Number> = new Vector.<Number>(2);
-
-	public function TransformConstraint (data:TransformConstraintData, skeleton:Skeleton) {
-		if (data == null) throw new ArgumentError("data cannot be null.");
-		if (skeleton == null) throw new ArgumentError("skeleton cannot be null.");
-		_data = data;
-		rotateMix = data.rotateMix;
-		translateMix = data.translateMix;
-		scaleMix = data.scaleMix;
-		shearMix = data.shearMix;
-		_bones = new Vector.<Bone>();		
-		for each (var boneData:BoneData in data.bones)
-			_bones.push(skeleton.findBone(boneData.name));		
-		target = skeleton.findBone(data.target._name);
-	}		
-
-	public function apply () : void {
-		update();
-	}
-
-	public function update () : void {
-		var rotateMix:Number = this.rotateMix, translateMix:Number = this.translateMix, scaleMix:Number = this.scaleMix, shearMix:Number = this.shearMix;
-		var target:Bone = this.target;
-		var ta:Number = target.a, tb:Number = target.b, tc:Number = target.c, td:Number = target.d;
-		var bones:Vector.<Bone> = this._bones;
-		for (var i:int = 0, n:int = bones.length; i < n; i++) {
-			var bone:Bone = bones[i];
-
-			if (rotateMix > 0) {
-				var a:Number = bone.a, b:Number = bone.b, c:Number = bone.c, d:Number = bone.d;
-				var r:Number = Math.atan2(tc, ta) - Math.atan2(c, a) + data.offsetRotation * MathUtils.degRad;
-				if (r > Math.PI)
-					r -= Math.PI * 2;
-				else if (r < -Math.PI) r += Math.PI * 2;
-				r *= rotateMix;
-				var cos:Number = Math.cos(r), sin:Number = Math.sin(r);
-				bone._a = cos * a - sin * c;
-				bone._b = cos * b - sin * d;
-				bone._c = sin * a + cos * c;
-				bone._d = sin * b + cos * d;
-			}
-
-			if (translateMix > 0) {
-				_temp[0] = data.offsetX;
-				_temp[1] = data.offsetY;
-				target.localToWorld(_temp);
-				bone._worldX += (_temp[0] - bone.worldX) * translateMix;
-				bone._worldY += (_temp[1] - bone.worldY) * translateMix;
-			}
-
-			if (scaleMix > 0) {
-				var bs:Number = Math.sqrt(bone.a * bone.a + bone.c * bone.c);
-				var ts:Number = Math.sqrt(ta * ta + tc * tc);
-				var s:Number = bs > 0.00001 ? (bs + (ts - bs + data.offsetScaleX) * scaleMix) / bs : 0;
-				bone._a *= s;
-				bone._c *= s;
-				bs = Math.sqrt(bone.b * bone.b + bone.d * bone.d);
-				ts = Math.sqrt(tb * tb + td * td);
-				s = bs > 0.00001 ? (bs + (ts - bs + data.offsetScaleY) * scaleMix) / bs : 0;
-				bone._b *= s;
-				bone._d *= s;
-			}
-
-			if (shearMix > 0) {
-				b = bone.b, d = bone.d;
-				var by:Number = Math.atan2(d, b);
-				r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(bone.c, bone.a));
-				if (r > Math.PI)
-					r -= Math.PI * 2;
-				else if (r < -Math.PI) r += Math.PI * 2;
-				r = by + (r + data.offsetShearY * MathUtils.degRad) * shearMix;
-				s = Math.sqrt(b * b + d * d);
-				bone._b = Math.cos(r) * s;
-				bone._d = Math.sin(r) * s;
-			}
-		}
-	}
-
-	public function get data () : TransformConstraintData {
-		return _data;
-	}
-	
-	public function get bones () : Vector.<Bone> {
-		return _bones;
-	}
-
-	public function toString () : String {
-		return _data._name;
-	}
-}
-
+package spine {
+
+public class TransformConstraint implements Updatable {
+	internal var _data:TransformConstraintData;
+	internal var _bones:Vector.<Bone>;
+	public var target:Bone;
+	public var rotateMix:Number;	
+	public var translateMix:Number;
+	public var scaleMix:Number;
+	public var shearMix:Number;
+	internal var _temp:Vector.<Number> = new Vector.<Number>(2);
+
+	public function TransformConstraint (data:TransformConstraintData, skeleton:Skeleton) {
+		if (data == null) throw new ArgumentError("data cannot be null.");
+		if (skeleton == null) throw new ArgumentError("skeleton cannot be null.");
+		_data = data;
+		rotateMix = data.rotateMix;
+		translateMix = data.translateMix;
+		scaleMix = data.scaleMix;
+		shearMix = data.shearMix;
+		_bones = new Vector.<Bone>();		
+		for each (var boneData:BoneData in data.bones)
+			_bones.push(skeleton.findBone(boneData.name));		
+		target = skeleton.findBone(data.target._name);
+	}		
+
+	public function apply () : void {
+		update();
+	}
+
+	public function update () : void {
+		var rotateMix:Number = this.rotateMix, translateMix:Number = this.translateMix, scaleMix:Number = this.scaleMix, shearMix:Number = this.shearMix;
+		var target:Bone = this.target;
+		var ta:Number = target.a, tb:Number = target.b, tc:Number = target.c, td:Number = target.d;
+		var bones:Vector.<Bone> = this._bones;
+		for (var i:int = 0, n:int = bones.length; i < n; i++) {
+			var bone:Bone = bones[i];
+
+			if (rotateMix > 0) {
+				var a:Number = bone.a, b:Number = bone.b, c:Number = bone.c, d:Number = bone.d;
+				var r:Number = Math.atan2(tc, ta) - Math.atan2(c, a) + data.offsetRotation * MathUtils.degRad;
+				if (r > Math.PI)
+					r -= Math.PI * 2;
+				else if (r < -Math.PI) r += Math.PI * 2;
+				r *= rotateMix;
+				var cos:Number = Math.cos(r), sin:Number = Math.sin(r);
+				bone._a = cos * a - sin * c;
+				bone._b = cos * b - sin * d;
+				bone._c = sin * a + cos * c;
+				bone._d = sin * b + cos * d;
+			}
+
+			if (translateMix > 0) {
+				_temp[0] = data.offsetX;
+				_temp[1] = data.offsetY;
+				target.localToWorld(_temp);
+				bone._worldX += (_temp[0] - bone.worldX) * translateMix;
+				bone._worldY += (_temp[1] - bone.worldY) * translateMix;
+			}
+
+			if (scaleMix > 0) {
+				var bs:Number = Math.sqrt(bone.a * bone.a + bone.c * bone.c);
+				var ts:Number = Math.sqrt(ta * ta + tc * tc);
+				var s:Number = bs > 0.00001 ? (bs + (ts - bs + data.offsetScaleX) * scaleMix) / bs : 0;
+				bone._a *= s;
+				bone._c *= s;
+				bs = Math.sqrt(bone.b * bone.b + bone.d * bone.d);
+				ts = Math.sqrt(tb * tb + td * td);
+				s = bs > 0.00001 ? (bs + (ts - bs + data.offsetScaleY) * scaleMix) / bs : 0;
+				bone._b *= s;
+				bone._d *= s;
+			}
+
+			if (shearMix > 0) {
+				b = bone.b, d = bone.d;
+				var by:Number = Math.atan2(d, b);
+				r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(bone.c, bone.a));
+				if (r > Math.PI)
+					r -= Math.PI * 2;
+				else if (r < -Math.PI) r += Math.PI * 2;
+				r = by + (r + data.offsetShearY * MathUtils.degRad) * shearMix;
+				s = Math.sqrt(b * b + d * d);
+				bone._b = Math.cos(r) * s;
+				bone._d = Math.sin(r) * s;
+			}
+		}
+	}
+
+	public function get data () : TransformConstraintData {
+		return _data;
+	}
+	
+	public function get bones () : Vector.<Bone> {
+		return _bones;
+	}
+
+	public function toString () : String {
+		return _data._name;
+	}
+}
+
 }

+ 63 - 64
spine-as3/spine-as3/src/spine/TransformConstraintData.as

@@ -1,67 +1,66 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public class TransformConstraintData {
-	internal var _name:String;
-	internal var _bones:Vector.<BoneData> = new Vector.<BoneData>();
-	public var target:BoneData;
-	public var rotateMix:Number;
-	public var translateMix:Number;
-	public var scaleMix:Number;
-	public var shearMix:Number;
-	public var offsetRotation:Number;
-	public var offsetX:Number;
-	public var offsetY:Number;
-	public var offsetScaleX:Number;
-	public var offsetScaleY:Number;
-	public var offsetShearY:Number;
-
-	public function TransformConstraintData (name:String) {
-		if (name == null) throw new ArgumentError("name cannot be null.");
-		_name = name;
-	}
-	
-	public function get bones () : Vector.<BoneData> {;
-		return _bones;
-	}
-
-	public function get name () : String {
-		return _name;
-	}
-
-	public function toString () : String {
-		return _name;
-	}
-}
-
+package spine {
+
+public class TransformConstraintData {
+	internal var _name:String;
+	internal var _bones:Vector.<BoneData> = new Vector.<BoneData>();
+	public var target:BoneData;
+	public var rotateMix:Number;
+	public var translateMix:Number;
+	public var scaleMix:Number;
+	public var shearMix:Number;
+	public var offsetRotation:Number;
+	public var offsetX:Number;
+	public var offsetY:Number;
+	public var offsetScaleX:Number;
+	public var offsetScaleY:Number;
+	public var offsetShearY:Number;
+
+	public function TransformConstraintData (name:String) {
+		if (name == null) throw new ArgumentError("name cannot be null.");
+		_name = name;
+	}
+	
+	public function get bones () : Vector.<BoneData> {;
+		return _bones;
+	}
+
+	public function get name () : String {
+		return _name;
+	}
+
+	public function toString () : String {
+		return _name;
+	}
+}
+
 }

+ 34 - 35
spine-as3/spine-as3/src/spine/Updatable.as

@@ -1,38 +1,37 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine {
-
-public interface Updatable {
-	function update () : void;
-}
-
+package spine {
+
+public interface Updatable {
+	function update () : void;
+}
+
 }

+ 130 - 131
spine-as3/spine-as3/src/spine/animation/Animation.as

@@ -1,134 +1,133 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.Event;
-import spine.Skeleton;
-
-public class Animation {
-	internal var _name:String;
-	private var _timelines:Vector.<Timeline>;
-	public var duration:Number;
-
-	public function Animation (name:String, timelines:Vector.<Timeline>, duration:Number) {
-		if (name == null) throw new ArgumentError("name cannot be null.");
-		if (timelines == null) throw new ArgumentError("timelines cannot be null.");
-		_name = name;
-		_timelines = timelines;
-		this.duration = duration;
-	}
-
-	public function get timelines () : Vector.<Timeline> {
-		return _timelines;
-	}
-
-	/** Poses the skeleton at the specified time for this animation. */
-	public function apply (skeleton:Skeleton, lastTime:Number, time:Number, loop:Boolean, events:Vector.<Event>) : void {
-		if (skeleton == null) throw new ArgumentError("skeleton cannot be null.");
-
-		if (loop && duration != 0) {
-			time %= duration;
-			if (lastTime > 0) lastTime %= duration;
-		}
-
-		for (var i:int = 0, n:int = timelines.length; i < n; i++)
-			timelines[i].apply(skeleton, lastTime, time, events, 1);
-	}
-
-	/** Poses the skeleton at the specified time for this animation mixed with the current pose.
-	 * @param alpha The amount of this animation that affects the current pose. */
-	public function mix (skeleton:Skeleton, lastTime:Number, time:Number, loop:Boolean, events:Vector.<Event>, alpha:Number) : void {
-		if (skeleton == null) throw new ArgumentError("skeleton cannot be null.");
-
-		if (loop && duration != 0) {
-			time %= duration;
-			if (lastTime > 0) lastTime %= duration;
-		}
-
-		for (var i:int = 0, n:int = timelines.length; i < n; i++)
-			timelines[i].apply(skeleton, lastTime, time, events, alpha);
-	}
-
-	public function get name () : String {
-		return _name;
-	}
-
-	public function toString () : String {
-		return _name;
-	}
-
-	/** @param target After the first and before the last entry. */
-	static public function binarySearch (values:Vector.<Number>, target:Number, step:int) : int {
-		var low:int = 0;
-		var high:int = values.length / step - 2;
-		if (high == 0)
-			return step;
-		var current:int = high >>> 1;
-		while (true) {
-			if (values[int((current + 1) * step)] <= target)
-				low = current + 1;
-			else
-				high = current;
-			if (low == high)
-				return (low + 1) * step;
-			current = (low + high) >>> 1;
-		}
-		return 0; // Can't happen.
-	}
-
-	/** @param target After the first and before the last entry. */
-	static public function binarySearch1 (values:Vector.<Number>, target:Number) : int {
-		var low:int = 0;
-		var high:int = values.length - 2;
-		if (high == 0)
-			return 1;
-		var current:int = high >>> 1;
-		while (true) {
-			if (values[int(current + 1)] <= target)
-				low = current + 1;
-			else
-				high = current;
-			if (low == high)
-				return low + 1;
-			current = (low + high) >>> 1;
-		}
-		return 0; // Can't happen.
-	}
-	
-	static public function linearSearch (values:Vector.<Number>, target:Number, step:int) : int {
-		for (var i:int = 0, last:int = values.length - step; i <= last; i += step)
-			if (values[i] > target)
-				return i;
-		return -1;
-	}
-}
-
+package spine.animation {
+import spine.Event;
+import spine.Skeleton;
+
+public class Animation {
+	internal var _name:String;
+	private var _timelines:Vector.<Timeline>;
+	public var duration:Number;
+
+	public function Animation (name:String, timelines:Vector.<Timeline>, duration:Number) {
+		if (name == null) throw new ArgumentError("name cannot be null.");
+		if (timelines == null) throw new ArgumentError("timelines cannot be null.");
+		_name = name;
+		_timelines = timelines;
+		this.duration = duration;
+	}
+
+	public function get timelines () : Vector.<Timeline> {
+		return _timelines;
+	}
+
+	/** Poses the skeleton at the specified time for this animation. */
+	public function apply (skeleton:Skeleton, lastTime:Number, time:Number, loop:Boolean, events:Vector.<Event>) : void {
+		if (skeleton == null) throw new ArgumentError("skeleton cannot be null.");
+
+		if (loop && duration != 0) {
+			time %= duration;
+			if (lastTime > 0) lastTime %= duration;
+		}
+
+		for (var i:int = 0, n:int = timelines.length; i < n; i++)
+			timelines[i].apply(skeleton, lastTime, time, events, 1);
+	}
+
+	/** Poses the skeleton at the specified time for this animation mixed with the current pose.
+	 * @param alpha The amount of this animation that affects the current pose. */
+	public function mix (skeleton:Skeleton, lastTime:Number, time:Number, loop:Boolean, events:Vector.<Event>, alpha:Number) : void {
+		if (skeleton == null) throw new ArgumentError("skeleton cannot be null.");
+
+		if (loop && duration != 0) {
+			time %= duration;
+			if (lastTime > 0) lastTime %= duration;
+		}
+
+		for (var i:int = 0, n:int = timelines.length; i < n; i++)
+			timelines[i].apply(skeleton, lastTime, time, events, alpha);
+	}
+
+	public function get name () : String {
+		return _name;
+	}
+
+	public function toString () : String {
+		return _name;
+	}
+
+	/** @param target After the first and before the last entry. */
+	static public function binarySearch (values:Vector.<Number>, target:Number, step:int) : int {
+		var low:int = 0;
+		var high:int = values.length / step - 2;
+		if (high == 0)
+			return step;
+		var current:int = high >>> 1;
+		while (true) {
+			if (values[int((current + 1) * step)] <= target)
+				low = current + 1;
+			else
+				high = current;
+			if (low == high)
+				return (low + 1) * step;
+			current = (low + high) >>> 1;
+		}
+		return 0; // Can't happen.
+	}
+
+	/** @param target After the first and before the last entry. */
+	static public function binarySearch1 (values:Vector.<Number>, target:Number) : int {
+		var low:int = 0;
+		var high:int = values.length - 2;
+		if (high == 0)
+			return 1;
+		var current:int = high >>> 1;
+		while (true) {
+			if (values[int(current + 1)] <= target)
+				low = current + 1;
+			else
+				high = current;
+			if (low == high)
+				return low + 1;
+			current = (low + high) >>> 1;
+		}
+		return 0; // Can't happen.
+	}
+	
+	static public function linearSearch (values:Vector.<Number>, target:Number, step:int) : int {
+		for (var i:int = 0, last:int = values.length - step; i <= last; i += step)
+			if (values[i] > target)
+				return i;
+		return -1;
+	}
+}
+
 }

+ 238 - 239
spine-as3/spine-as3/src/spine/animation/AnimationState.as

@@ -1,242 +1,241 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-
-import spine.Event;
-import spine.Skeleton;
-
-public class AnimationState {
-	private var _data:AnimationStateData;
-	private var _tracks:Vector.<TrackEntry> = new Vector.<TrackEntry>();
-	private var _events:Vector.<Event> = new Vector.<Event>();
-	public var onStart:Listeners = new Listeners();
-	public var onEnd:Listeners = new Listeners();
-	public var onComplete:Listeners = new Listeners();
-	public var onEvent:Listeners = new Listeners();
-	public var timeScale:Number = 1;
-
-	public function AnimationState (data:AnimationStateData) {
-		if (!data) throw new ArgumentError("data cannot be null.");
-		_data = data;
-	}
-
-	public function update (delta:Number) : void {
-		delta *= timeScale;
-		for (var i:int = 0; i < _tracks.length; i++) {
-			var current:TrackEntry = _tracks[i];
-			if (!current) continue;
-			
-			current.time += delta * current.timeScale;
-			if (current.previous) {
-				var previousDelta:Number = delta * current.previous.timeScale;
-				current.previous.time += previousDelta;
-				current.mixTime += previousDelta;
-			}
-
-			var next:TrackEntry = current.next;
-			if (next) {
-				next.time = current.lastTime - next.delay;
-				if (next.time >= 0) setCurrent(i, next);
-			} else {
-				// End non-looping animation when it reaches its end time and there is no next entry.
-				if (!current.loop && current.lastTime >= current.endTime) clearTrack(i);
-			}
-		}
-	}
-
-	public function apply (skeleton:Skeleton) : void {
-		for (var i:int = 0; i < _tracks.length; i++) {
-			var current:TrackEntry = _tracks[i];
-			if (!current) continue;
-			
-			_events.length = 0;
-			
-			var time:Number = current.time;
-			var lastTime:Number = current.lastTime;
-			var endTime:Number = current.endTime;
-			var loop:Boolean = current.loop;
-			if (!loop && time > endTime) time = endTime;
-			
-			var previous:TrackEntry = current.previous;
-			if (!previous) {
-				if (current.mix == 1)
-					current.animation.apply(skeleton, current.lastTime, time, loop, _events);
-				else
-					current.animation.mix(skeleton, current.lastTime, time, loop, _events, current.mix);
-			} else {
-				var previousTime:Number = previous.time;
-				if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime;
-				previous.animation.apply(skeleton, previousTime, previousTime, previous.loop, null);
-				
-				var alpha:Number = current.mixTime / current.mixDuration * current.mix;
-				if (alpha >= 1) {
-					alpha = 1;
-					current.previous = null;
-				}
-				current.animation.mix(skeleton, current.lastTime, time, loop, _events, alpha);
-			}
-			
-			for each (var event:Event in _events) {
-				if (current.onEvent != null) current.onEvent(i, event);
-				onEvent.invoke(i, event);
-			}
-
-			// Check if completed the animation or a loop iteration.
-			if (loop ? (lastTime % endTime > time % endTime) : (lastTime < endTime && time >= endTime)) {
-				var count:int = (int)(time / endTime);
-				if (current.onComplete != null) current.onComplete(i, count);
-				onComplete.invoke(i, count);
-			}
-
-			current.lastTime = current.time;
-		}
-	}
-
-	public function clearTracks () : void {
-		for (var i:int = 0, n:int = _tracks.length; i < n; i++)
-			clearTrack(i);
-		_tracks.length = 0; 
-	}
-	
-	public function clearTrack (trackIndex:int) : void {
-		if (trackIndex >= _tracks.length) return;
-		var current:TrackEntry = _tracks[trackIndex];
-		if (!current) return;
-
-		if (current.onEnd != null) current.onEnd(trackIndex);
-		onEnd.invoke(trackIndex);
-
-		_tracks[trackIndex] = null;
-	}
-	
-	private function expandToIndex (index:int) : TrackEntry {
-		if (index < _tracks.length) return _tracks[index];
-		while (index >= _tracks.length)
-			_tracks[_tracks.length] = null;
-		return null;
-	}
-	
-	private function setCurrent (index:int, entry:TrackEntry) : void {
-		var current:TrackEntry = expandToIndex(index);
-		if (current) {
-			var previous:TrackEntry = current.previous;
-			current.previous = null;
-
-			if (current.onEnd != null) current.onEnd(index);
-			onEnd.invoke(index);
-
-			entry.mixDuration = _data.getMix(current.animation, entry.animation);
-			if (entry.mixDuration > 0) {
-				entry.mixTime = 0;
-				// If a mix is in progress, mix from the closest animation.
-				if (previous != null && current.mixTime / current.mixDuration < 0.5) {
-					entry.previous = previous;
-					previous = current;
-				} else
-					entry.previous = current;
-			}
-		}
-		
-		_tracks[index] = entry;
-
-		if (entry.onStart != null) entry.onStart(index);
-		onStart.invoke(index);
-	}
-	
-	public function setAnimationByName (trackIndex:int, animationName:String, loop:Boolean) : TrackEntry {
-		var animation:Animation = _data._skeletonData.findAnimation(animationName);
-		if (!animation) throw new ArgumentError("Animation not found: " + animationName);
-		return setAnimation(trackIndex, animation, loop);
-	}
-	
-	/** Set the current animation. Any queued animations are cleared. */
-	public function setAnimation (trackIndex:int, animation:Animation, loop:Boolean) : TrackEntry {
-		var entry:TrackEntry = new TrackEntry();
-		entry.animation = animation;
-		entry.loop = loop;
-		entry.endTime = animation.duration;
-		setCurrent(trackIndex, entry);
-		return entry;
-	}
-	
-	public function addAnimationByName (trackIndex:int, animationName:String, loop:Boolean, delay:Number) : TrackEntry {
-		var animation:Animation = _data._skeletonData.findAnimation(animationName);
-		if (!animation) throw new ArgumentError("Animation not found: " + animationName);
-		return addAnimation(trackIndex, animation, loop, delay);
-	}
-	
-	/** Adds an animation to be played delay seconds after the current or last queued animation.
-	 * @param delay May be <= 0 to use duration of previous animation minus any mix duration plus the negative delay. */
-	public function addAnimation (trackIndex:int, animation:Animation, loop:Boolean, delay:Number) : TrackEntry {
-		var entry:TrackEntry = new TrackEntry();
-		entry.animation = animation;
-		entry.loop = loop;
-		entry.endTime = animation.duration;
-		
-		var last:TrackEntry = expandToIndex(trackIndex);
-		if (last) {
-			while (last.next)
-				last = last.next;
-			last.next = entry;
-		} else
-			_tracks[trackIndex] = entry;
-		
-		if (delay <= 0) {
-			if (last)
-				delay += last.endTime - _data.getMix(last.animation, animation);
-			else
-				delay = 0;
-		}
-		entry.delay = delay;
-		
-		return entry;
-	}
-	
-	/** May be null. */
-	public function getCurrent (trackIndex:int) : TrackEntry {
-		if (trackIndex >= _tracks.length) return null;
-		return _tracks[trackIndex];
-	}
-
-	public function toString () : String {
-		var buffer:String = "";
-		for each (var entry:TrackEntry in _tracks) {
-			if (!entry) continue;
-			if (buffer.length > 0) buffer += ", ";
-			buffer += entry.toString();
-		}
-		if (buffer.length == 0) return "<none>";
-		return buffer;
-	}
-}
-
+package spine.animation {
+
+import spine.Event;
+import spine.Skeleton;
+
+public class AnimationState {
+	private var _data:AnimationStateData;
+	private var _tracks:Vector.<TrackEntry> = new Vector.<TrackEntry>();
+	private var _events:Vector.<Event> = new Vector.<Event>();
+	public var onStart:Listeners = new Listeners();
+	public var onEnd:Listeners = new Listeners();
+	public var onComplete:Listeners = new Listeners();
+	public var onEvent:Listeners = new Listeners();
+	public var timeScale:Number = 1;
+
+	public function AnimationState (data:AnimationStateData) {
+		if (!data) throw new ArgumentError("data cannot be null.");
+		_data = data;
+	}
+
+	public function update (delta:Number) : void {
+		delta *= timeScale;
+		for (var i:int = 0; i < _tracks.length; i++) {
+			var current:TrackEntry = _tracks[i];
+			if (!current) continue;
+			
+			current.time += delta * current.timeScale;
+			if (current.previous) {
+				var previousDelta:Number = delta * current.previous.timeScale;
+				current.previous.time += previousDelta;
+				current.mixTime += previousDelta;
+			}
+
+			var next:TrackEntry = current.next;
+			if (next) {
+				next.time = current.lastTime - next.delay;
+				if (next.time >= 0) setCurrent(i, next);
+			} else {
+				// End non-looping animation when it reaches its end time and there is no next entry.
+				if (!current.loop && current.lastTime >= current.endTime) clearTrack(i);
+			}
+		}
+	}
+
+	public function apply (skeleton:Skeleton) : void {
+		for (var i:int = 0; i < _tracks.length; i++) {
+			var current:TrackEntry = _tracks[i];
+			if (!current) continue;
+			
+			_events.length = 0;
+			
+			var time:Number = current.time;
+			var lastTime:Number = current.lastTime;
+			var endTime:Number = current.endTime;
+			var loop:Boolean = current.loop;
+			if (!loop && time > endTime) time = endTime;
+			
+			var previous:TrackEntry = current.previous;
+			if (!previous) {
+				if (current.mix == 1)
+					current.animation.apply(skeleton, current.lastTime, time, loop, _events);
+				else
+					current.animation.mix(skeleton, current.lastTime, time, loop, _events, current.mix);
+			} else {
+				var previousTime:Number = previous.time;
+				if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime;
+				previous.animation.apply(skeleton, previousTime, previousTime, previous.loop, null);
+				
+				var alpha:Number = current.mixTime / current.mixDuration * current.mix;
+				if (alpha >= 1) {
+					alpha = 1;
+					current.previous = null;
+				}
+				current.animation.mix(skeleton, current.lastTime, time, loop, _events, alpha);
+			}
+			
+			for each (var event:Event in _events) {
+				if (current.onEvent != null) current.onEvent(i, event);
+				onEvent.invoke(i, event);
+			}
+
+			// Check if completed the animation or a loop iteration.
+			if (loop ? (lastTime % endTime > time % endTime) : (lastTime < endTime && time >= endTime)) {
+				var count:int = (int)(time / endTime);
+				if (current.onComplete != null) current.onComplete(i, count);
+				onComplete.invoke(i, count);
+			}
+
+			current.lastTime = current.time;
+		}
+	}
+
+	public function clearTracks () : void {
+		for (var i:int = 0, n:int = _tracks.length; i < n; i++)
+			clearTrack(i);
+		_tracks.length = 0; 
+	}
+	
+	public function clearTrack (trackIndex:int) : void {
+		if (trackIndex >= _tracks.length) return;
+		var current:TrackEntry = _tracks[trackIndex];
+		if (!current) return;
+
+		if (current.onEnd != null) current.onEnd(trackIndex);
+		onEnd.invoke(trackIndex);
+
+		_tracks[trackIndex] = null;
+	}
+	
+	private function expandToIndex (index:int) : TrackEntry {
+		if (index < _tracks.length) return _tracks[index];
+		while (index >= _tracks.length)
+			_tracks[_tracks.length] = null;
+		return null;
+	}
+	
+	private function setCurrent (index:int, entry:TrackEntry) : void {
+		var current:TrackEntry = expandToIndex(index);
+		if (current) {
+			var previous:TrackEntry = current.previous;
+			current.previous = null;
+
+			if (current.onEnd != null) current.onEnd(index);
+			onEnd.invoke(index);
+
+			entry.mixDuration = _data.getMix(current.animation, entry.animation);
+			if (entry.mixDuration > 0) {
+				entry.mixTime = 0;
+				// If a mix is in progress, mix from the closest animation.
+				if (previous != null && current.mixTime / current.mixDuration < 0.5) {
+					entry.previous = previous;
+					previous = current;
+				} else
+					entry.previous = current;
+			}
+		}
+		
+		_tracks[index] = entry;
+
+		if (entry.onStart != null) entry.onStart(index);
+		onStart.invoke(index);
+	}
+	
+	public function setAnimationByName (trackIndex:int, animationName:String, loop:Boolean) : TrackEntry {
+		var animation:Animation = _data._skeletonData.findAnimation(animationName);
+		if (!animation) throw new ArgumentError("Animation not found: " + animationName);
+		return setAnimation(trackIndex, animation, loop);
+	}
+	
+	/** Set the current animation. Any queued animations are cleared. */
+	public function setAnimation (trackIndex:int, animation:Animation, loop:Boolean) : TrackEntry {
+		var entry:TrackEntry = new TrackEntry();
+		entry.animation = animation;
+		entry.loop = loop;
+		entry.endTime = animation.duration;
+		setCurrent(trackIndex, entry);
+		return entry;
+	}
+	
+	public function addAnimationByName (trackIndex:int, animationName:String, loop:Boolean, delay:Number) : TrackEntry {
+		var animation:Animation = _data._skeletonData.findAnimation(animationName);
+		if (!animation) throw new ArgumentError("Animation not found: " + animationName);
+		return addAnimation(trackIndex, animation, loop, delay);
+	}
+	
+	/** Adds an animation to be played delay seconds after the current or last queued animation.
+	 * @param delay May be <= 0 to use duration of previous animation minus any mix duration plus the negative delay. */
+	public function addAnimation (trackIndex:int, animation:Animation, loop:Boolean, delay:Number) : TrackEntry {
+		var entry:TrackEntry = new TrackEntry();
+		entry.animation = animation;
+		entry.loop = loop;
+		entry.endTime = animation.duration;
+		
+		var last:TrackEntry = expandToIndex(trackIndex);
+		if (last) {
+			while (last.next)
+				last = last.next;
+			last.next = entry;
+		} else
+			_tracks[trackIndex] = entry;
+		
+		if (delay <= 0) {
+			if (last)
+				delay += last.endTime - _data.getMix(last.animation, animation);
+			else
+				delay = 0;
+		}
+		entry.delay = delay;
+		
+		return entry;
+	}
+	
+	/** May be null. */
+	public function getCurrent (trackIndex:int) : TrackEntry {
+		if (trackIndex >= _tracks.length) return null;
+		return _tracks[trackIndex];
+	}
+
+	public function toString () : String {
+		var buffer:String = "";
+		for each (var entry:TrackEntry in _tracks) {
+			if (!entry) continue;
+			if (buffer.length > 0) buffer += ", ";
+			buffer += entry.toString();
+		}
+		if (buffer.length == 0) return "<none>";
+		return buffer;
+	}
+}
+
 }

+ 65 - 66
spine-as3/spine-as3/src/spine/animation/AnimationStateData.as

@@ -1,69 +1,68 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.SkeletonData;
-
-public class AnimationStateData {
-	internal var _skeletonData:SkeletonData;
-	private var animationToMixTime:Object = new Object();
-	public var defaultMix:Number = 0;
-
-	public function AnimationStateData (skeletonData:SkeletonData) {
-		_skeletonData = skeletonData;
-	}
-
-	public function get skeletonData () : SkeletonData {
-		return _skeletonData;
-	}
-
-	public function setMixByName (fromName:String, toName:String, duration:Number) : void {
-		var from:Animation = _skeletonData.findAnimation(fromName);
-		if (from == null) throw new ArgumentError("Animation not found: " + fromName);
-		var to:Animation = _skeletonData.findAnimation(toName);
-		if (to == null) throw new ArgumentError("Animation not found: " + toName);
-		setMix(from, to, duration);
-	}
-
-	public function setMix (from:Animation, to:Animation, duration:Number) : void {
-		if (from == null) throw new ArgumentError("from cannot be null.");
-		if (to == null) throw new ArgumentError("to cannot be null.");
-		animationToMixTime[from.name + ":" + to.name] = duration;
-	}
-
-	public function getMix (from:Animation, to:Animation) : Number {
-		var time:Object = animationToMixTime[from.name + ":" + to.name];
-		if (time == null) return defaultMix;
-		return time as Number;
-	}
-}
-
+package spine.animation {
+import spine.SkeletonData;
+
+public class AnimationStateData {
+	internal var _skeletonData:SkeletonData;
+	private var animationToMixTime:Object = new Object();
+	public var defaultMix:Number = 0;
+
+	public function AnimationStateData (skeletonData:SkeletonData) {
+		_skeletonData = skeletonData;
+	}
+
+	public function get skeletonData () : SkeletonData {
+		return _skeletonData;
+	}
+
+	public function setMixByName (fromName:String, toName:String, duration:Number) : void {
+		var from:Animation = _skeletonData.findAnimation(fromName);
+		if (from == null) throw new ArgumentError("Animation not found: " + fromName);
+		var to:Animation = _skeletonData.findAnimation(toName);
+		if (to == null) throw new ArgumentError("Animation not found: " + toName);
+		setMix(from, to, duration);
+	}
+
+	public function setMix (from:Animation, to:Animation, duration:Number) : void {
+		if (from == null) throw new ArgumentError("from cannot be null.");
+		if (to == null) throw new ArgumentError("to cannot be null.");
+		animationToMixTime[from.name + ":" + to.name] = duration;
+	}
+
+	public function getMix (from:Animation, to:Animation) : Number {
+		var time:Object = animationToMixTime[from.name + ":" + to.name];
+		if (time == null) return defaultMix;
+		return time as Number;
+	}
+}
+
 }

+ 67 - 68
spine-as3/spine-as3/src/spine/animation/AttachmentTimeline.as

@@ -1,71 +1,70 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.Event;
-import spine.Skeleton;
-
-public class AttachmentTimeline implements Timeline {
-	public var slotIndex:int;
-	public var frames:Vector.<Number>; // time, ...
-	public var attachmentNames:Vector.<String>;
-
-	public function AttachmentTimeline (frameCount:int) {
-		frames = new Vector.<Number>(frameCount, true);
-		attachmentNames = new Vector.<String>(frameCount, true);
-	}
-
-	public function get frameCount () : int {
-		return frames.length;
-	}
-
-	/** Sets the time and value of the specified keyframe. */
-	public function setFrame (frameIndex:int, time:Number, attachmentName:String) : void {
-		frames[frameIndex] = time;
-		attachmentNames[frameIndex] = attachmentName;
-	}
-
-	public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
-		var frames:Vector.<Number> = this.frames;
-		if (time < frames[0]) return; // Time is before first frame.
-
-		var frameIndex:int;
-		if (time >= frames[frames.length - 1]) // Time is after last frame.
-			frameIndex = frames.length - 1;
-		else
-			frameIndex = Animation.binarySearch(frames, time, 1) - 1;
-
-		var attachmentName:String = attachmentNames[frameIndex];
-		skeleton.slots[slotIndex].attachment = attachmentName == null ? null : skeleton.getAttachmentForSlotIndex(slotIndex, attachmentName);
-	}
-}
-
+package spine.animation {
+import spine.Event;
+import spine.Skeleton;
+
+public class AttachmentTimeline implements Timeline {
+	public var slotIndex:int;
+	public var frames:Vector.<Number>; // time, ...
+	public var attachmentNames:Vector.<String>;
+
+	public function AttachmentTimeline (frameCount:int) {
+		frames = new Vector.<Number>(frameCount, true);
+		attachmentNames = new Vector.<String>(frameCount, true);
+	}
+
+	public function get frameCount () : int {
+		return frames.length;
+	}
+
+	/** Sets the time and value of the specified keyframe. */
+	public function setFrame (frameIndex:int, time:Number, attachmentName:String) : void {
+		frames[frameIndex] = time;
+		attachmentNames[frameIndex] = attachmentName;
+	}
+
+	public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
+		var frames:Vector.<Number> = this.frames;
+		if (time < frames[0]) return; // Time is before first frame.
+
+		var frameIndex:int;
+		if (time >= frames[frames.length - 1]) // Time is after last frame.
+			frameIndex = frames.length - 1;
+		else
+			frameIndex = Animation.binarySearch(frames, time, 1) - 1;
+
+		var attachmentName:String = attachmentNames[frameIndex];
+		skeleton.slots[slotIndex].attachment = attachmentName == null ? null : skeleton.getAttachmentForSlotIndex(slotIndex, attachmentName);
+	}
+}
+
 }

+ 99 - 100
spine-as3/spine-as3/src/spine/animation/ColorTimeline.as

@@ -1,103 +1,102 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.Event;
-import spine.Skeleton;
-import spine.Slot;
-
-public class ColorTimeline extends CurveTimeline {
-	static public const ENTRIES:int = 5;
-	static internal const PREV_TIME:int = -5, PREV_R:int = -4, PREV_G:int = -3, PREV_B:int = -2, PREV_A:int = -1;
-	static internal const R:int = 1, G:int = 2, B:int = 3, A:int = 4;
-
-	public var slotIndex:int;
-	public var frames:Vector.<Number>; // time, r, g, b, a, ...
-
-	public function ColorTimeline (frameCount:int) {
-		super(frameCount);
-		frames = new Vector.<Number>(frameCount * 5, true);
-	}
-
-	/** Sets the time and value of the specified keyframe. */
-	public function setFrame (frameIndex:int, time:Number, r:Number, g:Number, b:Number, a:Number) : void {
-		frameIndex *= ENTRIES;
-		frames[frameIndex] = time;
-		frames[int(frameIndex + R)] = r;
-		frames[int(frameIndex + G)] = g;
-		frames[int(frameIndex + B)] = b;
-		frames[int(frameIndex + A)] = a;
-	}
-
-	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
-		if (time < frames[0])
-			return; // Time is before first frame.
-
-		var r:Number, g:Number, b:Number, a:Number;
-		if (time >= frames[int(frames.length - ENTRIES)]) {
-			// Time is after last frame.
-			var i:int = frames.length;
-			r = frames[int(i + PREV_R)];
-			g = frames[int(i + PREV_G)];
-			b = frames[int(i + PREV_B)];
-			a = frames[int(i + PREV_A)];
-		} else {
-			// Interpolate between the previous frame and the current frame.
-			var frame:int = Animation.binarySearch(frames, time, ENTRIES);
-			r = frames[int(frame + PREV_R)];
-			g = frames[int(frame + PREV_G)];
-			b = frames[int(frame + PREV_B)];
-			a = frames[int(frame + PREV_A)];
-			var frameTime:Number = frames[frame];
-			var percent:Number = getCurvePercent(frame / ENTRIES - 1,
-					1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
-
-			r += (frames[frame + R] - r) * percent;
-			g += (frames[frame + G] - g) * percent;
-			b += (frames[frame + B] - b) * percent;
-			a += (frames[frame + A] - a) * percent;
-		}
-		var slot:Slot = skeleton.slots[slotIndex];
-		if (alpha < 1) {
-			slot.r += (r - slot.r) * alpha;
-			slot.g += (g - slot.g) * alpha;
-			slot.b += (b - slot.b) * alpha;
-			slot.a += (a - slot.a) * alpha;
-		} else {
-			slot.r = r;
-			slot.g = g;
-			slot.b = b;
-			slot.a = a;
-		}
-	}
-}
-
+package spine.animation {
+import spine.Event;
+import spine.Skeleton;
+import spine.Slot;
+
+public class ColorTimeline extends CurveTimeline {
+	static public const ENTRIES:int = 5;
+	static internal const PREV_TIME:int = -5, PREV_R:int = -4, PREV_G:int = -3, PREV_B:int = -2, PREV_A:int = -1;
+	static internal const R:int = 1, G:int = 2, B:int = 3, A:int = 4;
+
+	public var slotIndex:int;
+	public var frames:Vector.<Number>; // time, r, g, b, a, ...
+
+	public function ColorTimeline (frameCount:int) {
+		super(frameCount);
+		frames = new Vector.<Number>(frameCount * 5, true);
+	}
+
+	/** Sets the time and value of the specified keyframe. */
+	public function setFrame (frameIndex:int, time:Number, r:Number, g:Number, b:Number, a:Number) : void {
+		frameIndex *= ENTRIES;
+		frames[frameIndex] = time;
+		frames[int(frameIndex + R)] = r;
+		frames[int(frameIndex + G)] = g;
+		frames[int(frameIndex + B)] = b;
+		frames[int(frameIndex + A)] = a;
+	}
+
+	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
+		if (time < frames[0])
+			return; // Time is before first frame.
+
+		var r:Number, g:Number, b:Number, a:Number;
+		if (time >= frames[int(frames.length - ENTRIES)]) {
+			// Time is after last frame.
+			var i:int = frames.length;
+			r = frames[int(i + PREV_R)];
+			g = frames[int(i + PREV_G)];
+			b = frames[int(i + PREV_B)];
+			a = frames[int(i + PREV_A)];
+		} else {
+			// Interpolate between the previous frame and the current frame.
+			var frame:int = Animation.binarySearch(frames, time, ENTRIES);
+			r = frames[int(frame + PREV_R)];
+			g = frames[int(frame + PREV_G)];
+			b = frames[int(frame + PREV_B)];
+			a = frames[int(frame + PREV_A)];
+			var frameTime:Number = frames[frame];
+			var percent:Number = getCurvePercent(frame / ENTRIES - 1,
+					1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
+
+			r += (frames[frame + R] - r) * percent;
+			g += (frames[frame + G] - g) * percent;
+			b += (frames[frame + B] - b) * percent;
+			a += (frames[frame + A] - a) * percent;
+		}
+		var slot:Slot = skeleton.slots[slotIndex];
+		if (alpha < 1) {
+			slot.r += (r - slot.r) * alpha;
+			slot.g += (g - slot.g) * alpha;
+			slot.b += (b - slot.b) * alpha;
+			slot.a += (a - slot.a) * alpha;
+		} else {
+			slot.r = r;
+			slot.g = g;
+			slot.b = b;
+			slot.a = a;
+		}
+	}
+}
+
 }

+ 115 - 116
spine-as3/spine-as3/src/spine/animation/CurveTimeline.as

@@ -1,119 +1,118 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-	import spine.MathUtils;
-import spine.Event;
-import spine.Skeleton;
-
-/** Base class for frames that use an interpolation bezier curve. */
-public class CurveTimeline implements Timeline {
-	static private const LINEAR:Number = 0;
-	static private const STEPPED:Number = 1;
-	static private const BEZIER:Number = 2;	
-	static private const BEZIER_SIZE:int = 10 * 2 - 1;
-
-	private var curves:Vector.<Number>; // type, x, y, ...
-
-	public function CurveTimeline (frameCount:int) {
-		curves = new Vector.<Number>((frameCount - 1) * BEZIER_SIZE, true);
-	}
-
-	public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
-	}
-
-	public function get frameCount () : int {
-		return curves.length / BEZIER_SIZE + 1;
-	}
-
-	public function setLinear (frameIndex:int) : void {
-		curves[int(frameIndex * BEZIER_SIZE)] = LINEAR;
-	}
-
-	public function setStepped (frameIndex:int) : void {
-		curves[int(frameIndex * BEZIER_SIZE)] = STEPPED;
-	}
-
-	/** Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next.
-	 * cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of
-	 * the difference between the keyframe's values. */
-	public function setCurve (frameIndex:int, cx1:Number, cy1:Number, cx2:Number, cy2:Number) : void {
-		var tmpx:Number = (-cx1 * 2 + cx2) * 0.03, tmpy:Number = (-cy1 * 2 + cy2) * 0.03;
-		var dddfx:Number = ((cx1 - cx2) * 3 + 1) * 0.006, dddfy:Number = ((cy1 - cy2) * 3 + 1) * 0.006;
-		var ddfx:Number = tmpx * 2 + dddfx, ddfy:Number = tmpy * 2 + dddfy;
-		var dfx:Number = cx1 * 0.3 + tmpx + dddfx * 0.16666667, dfy:Number = cy1 * 0.3 + tmpy + dddfy * 0.16666667;
-
-		var i:int = frameIndex * BEZIER_SIZE;
-		var curves:Vector.<Number> = this.curves;
-		curves[int(i++)] = BEZIER;
-
-		var x:Number = dfx, y:Number = dfy;
-		for (var n:int = i + BEZIER_SIZE - 1; i < n; i += 2) {
-			curves[i] = x;
-			curves[int(i + 1)] = y;
-			dfx += ddfx;
-			dfy += ddfy;
-			ddfx += dddfx;
-			ddfy += dddfy;
-			x += dfx;
-			y += dfy;
-		}
-	}
-
-	public function getCurvePercent (frameIndex:int, percent:Number) : Number {
-		percent = MathUtils.clamp(percent, 0, 1);
-		var curves:Vector.<Number> = this.curves;
-		var i:int = frameIndex * BEZIER_SIZE;
-		var type:Number = curves[i];
-		if (type == LINEAR) return percent;
-		if (type == STEPPED) return 0;
-		i++;
-		var x:Number = 0;
-		for (var start:int = i, n:int = i + BEZIER_SIZE - 1; i < n; i += 2) {
-			x = curves[i];
-			if (x >= percent) {
-				var prevX:Number, prevY:Number;
-				if (i == start) {
-					prevX = 0;
-					prevY = 0;
-				} else {
-					prevX = curves[int(i - 2)];
-					prevY = curves[int(i - 1)];
-				}
-				return prevY + (curves[int(i + 1)] - prevY) * (percent - prevX) / (x - prevX);
-			}
-		}
-		var y:Number = curves[int(i - 1)];
-		return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1.
-	}
-}
-
+package spine.animation {
+	import spine.MathUtils;
+import spine.Event;
+import spine.Skeleton;
+
+/** Base class for frames that use an interpolation bezier curve. */
+public class CurveTimeline implements Timeline {
+	static private const LINEAR:Number = 0;
+	static private const STEPPED:Number = 1;
+	static private const BEZIER:Number = 2;	
+	static private const BEZIER_SIZE:int = 10 * 2 - 1;
+
+	private var curves:Vector.<Number>; // type, x, y, ...
+
+	public function CurveTimeline (frameCount:int) {
+		curves = new Vector.<Number>((frameCount - 1) * BEZIER_SIZE, true);
+	}
+
+	public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
+	}
+
+	public function get frameCount () : int {
+		return curves.length / BEZIER_SIZE + 1;
+	}
+
+	public function setLinear (frameIndex:int) : void {
+		curves[int(frameIndex * BEZIER_SIZE)] = LINEAR;
+	}
+
+	public function setStepped (frameIndex:int) : void {
+		curves[int(frameIndex * BEZIER_SIZE)] = STEPPED;
+	}
+
+	/** Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next.
+	 * cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of
+	 * the difference between the keyframe's values. */
+	public function setCurve (frameIndex:int, cx1:Number, cy1:Number, cx2:Number, cy2:Number) : void {
+		var tmpx:Number = (-cx1 * 2 + cx2) * 0.03, tmpy:Number = (-cy1 * 2 + cy2) * 0.03;
+		var dddfx:Number = ((cx1 - cx2) * 3 + 1) * 0.006, dddfy:Number = ((cy1 - cy2) * 3 + 1) * 0.006;
+		var ddfx:Number = tmpx * 2 + dddfx, ddfy:Number = tmpy * 2 + dddfy;
+		var dfx:Number = cx1 * 0.3 + tmpx + dddfx * 0.16666667, dfy:Number = cy1 * 0.3 + tmpy + dddfy * 0.16666667;
+
+		var i:int = frameIndex * BEZIER_SIZE;
+		var curves:Vector.<Number> = this.curves;
+		curves[int(i++)] = BEZIER;
+
+		var x:Number = dfx, y:Number = dfy;
+		for (var n:int = i + BEZIER_SIZE - 1; i < n; i += 2) {
+			curves[i] = x;
+			curves[int(i + 1)] = y;
+			dfx += ddfx;
+			dfy += ddfy;
+			ddfx += dddfx;
+			ddfy += dddfy;
+			x += dfx;
+			y += dfy;
+		}
+	}
+
+	public function getCurvePercent (frameIndex:int, percent:Number) : Number {
+		percent = MathUtils.clamp(percent, 0, 1);
+		var curves:Vector.<Number> = this.curves;
+		var i:int = frameIndex * BEZIER_SIZE;
+		var type:Number = curves[i];
+		if (type == LINEAR) return percent;
+		if (type == STEPPED) return 0;
+		i++;
+		var x:Number = 0;
+		for (var start:int = i, n:int = i + BEZIER_SIZE - 1; i < n; i += 2) {
+			x = curves[i];
+			if (x >= percent) {
+				var prevX:Number, prevY:Number;
+				if (i == start) {
+					prevX = 0;
+					prevY = 0;
+				} else {
+					prevX = curves[int(i - 2)];
+					prevY = curves[int(i - 1)];
+				}
+				return prevY + (curves[int(i + 1)] - prevY) * (percent - prevX) / (x - prevX);
+			}
+		}
+		var y:Number = curves[int(i - 1)];
+		return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1.
+	}
+}
+
 }

+ 102 - 103
spine-as3/spine-as3/src/spine/animation/DeformTimeline.as

@@ -1,106 +1,105 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.attachments.VertexAttachment;
-import spine.Event;
-import spine.Skeleton;
-import spine.Slot;
-
-public class DeformTimeline extends CurveTimeline {
-	public var slotIndex:int;
-	public var frames:Vector.<Number>;
-	public var frameVertices:Vector.<Vector.<Number>>;
-	public var attachment:VertexAttachment;
-
-	public function DeformTimeline (frameCount:int) {
-		super(frameCount);
-		frames = new Vector.<Number>(frameCount, true);
-		frameVertices = new Vector.<Vector.<Number>>(frameCount, true);
-	}
-
-	/** Sets the time and value of the specified keyframe. */
-	public function setFrame (frameIndex:int, time:Number, vertices:Vector.<Number>) : void {
-		frames[frameIndex] = time;
-		frameVertices[frameIndex] = vertices;
-	}
-
-	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
-		var slot:Slot = skeleton.slots[slotIndex];
-		var slotAttachment:VertexAttachment = slot.attachment as VertexAttachment;
-		if (!slotAttachment || !slotAttachment.applyDeform(attachment)) return;
-
-		var frames:Vector.<Number> = this.frames;
-		if (time < frames[0]) return; // Time is before first frame.
-
-		var frameVertices:Vector.<Vector.<Number>> = this.frameVertices;
-		var vertexCount:int = frameVertices[0].length;
-
-		var vertices:Vector.<Number> = slot.attachmentVertices;
-		if (vertices.length != vertexCount) alpha = 1; // Don't mix from uninitialized slot vertices.
-		vertices.length = vertexCount;
-
-		var i:int;
-		if (time >= frames[frames.length - 1]) { // Time is after last frame.
-			var lastVertices:Vector.<Number> = frameVertices[int(frames.length - 1)];
-			if (alpha < 1) {
-				for (i = 0; i < vertexCount; i++)
-					vertices[i] += (lastVertices[i] - vertices[i]) * alpha;
-			} else {
-				for (i = 0; i < vertexCount; i++)
-					vertices[i] = lastVertices[i];
-			}
-			return;
-		}
-
-		// Interpolate between the previous frame and the current frame.
-		var frame:int = Animation.binarySearch1(frames, time);
-		var prevVertices:Vector.<Number> = frameVertices[int(frame - 1)];
-		var nextVertices:Vector.<Number> = frameVertices[frame];
-		var frameTime:Number = frames[frame];		
-		var percent:Number = getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime));		
-
-		var prev:Number;
-		if (alpha < 1) {
-			for (i = 0; i < vertexCount; i++) {
-				prev = prevVertices[i];
-				vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha;
-			}
-		} else {
-			for (i = 0; i < vertexCount; i++) {
-				prev = prevVertices[i];
-				vertices[i] = prev + (nextVertices[i] - prev) * percent;
-			}
-		}
-	}
-}
-
+package spine.animation {
+import spine.attachments.VertexAttachment;
+import spine.Event;
+import spine.Skeleton;
+import spine.Slot;
+
+public class DeformTimeline extends CurveTimeline {
+	public var slotIndex:int;
+	public var frames:Vector.<Number>;
+	public var frameVertices:Vector.<Vector.<Number>>;
+	public var attachment:VertexAttachment;
+
+	public function DeformTimeline (frameCount:int) {
+		super(frameCount);
+		frames = new Vector.<Number>(frameCount, true);
+		frameVertices = new Vector.<Vector.<Number>>(frameCount, true);
+	}
+
+	/** Sets the time and value of the specified keyframe. */
+	public function setFrame (frameIndex:int, time:Number, vertices:Vector.<Number>) : void {
+		frames[frameIndex] = time;
+		frameVertices[frameIndex] = vertices;
+	}
+
+	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
+		var slot:Slot = skeleton.slots[slotIndex];
+		var slotAttachment:VertexAttachment = slot.attachment as VertexAttachment;
+		if (!slotAttachment || !slotAttachment.applyDeform(attachment)) return;
+
+		var frames:Vector.<Number> = this.frames;
+		if (time < frames[0]) return; // Time is before first frame.
+
+		var frameVertices:Vector.<Vector.<Number>> = this.frameVertices;
+		var vertexCount:int = frameVertices[0].length;
+
+		var vertices:Vector.<Number> = slot.attachmentVertices;
+		if (vertices.length != vertexCount) alpha = 1; // Don't mix from uninitialized slot vertices.
+		vertices.length = vertexCount;
+
+		var i:int;
+		if (time >= frames[frames.length - 1]) { // Time is after last frame.
+			var lastVertices:Vector.<Number> = frameVertices[int(frames.length - 1)];
+			if (alpha < 1) {
+				for (i = 0; i < vertexCount; i++)
+					vertices[i] += (lastVertices[i] - vertices[i]) * alpha;
+			} else {
+				for (i = 0; i < vertexCount; i++)
+					vertices[i] = lastVertices[i];
+			}
+			return;
+		}
+
+		// Interpolate between the previous frame and the current frame.
+		var frame:int = Animation.binarySearch1(frames, time);
+		var prevVertices:Vector.<Number> = frameVertices[int(frame - 1)];
+		var nextVertices:Vector.<Number> = frameVertices[frame];
+		var frameTime:Number = frames[frame];		
+		var percent:Number = getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime));		
+
+		var prev:Number;
+		if (alpha < 1) {
+			for (i = 0; i < vertexCount; i++) {
+				prev = prevVertices[i];
+				vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha;
+			}
+		} else {
+			for (i = 0; i < vertexCount; i++) {
+				prev = prevVertices[i];
+				vertices[i] = prev + (nextVertices[i] - prev) * percent;
+			}
+		}
+	}
+}
+
 }

+ 76 - 77
spine-as3/spine-as3/src/spine/animation/DrawOrderTimeline.as

@@ -1,80 +1,79 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.Event;
-import spine.Skeleton;
-import spine.Slot;
-
-public class DrawOrderTimeline implements Timeline {
-	public var frames:Vector.<Number>; // time, ...
-	public var drawOrders:Vector.<Vector.<int>>;
-
-	public function DrawOrderTimeline (frameCount:int) {
-		frames = new Vector.<Number>(frameCount, true);
-		drawOrders = new Vector.<Vector.<int>>(frameCount, true);
-	}
-
-	public function get frameCount () : int {
-		return frames.length;
-	}
-
-	/** Sets the time and value of the specified keyframe. */
-	public function setFrame (frameIndex:int, time:Number, drawOrder:Vector.<int>) : void {
-		frames[frameIndex] = time;
-		drawOrders[frameIndex] = drawOrder;
-	}
-
-	public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
-		if (time < frames[0])
-			return; // Time is before first frame.
-
-		var frameIndex:int;
-		if (time >= frames[int(frames.length - 1)]) // Time is after last frame.
-			frameIndex = frames.length - 1;
-		else
-			frameIndex = Animation.binarySearch1(frames, time) - 1;
-
-		var drawOrder:Vector.<Slot> = skeleton.drawOrder;
-		var slots:Vector.<Slot> = skeleton.slots;
-		var drawOrderToSetupIndex:Vector.<int> = drawOrders[frameIndex];
-		var i:int = 0;
-		if (!drawOrderToSetupIndex) {
-			for each (var slot:Slot in slots)
-				drawOrder[i++] = slot;
-		} else {
-			for each (var setupIndex:int in drawOrderToSetupIndex) 
-				drawOrder[i++] = slots[setupIndex];
-		}
-	}
-}
-
+package spine.animation {
+import spine.Event;
+import spine.Skeleton;
+import spine.Slot;
+
+public class DrawOrderTimeline implements Timeline {
+	public var frames:Vector.<Number>; // time, ...
+	public var drawOrders:Vector.<Vector.<int>>;
+
+	public function DrawOrderTimeline (frameCount:int) {
+		frames = new Vector.<Number>(frameCount, true);
+		drawOrders = new Vector.<Vector.<int>>(frameCount, true);
+	}
+
+	public function get frameCount () : int {
+		return frames.length;
+	}
+
+	/** Sets the time and value of the specified keyframe. */
+	public function setFrame (frameIndex:int, time:Number, drawOrder:Vector.<int>) : void {
+		frames[frameIndex] = time;
+		drawOrders[frameIndex] = drawOrder;
+	}
+
+	public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
+		if (time < frames[0])
+			return; // Time is before first frame.
+
+		var frameIndex:int;
+		if (time >= frames[int(frames.length - 1)]) // Time is after last frame.
+			frameIndex = frames.length - 1;
+		else
+			frameIndex = Animation.binarySearch1(frames, time) - 1;
+
+		var drawOrder:Vector.<Slot> = skeleton.drawOrder;
+		var slots:Vector.<Slot> = skeleton.slots;
+		var drawOrderToSetupIndex:Vector.<int> = drawOrders[frameIndex];
+		var i:int = 0;
+		if (!drawOrderToSetupIndex) {
+			for each (var slot:Slot in slots)
+				drawOrder[i++] = slot;
+		} else {
+			for each (var setupIndex:int in drawOrderToSetupIndex) 
+				drawOrder[i++] = slots[setupIndex];
+		}
+	}
+}
+
 }

+ 78 - 79
spine-as3/spine-as3/src/spine/animation/EventTimeline.as

@@ -1,82 +1,81 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.Event;
-import spine.Skeleton;
-
-public class EventTimeline implements Timeline {
-	public var frames:Vector.<Number>; // time, ...
-	public var events:Vector.<Event>;
-
-	public function EventTimeline (frameCount:int) {
-		frames = new Vector.<Number>(frameCount, true);
-		events = new Vector.<Event>(frameCount, true);
-	}
-
-	public function get frameCount () : int {
-		return frames.length;
-	}
-
-	/** Sets the time and value of the specified keyframe. */
-	public function setFrame (frameIndex:int, event:Event) : void {
-		frames[frameIndex] = event.time;
-		events[frameIndex] = event;
-	}
-
-	/** Fires events for frames > lastTime and <= time. */
-	public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
-		if (!firedEvents) return;
-		
-		if (lastTime > time) { // Fire events after last time for looped animations.
-			apply(skeleton, lastTime, int.MAX_VALUE, firedEvents, alpha);
-			lastTime = -1;
-		} else if (lastTime >= frames[int(frameCount - 1)]) // Last time is after last frame.
-			return;
-		if (time < frames[0]) return; // Time is before first frame.
-		
-		var frame:int;
-		if (lastTime < frames[0])
-			frame = 0;
-		else {
-			frame = Animation.binarySearch1(frames, lastTime);
-			var frameTime:Number = frames[frame];
-			while (frame > 0) { // Fire multiple events with the same frame.
-				if (frames[int(frame - 1)] != frameTime) break;
-				frame--;
-			}
-		}
-		for (; frame < frameCount && time >= frames[frame]; frame++)
-			firedEvents[firedEvents.length] = events[frame];
-	}
-}
-
+package spine.animation {
+import spine.Event;
+import spine.Skeleton;
+
+public class EventTimeline implements Timeline {
+	public var frames:Vector.<Number>; // time, ...
+	public var events:Vector.<Event>;
+
+	public function EventTimeline (frameCount:int) {
+		frames = new Vector.<Number>(frameCount, true);
+		events = new Vector.<Event>(frameCount, true);
+	}
+
+	public function get frameCount () : int {
+		return frames.length;
+	}
+
+	/** Sets the time and value of the specified keyframe. */
+	public function setFrame (frameIndex:int, event:Event) : void {
+		frames[frameIndex] = event.time;
+		events[frameIndex] = event;
+	}
+
+	/** Fires events for frames > lastTime and <= time. */
+	public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
+		if (!firedEvents) return;
+		
+		if (lastTime > time) { // Fire events after last time for looped animations.
+			apply(skeleton, lastTime, int.MAX_VALUE, firedEvents, alpha);
+			lastTime = -1;
+		} else if (lastTime >= frames[int(frameCount - 1)]) // Last time is after last frame.
+			return;
+		if (time < frames[0]) return; // Time is before first frame.
+		
+		var frame:int;
+		if (lastTime < frames[0])
+			frame = 0;
+		else {
+			frame = Animation.binarySearch1(frames, lastTime);
+			var frameTime:Number = frames[frame];
+			while (frame > 0) { // Fire multiple events with the same frame.
+				if (frames[int(frame - 1)] != frameTime) break;
+				frame--;
+			}
+		}
+		for (; frame < frameCount && time >= frames[frame]; frame++)
+			firedEvents[firedEvents.length] = events[frame];
+	}
+}
+
 }

+ 76 - 77
spine-as3/spine-as3/src/spine/animation/IkConstraintTimeline.as

@@ -1,80 +1,79 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.Event;
-import spine.IkConstraint;
-import spine.Skeleton;
-
-public class IkConstraintTimeline extends CurveTimeline {
-	static public const ENTRIES:int = 3;
-	static internal const PREV_TIME:int = -3, PREV_MIX:int = -2, PREV_BEND_DIRECTION:int = -1;
-	static internal const MIX:int = 1, BEND_DIRECTION:int = 2;
-
-	public var ikConstraintIndex:int;
-	public var frames:Vector.<Number>; // time, mix, bendDirection, ...
-
-	public function IkConstraintTimeline (frameCount:int) {
-		super(frameCount);
-		frames = new Vector.<Number>(frameCount * ENTRIES, true);
-	}
-
-	/** Sets the time, mix and bend direction of the specified keyframe. */
-	public function setFrame (frameIndex:int, time:Number, mix:Number, bendDirection:int) : void {
-		frameIndex *= ENTRIES;
-		frames[frameIndex] = time;
-		frames[int(frameIndex + MIX)] = mix;
-		frames[int(frameIndex + BEND_DIRECTION)] = bendDirection;
-	}
-
-	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
-		if (time < frames[0]) return; // Time is before first frame.
-
-		var constraint:IkConstraint = skeleton.ikConstraints[ikConstraintIndex];
-
-		if (time >= frames[int(frames.length - ENTRIES)]) { // Time is after last frame.
-			constraint.mix += (frames[int(frames.length + PREV_MIX)] - constraint.mix) * alpha;
-			constraint.bendDirection = int(frames[int(frames.length + PREV_BEND_DIRECTION)]);
-			return;
-		}
-
-		// Interpolate between the previous frame and the current frame.
-		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
-		var mix:Number = frames[int(frame + PREV_MIX)];
-		var frameTime:Number = frames[frame];
-		var percent:Number = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
-
-		constraint.mix += (mix + (frames[frame + MIX] - mix) * percent - constraint.mix) * alpha;
-		constraint.bendDirection = int(frames[frame + PREV_BEND_DIRECTION]);
-	}
-}
-
+package spine.animation {
+import spine.Event;
+import spine.IkConstraint;
+import spine.Skeleton;
+
+public class IkConstraintTimeline extends CurveTimeline {
+	static public const ENTRIES:int = 3;
+	static internal const PREV_TIME:int = -3, PREV_MIX:int = -2, PREV_BEND_DIRECTION:int = -1;
+	static internal const MIX:int = 1, BEND_DIRECTION:int = 2;
+
+	public var ikConstraintIndex:int;
+	public var frames:Vector.<Number>; // time, mix, bendDirection, ...
+
+	public function IkConstraintTimeline (frameCount:int) {
+		super(frameCount);
+		frames = new Vector.<Number>(frameCount * ENTRIES, true);
+	}
+
+	/** Sets the time, mix and bend direction of the specified keyframe. */
+	public function setFrame (frameIndex:int, time:Number, mix:Number, bendDirection:int) : void {
+		frameIndex *= ENTRIES;
+		frames[frameIndex] = time;
+		frames[int(frameIndex + MIX)] = mix;
+		frames[int(frameIndex + BEND_DIRECTION)] = bendDirection;
+	}
+
+	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
+		if (time < frames[0]) return; // Time is before first frame.
+
+		var constraint:IkConstraint = skeleton.ikConstraints[ikConstraintIndex];
+
+		if (time >= frames[int(frames.length - ENTRIES)]) { // Time is after last frame.
+			constraint.mix += (frames[int(frames.length + PREV_MIX)] - constraint.mix) * alpha;
+			constraint.bendDirection = int(frames[int(frames.length + PREV_BEND_DIRECTION)]);
+			return;
+		}
+
+		// Interpolate between the previous frame and the current frame.
+		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
+		var mix:Number = frames[int(frame + PREV_MIX)];
+		var frameTime:Number = frames[frame];
+		var percent:Number = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
+
+		constraint.mix += (mix + (frames[frame + MIX] - mix) * percent - constraint.mix) * alpha;
+		constraint.bendDirection = int(frames[frame + PREV_BEND_DIRECTION]);
+	}
+}
+
 }

+ 60 - 61
spine-as3/spine-as3/src/spine/animation/Listeners.as

@@ -1,64 +1,63 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-	public class Listeners {
-		private var _listeners:Vector.<Function> = new Vector.<Function>();
-		
-		public function Listeners () {			
-		}
-		
-		public function get listeners () : Vector.<Function> {
-			return _listeners;
-		}
-		
-		public function add (listener:Function) : void {
-			if (listener == null)
-				throw new ArgumentError("listener cannot be null.");
-			var indexOf:int = _listeners.indexOf(listener);
-			if (indexOf == -1)
-				_listeners[_listeners.length] = listener;
-		}
-
-		public function remove (listener:Function) : void {
-			if (listener == null)
-				throw new ArgumentError("listener cannot be null.");
-			var indexOf:int = _listeners.indexOf(listener);
-			if (indexOf != -1)
-				_listeners.splice(_listeners.indexOf(listener), 1);
-		}
-
-		public function invoke (... args:*) : void {
-			for each (var listener:Function in _listeners)
-				listener.apply(null, args);
-		}
-	}
+package spine.animation {
+	public class Listeners {
+		private var _listeners:Vector.<Function> = new Vector.<Function>();
+		
+		public function Listeners () {			
+		}
+		
+		public function get listeners () : Vector.<Function> {
+			return _listeners;
+		}
+		
+		public function add (listener:Function) : void {
+			if (listener == null)
+				throw new ArgumentError("listener cannot be null.");
+			var indexOf:int = _listeners.indexOf(listener);
+			if (indexOf == -1)
+				_listeners[_listeners.length] = listener;
+		}
+
+		public function remove (listener:Function) : void {
+			if (listener == null)
+				throw new ArgumentError("listener cannot be null.");
+			var indexOf:int = _listeners.indexOf(listener);
+			if (indexOf != -1)
+				_listeners.splice(_listeners.indexOf(listener), 1);
+		}
+
+		public function invoke (... args:*) : void {
+			for each (var listener:Function in _listeners)
+				listener.apply(null, args);
+		}
+	}
 }

+ 79 - 80
spine-as3/spine-as3/src/spine/animation/PathConstraintMixTimeline.as

@@ -1,83 +1,82 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.Event;
-import spine.Skeleton;
-import spine.PathConstraint;
-
-public class PathConstraintMixTimeline extends CurveTimeline {
-	static public const ENTRIES:int = 3;
-	static internal const PREV_TIME:int = -3, PREV_ROTATE:int = -2, PREV_TRANSLATE:int = -1;
-	static internal const ROTATE:int = 1, TRANSLATE:int = 2;
-
-	public var pathConstraintIndex:int;
-	
-	public var frames:Vector.<Number>; // time, rotate mix, translate mix, ...
-
-	public function PathConstraintMixTimeline (frameCount:int) {
-		super(frameCount);
-		frames = new Vector.<Number>(frameCount * ENTRIES, true);
-	}	
-
-	/** Sets the time and mixes of the specified keyframe. */
-	public function setFrame (frameIndex:int, time:Number, rotateMix:Number, translateMix:Number) : void {
-		frameIndex *= ENTRIES;
-		frames[frameIndex] = time;
-		frames[frameIndex + ROTATE] = rotateMix;
-		frames[frameIndex + TRANSLATE] = translateMix;
-	}
-
-	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {		
-		if (time < frames[0]) return; // Time is before first frame.
-
-		var constraint:PathConstraint = skeleton.pathConstraints[pathConstraintIndex];
-
-		if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
-			var i:int = frames.length;
-			constraint.rotateMix += (frames[i + PREV_ROTATE] - constraint.rotateMix) * alpha;
-			constraint.translateMix += (frames[i + PREV_TRANSLATE] - constraint.translateMix) * alpha;
-			return;
-		}
-
-		// Interpolate between the previous frame and the current frame.
-		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
-		var rotate:Number = frames[frame + PREV_ROTATE];
-		var translate:Number = frames[frame + PREV_TRANSLATE];
-		var frameTime:Number = frames[frame];
-		var percent:Number = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
-
-		constraint.rotateMix += (rotate + (frames[frame + ROTATE] - rotate) * percent - constraint.rotateMix) * alpha;
-		constraint.translateMix += (translate + (frames[frame + TRANSLATE] - translate) * percent - constraint.translateMix)
-			* alpha;
-	}
+package spine.animation {
+import spine.Event;
+import spine.Skeleton;
+import spine.PathConstraint;
+
+public class PathConstraintMixTimeline extends CurveTimeline {
+	static public const ENTRIES:int = 3;
+	static internal const PREV_TIME:int = -3, PREV_ROTATE:int = -2, PREV_TRANSLATE:int = -1;
+	static internal const ROTATE:int = 1, TRANSLATE:int = 2;
+
+	public var pathConstraintIndex:int;
+	
+	public var frames:Vector.<Number>; // time, rotate mix, translate mix, ...
+
+	public function PathConstraintMixTimeline (frameCount:int) {
+		super(frameCount);
+		frames = new Vector.<Number>(frameCount * ENTRIES, true);
+	}	
+
+	/** Sets the time and mixes of the specified keyframe. */
+	public function setFrame (frameIndex:int, time:Number, rotateMix:Number, translateMix:Number) : void {
+		frameIndex *= ENTRIES;
+		frames[frameIndex] = time;
+		frames[frameIndex + ROTATE] = rotateMix;
+		frames[frameIndex + TRANSLATE] = translateMix;
+	}
+
+	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {		
+		if (time < frames[0]) return; // Time is before first frame.
+
+		var constraint:PathConstraint = skeleton.pathConstraints[pathConstraintIndex];
+
+		if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
+			var i:int = frames.length;
+			constraint.rotateMix += (frames[i + PREV_ROTATE] - constraint.rotateMix) * alpha;
+			constraint.translateMix += (frames[i + PREV_TRANSLATE] - constraint.translateMix) * alpha;
+			return;
+		}
+
+		// Interpolate between the previous frame and the current frame.
+		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
+		var rotate:Number = frames[frame + PREV_ROTATE];
+		var translate:Number = frames[frame + PREV_TRANSLATE];
+		var frameTime:Number = frames[frame];
+		var percent:Number = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
+
+		constraint.rotateMix += (rotate + (frames[frame + ROTATE] - rotate) * percent - constraint.rotateMix) * alpha;
+		constraint.translateMix += (translate + (frames[frame + TRANSLATE] - translate) * percent - constraint.translateMix)
+			* alpha;
+	}
+}
 }
-}

+ 74 - 75
spine-as3/spine-as3/src/spine/animation/PathConstraintPositionTimeline.as

@@ -1,78 +1,77 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.PathConstraint;
-import spine.Event;
-import spine.Skeleton;
-	
-public class PathConstraintPositionTimeline extends CurveTimeline {
-	static public const ENTRIES:int = 2;
-	static internal const PREV_TIME:int = -2, PREV_VALUE:int = -1;
-	static internal const VALUE:int = 1;
-
-	public var pathConstraintIndex:int;
-
-	public var frames:Vector.<Number>; // time, position, ...
-
-	public function PathConstraintPositionTimeline (frameCount:int) {
-		super(frameCount);
-		frames = new Vector.<Number>(frameCount * ENTRIES, true);
-	}
-
-	/** Sets the time and value of the specified keyframe. */
-	public function setFrame (frameIndex:int, time:Number, value:Number) : void {
-		frameIndex *= ENTRIES;
-		frames[frameIndex] = time;
-		frames[frameIndex + VALUE] = value;
-	}
-
-	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {		
-		if (time < frames[0]) return; // Time is before first frame.
-
-		var constraint:PathConstraint = skeleton.pathConstraints[pathConstraintIndex];
-
-		if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
-			var i:int = frames.length;
-			constraint.position += (frames[i + PREV_VALUE] - constraint.position) * alpha;
-			return;
-		}
-
-		// Interpolate between the previous frame and the current frame.
-		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
-		var position:Number = frames[frame + PREV_VALUE];
-		var frameTime:Number = frames[frame];
-		var percent:Number = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
-
-		constraint.position += (position + (frames[frame + VALUE] - position) * percent - constraint.position) * alpha;
-	}
+package spine.animation {
+import spine.PathConstraint;
+import spine.Event;
+import spine.Skeleton;
+	
+public class PathConstraintPositionTimeline extends CurveTimeline {
+	static public const ENTRIES:int = 2;
+	static internal const PREV_TIME:int = -2, PREV_VALUE:int = -1;
+	static internal const VALUE:int = 1;
+
+	public var pathConstraintIndex:int;
+
+	public var frames:Vector.<Number>; // time, position, ...
+
+	public function PathConstraintPositionTimeline (frameCount:int) {
+		super(frameCount);
+		frames = new Vector.<Number>(frameCount * ENTRIES, true);
+	}
+
+	/** Sets the time and value of the specified keyframe. */
+	public function setFrame (frameIndex:int, time:Number, value:Number) : void {
+		frameIndex *= ENTRIES;
+		frames[frameIndex] = time;
+		frames[frameIndex + VALUE] = value;
+	}
+
+	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {		
+		if (time < frames[0]) return; // Time is before first frame.
+
+		var constraint:PathConstraint = skeleton.pathConstraints[pathConstraintIndex];
+
+		if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
+			var i:int = frames.length;
+			constraint.position += (frames[i + PREV_VALUE] - constraint.position) * alpha;
+			return;
+		}
+
+		// Interpolate between the previous frame and the current frame.
+		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
+		var position:Number = frames[frame + PREV_VALUE];
+		var frameTime:Number = frames[frame];
+		var percent:Number = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
+
+		constraint.position += (position + (frames[frame + VALUE] - position) * percent - constraint.position) * alpha;
+	}
+}
 }
-}

+ 58 - 59
spine-as3/spine-as3/src/spine/animation/PathConstraintSpacingTimeline.as

@@ -1,62 +1,61 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.Skeleton;
-import spine.Event;
-import spine.PathConstraint;
-
-public class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
-	public function PathConstraintSpacingTimeline (frameCount:int) {
-		super(frameCount);
-	}
-
-	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {		
-		if (time < frames[0]) return; // Time is before first frame.
-
-		var constraint:PathConstraint = skeleton.pathConstraints[pathConstraintIndex];
-
-		if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
-			var i:int = frames.length;
-			constraint.spacing += (frames[i + PREV_VALUE] - constraint.spacing) * alpha;
-			return;
-		}
-
-		// Interpolate between the previous frame and the current frame.
-		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
-		var spacing:Number = frames[frame + PREV_VALUE];
-		var frameTime:Number = frames[frame];
-		var percent:Number = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
-
-		constraint.spacing += (spacing + (frames[frame + VALUE] - spacing) * percent - constraint.spacing) * alpha;
-	}
+package spine.animation {
+import spine.Skeleton;
+import spine.Event;
+import spine.PathConstraint;
+
+public class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
+	public function PathConstraintSpacingTimeline (frameCount:int) {
+		super(frameCount);
+	}
+
+	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {		
+		if (time < frames[0]) return; // Time is before first frame.
+
+		var constraint:PathConstraint = skeleton.pathConstraints[pathConstraintIndex];
+
+		if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
+			var i:int = frames.length;
+			constraint.spacing += (frames[i + PREV_VALUE] - constraint.spacing) * alpha;
+			return;
+		}
+
+		// Interpolate between the previous frame and the current frame.
+		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
+		var spacing:Number = frames[frame + PREV_VALUE];
+		var frameTime:Number = frames[frame];
+		var percent:Number = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
+
+		constraint.spacing += (spacing + (frames[frame + VALUE] - spacing) * percent - constraint.spacing) * alpha;
+	}
+}
 }
-}

+ 89 - 90
spine-as3/spine-as3/src/spine/animation/RotateTimeline.as

@@ -1,93 +1,92 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.Bone;
-import spine.Event;
-import spine.Skeleton;
-
-public class RotateTimeline extends CurveTimeline {
-	static public const ENTRIES:int = 2;
-	static private const PREV_TIME:int = -2, PREV_ROTATION:int = -1;
-	static private const ROTATION:int = 1;
-
-	public var boneIndex:int;
-	public var frames:Vector.<Number>; // time, value, ...
-
-	public function RotateTimeline (frameCount:int) {
-		super(frameCount);
-		frames = new Vector.<Number>(frameCount * 2, true);
-	}
-
-	/** Sets the time and angle of the specified keyframe. */
-	public function setFrame (frameIndex:int, time:Number, degrees:Number) : void {
-		frameIndex <<= 1;
-		frames[frameIndex] = time;
-		frames[int(frameIndex + ROTATION)] = degrees;
-	}
-
-	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
-		if (time < frames[0])
-			return; // Time is before first frame.
-
-		var bone:Bone = skeleton.bones[boneIndex];
-		
-		if (time >= frames[int(frames.length - 2)]) { // Time is after last frame.
-			var amount:Number = bone.data.rotation + frames[int(frames.length + PREV_ROTATION)] - bone.rotation;
-			while (amount > 180)
-				amount -= 360;
-			while (amount < -180)
-				amount += 360;
-			bone.rotation += amount * alpha;
-			return;
-		}
-
-		// Interpolate between the previous frame and the current frame.
-		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
-		var prevRotation:Number = frames[int(frame + PREV_ROTATION)];
-		var frameTime:Number = frames[frame];		
-		var percent:Number = getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
-
-		amount = frames[int(frame + ROTATION)] - prevRotation;
-		while (amount > 180)
-			amount -= 360;
-		while (amount < -180)
-			amount += 360;
-		amount = bone.data.rotation + (prevRotation + amount * percent) - bone.rotation;
-		while (amount > 180)
-			amount -= 360;
-		while (amount < -180)
-			amount += 360;
-		bone.rotation += amount * alpha;
-	}
-}
-
+package spine.animation {
+import spine.Bone;
+import spine.Event;
+import spine.Skeleton;
+
+public class RotateTimeline extends CurveTimeline {
+	static public const ENTRIES:int = 2;
+	static private const PREV_TIME:int = -2, PREV_ROTATION:int = -1;
+	static private const ROTATION:int = 1;
+
+	public var boneIndex:int;
+	public var frames:Vector.<Number>; // time, value, ...
+
+	public function RotateTimeline (frameCount:int) {
+		super(frameCount);
+		frames = new Vector.<Number>(frameCount * 2, true);
+	}
+
+	/** Sets the time and angle of the specified keyframe. */
+	public function setFrame (frameIndex:int, time:Number, degrees:Number) : void {
+		frameIndex <<= 1;
+		frames[frameIndex] = time;
+		frames[int(frameIndex + ROTATION)] = degrees;
+	}
+
+	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
+		if (time < frames[0])
+			return; // Time is before first frame.
+
+		var bone:Bone = skeleton.bones[boneIndex];
+		
+		if (time >= frames[int(frames.length - 2)]) { // Time is after last frame.
+			var amount:Number = bone.data.rotation + frames[int(frames.length + PREV_ROTATION)] - bone.rotation;
+			while (amount > 180)
+				amount -= 360;
+			while (amount < -180)
+				amount += 360;
+			bone.rotation += amount * alpha;
+			return;
+		}
+
+		// Interpolate between the previous frame and the current frame.
+		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
+		var prevRotation:Number = frames[int(frame + PREV_ROTATION)];
+		var frameTime:Number = frames[frame];		
+		var percent:Number = getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
+
+		amount = frames[int(frame + ROTATION)] - prevRotation;
+		while (amount > 180)
+			amount -= 360;
+		while (amount < -180)
+			amount += 360;
+		amount = bone.data.rotation + (prevRotation + amount * percent) - bone.rotation;
+		while (amount > 180)
+			amount -= 360;
+		while (amount < -180)
+			amount += 360;
+		bone.rotation += amount * alpha;
+	}
+}
+
 }

+ 61 - 62
spine-as3/spine-as3/src/spine/animation/ScaleTimeline.as

@@ -1,65 +1,64 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.Bone;
-import spine.Event;
-import spine.Skeleton;
-
-public class ScaleTimeline extends TranslateTimeline {
-	public function ScaleTimeline (frameCount:int) {
-		super(frameCount);
-	}
-
-	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
-		if (time < frames[0])
-			return; // Time is before first frame.
-
-		var bone:Bone = skeleton.bones[boneIndex];
-		if (time >= frames[int(frames.length - ENTRIES)]) { // Time is after last frame.
-			bone.scaleX += (bone.data.scaleX * frames[int(frames.length + PREV_X)] - bone.scaleX) * alpha;
-			bone.scaleY += (bone.data.scaleY * frames[int(frames.length + PREV_Y)] - bone.scaleY) * alpha;
-			return;
-		}
-
-		// Interpolate between the previous frame and the current frame.
-		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
-		var prevX:Number = frames[frame + PREV_X];
-		var prevY:Number = frames[frame + PREV_Y];
-		var frameTime:Number = frames[frame];
-		var percent:Number = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
-
-		bone.scaleX += (bone.data.scaleX * (prevX + (frames[frame + X] - prevX) * percent) - bone.scaleX) * alpha;
-		bone.scaleY += (bone.data.scaleY * (prevY + (frames[frame + Y] - prevY) * percent) - bone.scaleY) * alpha;
-	}
-}
-
+package spine.animation {
+import spine.Bone;
+import spine.Event;
+import spine.Skeleton;
+
+public class ScaleTimeline extends TranslateTimeline {
+	public function ScaleTimeline (frameCount:int) {
+		super(frameCount);
+	}
+
+	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
+		if (time < frames[0])
+			return; // Time is before first frame.
+
+		var bone:Bone = skeleton.bones[boneIndex];
+		if (time >= frames[int(frames.length - ENTRIES)]) { // Time is after last frame.
+			bone.scaleX += (bone.data.scaleX * frames[int(frames.length + PREV_X)] - bone.scaleX) * alpha;
+			bone.scaleY += (bone.data.scaleY * frames[int(frames.length + PREV_Y)] - bone.scaleY) * alpha;
+			return;
+		}
+
+		// Interpolate between the previous frame and the current frame.
+		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
+		var prevX:Number = frames[frame + PREV_X];
+		var prevY:Number = frames[frame + PREV_Y];
+		var frameTime:Number = frames[frame];
+		var percent:Number = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
+
+		bone.scaleX += (bone.data.scaleX * (prevX + (frames[frame + X] - prevX) * percent) - bone.scaleX) * alpha;
+		bone.scaleY += (bone.data.scaleY * (prevY + (frames[frame + Y] - prevY) * percent) - bone.scaleY) * alpha;
+	}
+}
+
 }

+ 15 - 16
spine-as3/spine-as3/src/spine/animation/ShearTimeline.as

@@ -1,18 +1,17 @@
 /******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
+ * Spine Runtimes Software License v2.5
  * 
- * Copyright (c) 2013-2015, Esoteric Software
+ * Copyright (c) 2013-2016, Esoteric Software
  * All rights reserved.
  * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
  * or other intellectual property or proprietary rights notices on or in the
  * Software, including any copy thereof. Redistributions in binary or source
  * form must include this license and terms.
@@ -22,11 +21,11 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
 package spine.animation {

+ 37 - 38
spine-as3/spine-as3/src/spine/animation/Timeline.as

@@ -1,41 +1,40 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.Event;
-import spine.Skeleton;
-
-public interface Timeline {
-	/** Sets the value(s) for the specified time. */
-	function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void;
-}
-
+package spine.animation {
+import spine.Event;
+import spine.Skeleton;
+
+public interface Timeline {
+	/** Sets the value(s) for the specified time. */
+	function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void;
+}
+
 }

+ 47 - 48
spine-as3/spine-as3/src/spine/animation/TrackEntry.as

@@ -1,51 +1,50 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-
-public class TrackEntry {
-	public var next:TrackEntry;
-	internal var previous:TrackEntry;
-	public var animation:Animation;
-	public var loop:Boolean;
-	public var delay:Number, time:Number = 0, lastTime:Number = -1, endTime:Number, timeScale:Number = 1;
-	internal var mixTime:Number, mixDuration:Number, mix:Number = 1;
-	public var onStart:Function, onEnd:Function, onComplete:Function, onEvent:Function;
-	
-	public function TrackEntry () {		
-	}
-	
-	public function toString () : String {
-		return animation == null ? "<none>" : animation.name;
-	}
-}
-
+package spine.animation {
+
+public class TrackEntry {
+	public var next:TrackEntry;
+	internal var previous:TrackEntry;
+	public var animation:Animation;
+	public var loop:Boolean;
+	public var delay:Number, time:Number = 0, lastTime:Number = -1, endTime:Number, timeScale:Number = 1;
+	internal var mixTime:Number, mixDuration:Number, mix:Number = 1;
+	public var onStart:Function, onEnd:Function, onComplete:Function, onEvent:Function;
+	
+	public function TrackEntry () {		
+	}
+	
+	public function toString () : String {
+		return animation == null ? "<none>" : animation.name;
+	}
+}
+
 }

+ 86 - 87
spine-as3/spine-as3/src/spine/animation/TransformConstraintTimeline.as

@@ -1,90 +1,89 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.Event;
-import spine.Skeleton;
-import spine.TransformConstraint;
-
-public class TransformConstraintTimeline extends CurveTimeline {
-	static public const ENTRIES:int = 5;
-	static internal const PREV_TIME:int = -5, PREV_ROTATE:int = -4, PREV_TRANSLATE:int = -3, PREV_SCALE:int = -2, PREV_SHEAR:int = -1;
-	static internal const ROTATE:int = 1, TRANSLATE:int = 2, SCALE:int = 3, SHEAR:int = 4;
-
-	public var transformConstraintIndex:int;
-	public var frames:Vector.<Number>; // time, rotate mix, translate mix, scale mix, shear mix, ...
-
-	public function TransformConstraintTimeline (frameCount:int) {
-		super(frameCount);
-		frames = new Vector.<Number>(frameCount * ENTRIES, true);
-	}
-	
-	/** Sets the time and mixes of the specified keyframe. */
-	public function setFrame (frameIndex:int, time:Number, rotateMix:Number, translateMix:Number, scaleMix:Number, shearMix:Number) : void {
-		frameIndex *= ENTRIES;
-		frames[frameIndex] = time;
-		frames[frameIndex + ROTATE] = rotateMix;
-		frames[frameIndex + TRANSLATE] = translateMix;
-		frames[frameIndex + SCALE] = scaleMix;
-		frames[frameIndex + SHEAR] = shearMix;
-	}
-
-	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
-		if (time < frames[0]) return; // Time is before first frame.
-
-		var constraint:TransformConstraint = skeleton.transformConstraints[transformConstraintIndex];
-
-		if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
-			var i:int = frames.length;
-			constraint.rotateMix += (frames[i + PREV_ROTATE] - constraint.rotateMix) * alpha;
-			constraint.translateMix += (frames[i + PREV_TRANSLATE] - constraint.translateMix) * alpha;
-			constraint.scaleMix += (frames[i + PREV_SCALE] - constraint.scaleMix) * alpha;
-			constraint.shearMix += (frames[i + PREV_SHEAR] - constraint.shearMix) * alpha;
-			return;
-		}
-
-		// Interpolate between the previous frame and the current frame.
-		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
-		var frameTime:Number = frames[frame];
-		var percent:Number = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
-
-		var rotate:Number = frames[frame + PREV_ROTATE];
-		var translate:Number = frames[frame + PREV_TRANSLATE];
-		var scale:Number = frames[frame + PREV_SCALE];
-		var shear:Number = frames[frame + PREV_SHEAR];
-		constraint.rotateMix += (rotate + (frames[frame + ROTATE] - rotate) * percent - constraint.rotateMix) * alpha;
-		constraint.translateMix += (translate + (frames[frame + TRANSLATE] - translate) * percent - constraint.translateMix)
-			* alpha;
-		constraint.scaleMix += (scale + (frames[frame + SCALE] - scale) * percent - constraint.scaleMix) * alpha;
-		constraint.shearMix += (shear + (frames[frame + SHEAR] - shear) * percent - constraint.shearMix) * alpha;
-	}
+package spine.animation {
+import spine.Event;
+import spine.Skeleton;
+import spine.TransformConstraint;
+
+public class TransformConstraintTimeline extends CurveTimeline {
+	static public const ENTRIES:int = 5;
+	static internal const PREV_TIME:int = -5, PREV_ROTATE:int = -4, PREV_TRANSLATE:int = -3, PREV_SCALE:int = -2, PREV_SHEAR:int = -1;
+	static internal const ROTATE:int = 1, TRANSLATE:int = 2, SCALE:int = 3, SHEAR:int = 4;
+
+	public var transformConstraintIndex:int;
+	public var frames:Vector.<Number>; // time, rotate mix, translate mix, scale mix, shear mix, ...
+
+	public function TransformConstraintTimeline (frameCount:int) {
+		super(frameCount);
+		frames = new Vector.<Number>(frameCount * ENTRIES, true);
+	}
+	
+	/** Sets the time and mixes of the specified keyframe. */
+	public function setFrame (frameIndex:int, time:Number, rotateMix:Number, translateMix:Number, scaleMix:Number, shearMix:Number) : void {
+		frameIndex *= ENTRIES;
+		frames[frameIndex] = time;
+		frames[frameIndex + ROTATE] = rotateMix;
+		frames[frameIndex + TRANSLATE] = translateMix;
+		frames[frameIndex + SCALE] = scaleMix;
+		frames[frameIndex + SHEAR] = shearMix;
+	}
+
+	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
+		if (time < frames[0]) return; // Time is before first frame.
+
+		var constraint:TransformConstraint = skeleton.transformConstraints[transformConstraintIndex];
+
+		if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
+			var i:int = frames.length;
+			constraint.rotateMix += (frames[i + PREV_ROTATE] - constraint.rotateMix) * alpha;
+			constraint.translateMix += (frames[i + PREV_TRANSLATE] - constraint.translateMix) * alpha;
+			constraint.scaleMix += (frames[i + PREV_SCALE] - constraint.scaleMix) * alpha;
+			constraint.shearMix += (frames[i + PREV_SHEAR] - constraint.shearMix) * alpha;
+			return;
+		}
+
+		// Interpolate between the previous frame and the current frame.
+		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
+		var frameTime:Number = frames[frame];
+		var percent:Number = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
+
+		var rotate:Number = frames[frame + PREV_ROTATE];
+		var translate:Number = frames[frame + PREV_TRANSLATE];
+		var scale:Number = frames[frame + PREV_SCALE];
+		var shear:Number = frames[frame + PREV_SHEAR];
+		constraint.rotateMix += (rotate + (frames[frame + ROTATE] - rotate) * percent - constraint.rotateMix) * alpha;
+		constraint.translateMix += (translate + (frames[frame + TRANSLATE] - translate) * percent - constraint.translateMix)
+			* alpha;
+		constraint.scaleMix += (scale + (frames[frame + SCALE] - scale) * percent - constraint.scaleMix) * alpha;
+		constraint.shearMix += (shear + (frames[frame + SHEAR] - shear) * percent - constraint.shearMix) * alpha;
+	}
+}
 }
-}

+ 78 - 79
spine-as3/spine-as3/src/spine/animation/TranslateTimeline.as

@@ -1,82 +1,81 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.animation {
-import spine.Bone;
-import spine.Event;
-import spine.Skeleton;
-
-public class TranslateTimeline extends CurveTimeline {
-	static public const ENTRIES:int = 3;
-	static internal const PREV_TIME:int = -3, PREV_X:int = -2, PREV_Y:int = -1;
-	static internal const X:int = 1, Y:int = 2;
-
-	public var boneIndex:int;
-	public var frames:Vector.<Number>; // time, value, value, ...
-
-	public function TranslateTimeline (frameCount:int) {
-		super(frameCount);
-		frames = new Vector.<Number>(frameCount * ENTRIES, true);
-	}
-
-	/** Sets the time and value of the specified keyframe. */
-	public function setFrame (frameIndex:int, time:Number, x:Number, y:Number) : void {
-		frameIndex *= ENTRIES;
-		frames[frameIndex] = time;
-		frames[int(frameIndex + X)] = x;
-		frames[int(frameIndex + Y)] = y;
-	}
-
-	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
-		if (time < frames[0])
-			return; // Time is before first frame.
-
-		var bone:Bone = skeleton.bones[boneIndex];
-
-		if (time >= frames[int(frames.length - ENTRIES)]) { // Time is after last frame.
-			bone.x += (bone.data.x + frames[int(frames.length + PREV_X)] - bone.x) * alpha;
-			bone.y += (bone.data.y + frames[int(frames.length + PREV_Y)] - bone.y) * alpha;
-			return;
-		}
-
-		// Interpolate between the previous frame and the current frame.
-		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
-		var prevX:Number = frames[frame + PREV_X];
-		var prevY:Number = frames[frame + PREV_Y];
-		var frameTime:Number = frames[frame];
-		var percent:Number = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
-
-		bone.x += (bone.data.x + prevX + (frames[frame + X] - prevX) * percent - bone.x) * alpha;
-		bone.y += (bone.data.y + prevY + (frames[frame + Y] - prevY) * percent - bone.y) * alpha;
-	}
-}
-
+package spine.animation {
+import spine.Bone;
+import spine.Event;
+import spine.Skeleton;
+
+public class TranslateTimeline extends CurveTimeline {
+	static public const ENTRIES:int = 3;
+	static internal const PREV_TIME:int = -3, PREV_X:int = -2, PREV_Y:int = -1;
+	static internal const X:int = 1, Y:int = 2;
+
+	public var boneIndex:int;
+	public var frames:Vector.<Number>; // time, value, value, ...
+
+	public function TranslateTimeline (frameCount:int) {
+		super(frameCount);
+		frames = new Vector.<Number>(frameCount * ENTRIES, true);
+	}
+
+	/** Sets the time and value of the specified keyframe. */
+	public function setFrame (frameIndex:int, time:Number, x:Number, y:Number) : void {
+		frameIndex *= ENTRIES;
+		frames[frameIndex] = time;
+		frames[int(frameIndex + X)] = x;
+		frames[int(frameIndex + Y)] = y;
+	}
+
+	override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
+		if (time < frames[0])
+			return; // Time is before first frame.
+
+		var bone:Bone = skeleton.bones[boneIndex];
+
+		if (time >= frames[int(frames.length - ENTRIES)]) { // Time is after last frame.
+			bone.x += (bone.data.x + frames[int(frames.length + PREV_X)] - bone.x) * alpha;
+			bone.y += (bone.data.y + frames[int(frames.length + PREV_Y)] - bone.y) * alpha;
+			return;
+		}
+
+		// Interpolate between the previous frame and the current frame.
+		var frame:int = Animation.binarySearch(frames, time, ENTRIES);
+		var prevX:Number = frames[frame + PREV_X];
+		var prevY:Number = frames[frame + PREV_Y];
+		var frameTime:Number = frames[frame];
+		var percent:Number = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
+
+		bone.x += (bone.data.x + prevX + (frames[frame + X] - prevX) * percent - bone.x) * alpha;
+		bone.y += (bone.data.y + prevY + (frames[frame + Y] - prevY) * percent - bone.y) * alpha;
+	}
+}
+
 }

+ 207 - 208
spine-as3/spine-as3/src/spine/atlas/Atlas.as

@@ -1,211 +1,210 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.atlas {
-import flash.utils.ByteArray;
-
-public class Atlas {
-	private var pages:Vector.<AtlasPage> = new Vector.<AtlasPage>();
-	private var regions:Vector.<AtlasRegion> = new Vector.<AtlasRegion>();
-	private var textureLoader:TextureLoader;
-
-	/** @param object A String or ByteArray. */
-	public function Atlas (object:*, textureLoader:TextureLoader) {
-		if (!object)
-			return;
-		if (object is String)
-			load(String(object), textureLoader);
-		else if (object is ByteArray)
-			load(ByteArray(object).readUTFBytes(ByteArray(object).length), textureLoader);
-		else
-			throw new ArgumentError("object must be a TextureAtlas or AttachmentLoader.");
-	}
-
-	protected function load (atlasText:String, textureLoader:TextureLoader) : void {
-		if (textureLoader == null)
-			throw new ArgumentError("textureLoader cannot be null.");
-		this.textureLoader = textureLoader;
-
-		var reader:Reader = new Reader(atlasText);
-		var tuple:Array = new Array();
-		tuple.length = 4;
-		var page:AtlasPage = null;
-		while (true) {
-			var line:String = reader.readLine();
-			if (line == null)
-				break;
-			line = reader.trim(line);
-			if (line.length == 0)
-				page = null;
-			else if (!page) {
-				page = new AtlasPage();
-				page.name = line;
-
-				if (reader.readTuple(tuple) == 2) { // size is only optional for an atlas packed with an old TexturePacker.
-					page.width = parseInt(tuple[0]);
-					page.height = parseInt(tuple[1]);
-					reader.readTuple(tuple);
-				}
-				page.format = Format[tuple[0]];
-
-				reader.readTuple(tuple);
-				page.minFilter = TextureFilter[tuple[0]];
-				page.magFilter = TextureFilter[tuple[1]];
-
-				var direction:String = reader.readValue();
-				page.uWrap = TextureWrap.clampToEdge;
-				page.vWrap = TextureWrap.clampToEdge;
-				if (direction == "x")
-					page.uWrap = TextureWrap.repeat;
-				else if (direction == "y")
-					page.vWrap = TextureWrap.repeat;
-				else if (direction == "xy")
-					page.uWrap = page.vWrap = TextureWrap.repeat;
-
-				textureLoader.loadPage(page, line);
-
-				pages[pages.length] = page;
-
-			} else {
-				var region:AtlasRegion = new AtlasRegion();
-				region.name = line;
-				region.page = page;
-
-				region.rotate = reader.readValue() == "true";
-
-				reader.readTuple(tuple);
-				var x:int = parseInt(tuple[0]);
-				var y:int = parseInt(tuple[1]);
-
-				reader.readTuple(tuple);
-				var width:int = parseInt(tuple[0]);
-				var height:int = parseInt(tuple[1]);
-
-				region.u = x / page.width;
-				region.v = y / page.height;
-				if (region.rotate) {
-					region.u2 = (x + height) / page.width;
-					region.v2 = (y + width) / page.height;
-				} else {
-					region.u2 = (x + width) / page.width;
-					region.v2 = (y + height) / page.height;
-				}
-				region.x = x;
-				region.y = y;
-				region.width = Math.abs(width);
-				region.height = Math.abs(height);
-
-				if (reader.readTuple(tuple) == 4) { // split is optional
-					region.splits = new Vector.<int>(parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3]));
-
-					if (reader.readTuple(tuple) == 4) { // pad is optional, but only present with splits
-						region.pads = Vector.<int>(parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3]));
-
-						reader.readTuple(tuple);
-					}
-				}
-
-				region.originalWidth = parseInt(tuple[0]);
-				region.originalHeight = parseInt(tuple[1]);
-
-				reader.readTuple(tuple);
-				region.offsetX = parseInt(tuple[0]);
-				region.offsetY = parseInt(tuple[1]);
-
-				region.index = parseInt(reader.readValue());
-
-				textureLoader.loadRegion(region);
-				regions[regions.length] = region;
-			}
-		}
-	}
-
-	/** Returns the first region found with the specified name. This method uses string comparison to find the region, so the result
-	 * should be cached rather than calling this method multiple times.
-	 * @return The region, or null. */
-	public function findRegion (name:String) : AtlasRegion {
-		for (var i:int = 0, n:int = regions.length; i < n; i++)
-			if (regions[i].name == name)
-				return regions[i];
-		return null;
-	}
-
-	public function dispose () : void {
-		for (var i:int = 0, n:int = pages.length; i < n; i++)
-			textureLoader.unloadPage(pages[i]);
-	}
-}
-
-}
-
-class Reader {
-	private var lines:Array;
-	private var index:int;
-
-	public function Reader (text:String) {
-		lines = text.split(/\r\n|\r|\n/);
-	}
-
-	public function trim (value:String) : String {
-		return value.replace(/^\s+|\s+$/gs, "");
-	}
-
-	public function readLine () : String {
-		if (index >= lines.length)
-			return null;
-		return lines[index++];
-	}
-
-	public function readValue () : String {
-		var line:String = readLine();
-		var colon:int = line.indexOf(":");
-		if (colon == -1)
-			throw new Error("Invalid line: " + line);
-		return trim(line.substring(colon + 1));
-	}
-
-	/** Returns the number of tuple values read (1, 2 or 4). */
-	public function readTuple (tuple:Array) : int {
-		var line:String = readLine();
-		var colon:int = line.indexOf(":");
-		if (colon == -1)
-			throw new Error("Invalid line: " + line);
-		var i:int = 0, lastMatch:int = colon + 1;
-		for (; i < 3; i++) {
-			var comma:int = line.indexOf(",", lastMatch);
-			if (comma == -1) break;
-			tuple[i] = trim(line.substr(lastMatch, comma - lastMatch));
-			lastMatch = comma + 1;
-		}
-		tuple[i] = trim(line.substring(lastMatch));
-		return i + 1;
-	}
+package spine.atlas {
+import flash.utils.ByteArray;
+
+public class Atlas {
+	private var pages:Vector.<AtlasPage> = new Vector.<AtlasPage>();
+	private var regions:Vector.<AtlasRegion> = new Vector.<AtlasRegion>();
+	private var textureLoader:TextureLoader;
+
+	/** @param object A String or ByteArray. */
+	public function Atlas (object:*, textureLoader:TextureLoader) {
+		if (!object)
+			return;
+		if (object is String)
+			load(String(object), textureLoader);
+		else if (object is ByteArray)
+			load(ByteArray(object).readUTFBytes(ByteArray(object).length), textureLoader);
+		else
+			throw new ArgumentError("object must be a TextureAtlas or AttachmentLoader.");
+	}
+
+	protected function load (atlasText:String, textureLoader:TextureLoader) : void {
+		if (textureLoader == null)
+			throw new ArgumentError("textureLoader cannot be null.");
+		this.textureLoader = textureLoader;
+
+		var reader:Reader = new Reader(atlasText);
+		var tuple:Array = new Array();
+		tuple.length = 4;
+		var page:AtlasPage = null;
+		while (true) {
+			var line:String = reader.readLine();
+			if (line == null)
+				break;
+			line = reader.trim(line);
+			if (line.length == 0)
+				page = null;
+			else if (!page) {
+				page = new AtlasPage();
+				page.name = line;
+
+				if (reader.readTuple(tuple) == 2) { // size is only optional for an atlas packed with an old TexturePacker.
+					page.width = parseInt(tuple[0]);
+					page.height = parseInt(tuple[1]);
+					reader.readTuple(tuple);
+				}
+				page.format = Format[tuple[0]];
+
+				reader.readTuple(tuple);
+				page.minFilter = TextureFilter[tuple[0]];
+				page.magFilter = TextureFilter[tuple[1]];
+
+				var direction:String = reader.readValue();
+				page.uWrap = TextureWrap.clampToEdge;
+				page.vWrap = TextureWrap.clampToEdge;
+				if (direction == "x")
+					page.uWrap = TextureWrap.repeat;
+				else if (direction == "y")
+					page.vWrap = TextureWrap.repeat;
+				else if (direction == "xy")
+					page.uWrap = page.vWrap = TextureWrap.repeat;
+
+				textureLoader.loadPage(page, line);
+
+				pages[pages.length] = page;
+
+			} else {
+				var region:AtlasRegion = new AtlasRegion();
+				region.name = line;
+				region.page = page;
+
+				region.rotate = reader.readValue() == "true";
+
+				reader.readTuple(tuple);
+				var x:int = parseInt(tuple[0]);
+				var y:int = parseInt(tuple[1]);
+
+				reader.readTuple(tuple);
+				var width:int = parseInt(tuple[0]);
+				var height:int = parseInt(tuple[1]);
+
+				region.u = x / page.width;
+				region.v = y / page.height;
+				if (region.rotate) {
+					region.u2 = (x + height) / page.width;
+					region.v2 = (y + width) / page.height;
+				} else {
+					region.u2 = (x + width) / page.width;
+					region.v2 = (y + height) / page.height;
+				}
+				region.x = x;
+				region.y = y;
+				region.width = Math.abs(width);
+				region.height = Math.abs(height);
+
+				if (reader.readTuple(tuple) == 4) { // split is optional
+					region.splits = new Vector.<int>(parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3]));
+
+					if (reader.readTuple(tuple) == 4) { // pad is optional, but only present with splits
+						region.pads = Vector.<int>(parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3]));
+
+						reader.readTuple(tuple);
+					}
+				}
+
+				region.originalWidth = parseInt(tuple[0]);
+				region.originalHeight = parseInt(tuple[1]);
+
+				reader.readTuple(tuple);
+				region.offsetX = parseInt(tuple[0]);
+				region.offsetY = parseInt(tuple[1]);
+
+				region.index = parseInt(reader.readValue());
+
+				textureLoader.loadRegion(region);
+				regions[regions.length] = region;
+			}
+		}
+	}
+
+	/** Returns the first region found with the specified name. This method uses string comparison to find the region, so the result
+	 * should be cached rather than calling this method multiple times.
+	 * @return The region, or null. */
+	public function findRegion (name:String) : AtlasRegion {
+		for (var i:int = 0, n:int = regions.length; i < n; i++)
+			if (regions[i].name == name)
+				return regions[i];
+		return null;
+	}
+
+	public function dispose () : void {
+		for (var i:int = 0, n:int = pages.length; i < n; i++)
+			textureLoader.unloadPage(pages[i]);
+	}
+}
+
+}
+
+class Reader {
+	private var lines:Array;
+	private var index:int;
+
+	public function Reader (text:String) {
+		lines = text.split(/\r\n|\r|\n/);
+	}
+
+	public function trim (value:String) : String {
+		return value.replace(/^\s+|\s+$/gs, "");
+	}
+
+	public function readLine () : String {
+		if (index >= lines.length)
+			return null;
+		return lines[index++];
+	}
+
+	public function readValue () : String {
+		var line:String = readLine();
+		var colon:int = line.indexOf(":");
+		if (colon == -1)
+			throw new Error("Invalid line: " + line);
+		return trim(line.substring(colon + 1));
+	}
+
+	/** Returns the number of tuple values read (1, 2 or 4). */
+	public function readTuple (tuple:Array) : int {
+		var line:String = readLine();
+		var colon:int = line.indexOf(":");
+		if (colon == -1)
+			throw new Error("Invalid line: " + line);
+		var i:int = 0, lastMatch:int = colon + 1;
+		for (; i < 3; i++) {
+			var comma:int = line.indexOf(",", lastMatch);
+			if (comma == -1) break;
+			tuple[i] = trim(line.substr(lastMatch, comma - lastMatch));
+			lastMatch = comma + 1;
+		}
+		tuple[i] = trim(line.substring(lastMatch));
+		return i + 1;
+	}
 }

+ 45 - 46
spine-as3/spine-as3/src/spine/atlas/AtlasPage.as

@@ -1,49 +1,48 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.atlas {
-
-public class AtlasPage {
-	public var name:String;
-	public var format:Format;
-	public var minFilter:TextureFilter;
-	public var magFilter:TextureFilter;
-	public var uWrap:TextureWrap;
-	public var vWrap:TextureWrap;
-	public var rendererObject:Object;
-	public var width:int;
-	public var height:int;
-	
-	public function AtlasPage () {		
-	}
-}
-
+package spine.atlas {
+
+public class AtlasPage {
+	public var name:String;
+	public var format:Format;
+	public var minFilter:TextureFilter;
+	public var magFilter:TextureFilter;
+	public var uWrap:TextureWrap;
+	public var vWrap:TextureWrap;
+	public var rendererObject:Object;
+	public var width:int;
+	public var height:int;
+	
+	public function AtlasPage () {		
+	}
+}
+
 }

+ 55 - 56
spine-as3/spine-as3/src/spine/atlas/AtlasRegion.as

@@ -1,59 +1,58 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.atlas {
-
-public class AtlasRegion {
-	public var page:AtlasPage;
-	public var name:String;
-	public var x:int;
-	public var y:int;
-	public var width:int;
-	public var height:int;
-	public var u:Number;
-	public var v:Number;
-	public var u2:Number;
-	public var v2:Number;
-	public var offsetX:Number;
-	public var offsetY:Number;
-	public var originalWidth:int;
-	public var originalHeight:int;
-	public var index:int;
-	public var rotate:Boolean;
-	public var splits:Vector.<int>;
-	public var pads:Vector.<int>;
-	public var rendererObject:Object;
-	
-	public function AtlasRegion () {		
-	}
-}
-
+package spine.atlas {
+
+public class AtlasRegion {
+	public var page:AtlasPage;
+	public var name:String;
+	public var x:int;
+	public var y:int;
+	public var width:int;
+	public var height:int;
+	public var u:Number;
+	public var v:Number;
+	public var u2:Number;
+	public var v2:Number;
+	public var offsetX:Number;
+	public var offsetY:Number;
+	public var originalWidth:int;
+	public var originalHeight:int;
+	public var index:int;
+	public var rotate:Boolean;
+	public var splits:Vector.<int>;
+	public var pads:Vector.<int>;
+	public var rendererObject:Object;
+	
+	public function AtlasRegion () {		
+	}
+}
+
 }

+ 48 - 49
spine-as3/spine-as3/src/spine/atlas/Format.as

@@ -1,52 +1,51 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.atlas {
-
-public class Format {
-	public static const alpha:Format = new Format(0, "alpha");
-	public static const intensity:Format = new Format(1, "intensity");
-	public static const luminanceAlpha:Format = new Format(2, "luminanceAlpha");
-	public static const rgb565:Format = new Format(3, "rgb565");
-	public static const rgba4444:Format = new Format(4, "rgba4444");
-	public static const rgb888:Format = new Format(5, "rgb888");
-	public static const rgba8888:Format = new Format(6, "rgba8888");
-
-	public var ordinal:int;
-	public var name:String;
-
-	public function Format (ordinal:int, name:String) {
-		this.ordinal = ordinal;
-		this.name = name;
-	}
-}
-
+package spine.atlas {
+
+public class Format {
+	public static const alpha:Format = new Format(0, "alpha");
+	public static const intensity:Format = new Format(1, "intensity");
+	public static const luminanceAlpha:Format = new Format(2, "luminanceAlpha");
+	public static const rgb565:Format = new Format(3, "rgb565");
+	public static const rgba4444:Format = new Format(4, "rgba4444");
+	public static const rgb888:Format = new Format(5, "rgb888");
+	public static const rgba8888:Format = new Format(6, "rgba8888");
+
+	public var ordinal:int;
+	public var name:String;
+
+	public function Format (ordinal:int, name:String) {
+		this.ordinal = ordinal;
+		this.name = name;
+	}
+}
+
 }

+ 48 - 49
spine-as3/spine-as3/src/spine/atlas/TextureFilter.as

@@ -1,52 +1,51 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.atlas {
-
-public class TextureFilter {
-	public static const nearest:TextureFilter = new TextureFilter(0, "nearest");
-	public static const linear:TextureFilter = new TextureFilter(1, "linear");
-	public static const mipMap:TextureFilter = new TextureFilter(2, "mipMap");
-	public static const mipMapNearestNearest:TextureFilter = new TextureFilter(3, "mipMapNearestNearest");
-	public static const mipMapLinearNearest:TextureFilter = new TextureFilter(4, "mipMapLinearNearest");
-	public static const mipMapNearestLinear:TextureFilter = new TextureFilter(5, "mipMapNearestLinear");
-	public static const mipMapLinearLinear:TextureFilter = new TextureFilter(6, "mipMapLinearLinear");
-
-	public var ordinal:int;
-	public var name:String;
-
-	public function TextureFilter (ordinal:int, name:String) {
-		this.ordinal = ordinal;
-		this.name = name;
-	}
-}
-
+package spine.atlas {
+
+public class TextureFilter {
+	public static const nearest:TextureFilter = new TextureFilter(0, "nearest");
+	public static const linear:TextureFilter = new TextureFilter(1, "linear");
+	public static const mipMap:TextureFilter = new TextureFilter(2, "mipMap");
+	public static const mipMapNearestNearest:TextureFilter = new TextureFilter(3, "mipMapNearestNearest");
+	public static const mipMapLinearNearest:TextureFilter = new TextureFilter(4, "mipMapLinearNearest");
+	public static const mipMapNearestLinear:TextureFilter = new TextureFilter(5, "mipMapNearestLinear");
+	public static const mipMapLinearLinear:TextureFilter = new TextureFilter(6, "mipMapLinearLinear");
+
+	public var ordinal:int;
+	public var name:String;
+
+	public function TextureFilter (ordinal:int, name:String) {
+		this.ordinal = ordinal;
+		this.name = name;
+	}
+}
+
 }

+ 36 - 37
spine-as3/spine-as3/src/spine/atlas/TextureLoader.as

@@ -1,40 +1,39 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.atlas {
-
-public interface TextureLoader {
-	function loadPage (page:AtlasPage, path:String) : void;
-	function loadRegion (region:AtlasRegion) : void;
-	function unloadPage (page:AtlasPage) : void;
-}
-
+package spine.atlas {
+
+public interface TextureLoader {
+	function loadPage (page:AtlasPage, path:String) : void;
+	function loadRegion (region:AtlasRegion) : void;
+	function unloadPage (page:AtlasPage) : void;
+}
+
 }

+ 44 - 45
spine-as3/spine-as3/src/spine/atlas/TextureWrap.as

@@ -1,48 +1,47 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.atlas {
-
-public class TextureWrap {
-	public static const mirroredRepeat:TextureWrap = new TextureWrap(0, "mirroredRepeat");
-	public static const clampToEdge:TextureWrap = new TextureWrap(1, "clampToEdge");
-	public static const repeat:TextureWrap = new TextureWrap(2, "repeat");
-
-	public var ordinal:int;
-	public var name:String;
-
-	public function TextureWrap (ordinal:int, name:String) {
-		this.ordinal = ordinal;
-		this.name = name;
-	}
-}
-
+package spine.atlas {
+
+public class TextureWrap {
+	public static const mirroredRepeat:TextureWrap = new TextureWrap(0, "mirroredRepeat");
+	public static const clampToEdge:TextureWrap = new TextureWrap(1, "clampToEdge");
+	public static const repeat:TextureWrap = new TextureWrap(2, "repeat");
+
+	public var ordinal:int;
+	public var name:String;
+
+	public function TextureWrap (ordinal:int, name:String) {
+		this.ordinal = ordinal;
+		this.name = name;
+	}
+}
+
 }

+ 101 - 102
spine-as3/spine-as3/src/spine/attachments/AtlasAttachmentLoader.as

@@ -1,105 +1,104 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.attachments {
-import spine.Skin;
-import spine.atlas.Atlas;
-import spine.atlas.AtlasRegion;
-
-public class AtlasAttachmentLoader implements AttachmentLoader {
-	private var atlas:Atlas;
-
-	public function AtlasAttachmentLoader (atlas:Atlas) {
-		if (atlas == null)
-			throw new ArgumentError("atlas cannot be null.");
-		this.atlas = atlas;
-	}
-	
-	public function newRegionAttachment (skin:Skin, name:String, path:String) : RegionAttachment {
-		var region:AtlasRegion = atlas.findRegion(path);
-		if (region == null)
-			throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")");
-		var attachment:RegionAttachment = new RegionAttachment(name);
-		attachment.rendererObject = region;
-		var scaleX:Number = region.page.width / nextPOT(region.page.width);
-		var scaleY:Number = region.page.height / nextPOT(region.page.height);
-		attachment.setUVs(region.u * scaleX, region.v * scaleY, region.u2 * scaleX, region.v2 * scaleY, region.rotate);
-		attachment.regionOffsetX = region.offsetX;
-		attachment.regionOffsetY = region.offsetY;
-		attachment.regionWidth = region.width;
-		attachment.regionHeight = region.height;
-		attachment.regionOriginalWidth = region.originalWidth;
-		attachment.regionOriginalHeight = region.originalHeight;
-		return attachment;
-	}
-	
-	public function newMeshAttachment (skin:Skin, name:String, path:String) : MeshAttachment {
-		var region:AtlasRegion = atlas.findRegion(path);
-		if (region == null)
-			throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")");
-		var attachment:MeshAttachment = new MeshAttachment(name);
-		attachment.rendererObject = region;
-		var scaleX:Number = region.page.width / nextPOT(region.page.width);
-		var scaleY:Number = region.page.height / nextPOT(region.page.height);
-		attachment.regionU = region.u * scaleX;
-		attachment.regionV = region.v * scaleY;
-		attachment.regionU2 = region.u2 * scaleX;
-		attachment.regionV2 = region.v2 * scaleY;
-		attachment.regionRotate = region.rotate;
-		attachment.regionOffsetX = region.offsetX;
-		attachment.regionOffsetY = region.offsetY;
-		attachment.regionWidth = region.width;
-		attachment.regionHeight = region.height;
-		attachment.regionOriginalWidth = region.originalWidth;
-		attachment.regionOriginalHeight = region.originalHeight;
-		return attachment;
-	}
-
-	public function newBoundingBoxAttachment (skin:Skin, name:String) : BoundingBoxAttachment {
-		return new BoundingBoxAttachment(name);
-	}
-	
-	public function newPathAttachment(skin:Skin, name:String) : PathAttachment {
-		return new PathAttachment(name);
-	}
-
-	static public function nextPOT (value:int) : int {
-		value--;
-		value |= value >> 1;
-		value |= value >> 2;
-		value |= value >> 4;
-		value |= value >> 8;
-		value |= value >> 16;
-		return value + 1;
-	}
-}
-
+package spine.attachments {
+import spine.Skin;
+import spine.atlas.Atlas;
+import spine.atlas.AtlasRegion;
+
+public class AtlasAttachmentLoader implements AttachmentLoader {
+	private var atlas:Atlas;
+
+	public function AtlasAttachmentLoader (atlas:Atlas) {
+		if (atlas == null)
+			throw new ArgumentError("atlas cannot be null.");
+		this.atlas = atlas;
+	}
+	
+	public function newRegionAttachment (skin:Skin, name:String, path:String) : RegionAttachment {
+		var region:AtlasRegion = atlas.findRegion(path);
+		if (region == null)
+			throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")");
+		var attachment:RegionAttachment = new RegionAttachment(name);
+		attachment.rendererObject = region;
+		var scaleX:Number = region.page.width / nextPOT(region.page.width);
+		var scaleY:Number = region.page.height / nextPOT(region.page.height);
+		attachment.setUVs(region.u * scaleX, region.v * scaleY, region.u2 * scaleX, region.v2 * scaleY, region.rotate);
+		attachment.regionOffsetX = region.offsetX;
+		attachment.regionOffsetY = region.offsetY;
+		attachment.regionWidth = region.width;
+		attachment.regionHeight = region.height;
+		attachment.regionOriginalWidth = region.originalWidth;
+		attachment.regionOriginalHeight = region.originalHeight;
+		return attachment;
+	}
+	
+	public function newMeshAttachment (skin:Skin, name:String, path:String) : MeshAttachment {
+		var region:AtlasRegion = atlas.findRegion(path);
+		if (region == null)
+			throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")");
+		var attachment:MeshAttachment = new MeshAttachment(name);
+		attachment.rendererObject = region;
+		var scaleX:Number = region.page.width / nextPOT(region.page.width);
+		var scaleY:Number = region.page.height / nextPOT(region.page.height);
+		attachment.regionU = region.u * scaleX;
+		attachment.regionV = region.v * scaleY;
+		attachment.regionU2 = region.u2 * scaleX;
+		attachment.regionV2 = region.v2 * scaleY;
+		attachment.regionRotate = region.rotate;
+		attachment.regionOffsetX = region.offsetX;
+		attachment.regionOffsetY = region.offsetY;
+		attachment.regionWidth = region.width;
+		attachment.regionHeight = region.height;
+		attachment.regionOriginalWidth = region.originalWidth;
+		attachment.regionOriginalHeight = region.originalHeight;
+		return attachment;
+	}
+
+	public function newBoundingBoxAttachment (skin:Skin, name:String) : BoundingBoxAttachment {
+		return new BoundingBoxAttachment(name);
+	}
+	
+	public function newPathAttachment(skin:Skin, name:String) : PathAttachment {
+		return new PathAttachment(name);
+	}
+
+	static public function nextPOT (value:int) : int {
+		value--;
+		value |= value >> 1;
+		value |= value >> 2;
+		value |= value >> 4;
+		value |= value >> 8;
+		value |= value >> 16;
+		return value + 1;
+	}
+}
+
 }

+ 48 - 49
spine-as3/spine-as3/src/spine/attachments/Attachment.as

@@ -1,52 +1,51 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.attachments {
-
-public class Attachment {
-	internal var _name:String;
-
-	public function Attachment (name:String) {
-		if (name == null)
-			throw new ArgumentError("name cannot be null.");
-		_name = name;
-	}
-
-	public function get name () : String {
-		return _name;
-	}
-
-	public function toString () : String {
-		return name;
-	}
-}
-
+package spine.attachments {
+
+public class Attachment {
+	internal var _name:String;
+
+	public function Attachment (name:String) {
+		if (name == null)
+			throw new ArgumentError("name cannot be null.");
+		_name = name;
+	}
+
+	public function get name () : String {
+		return _name;
+	}
+
+	public function toString () : String {
+		return name;
+	}
+}
+
 }

+ 45 - 46
spine-as3/spine-as3/src/spine/attachments/AttachmentLoader.as

@@ -1,49 +1,48 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.attachments {
-import spine.Skin;
-
-public interface AttachmentLoader {
-	/** @return May be null to not load an attachment. */
-	function newRegionAttachment (skin:Skin, name:String, path:String) : RegionAttachment;
-
-	/** @return May be null to not load an attachment. */
-	function newMeshAttachment (skin:Skin, name:String, path:String) : MeshAttachment;
-
-	/** @return May be null to not load an attachment. */
-	function newBoundingBoxAttachment (skin:Skin, name:String) : BoundingBoxAttachment;
-	
-	/** @return May be null to not load an attachment */
-	function newPathAttachment(skin:Skin, name:String): PathAttachment;
-}
-
+package spine.attachments {
+import spine.Skin;
+
+public interface AttachmentLoader {
+	/** @return May be null to not load an attachment. */
+	function newRegionAttachment (skin:Skin, name:String, path:String) : RegionAttachment;
+
+	/** @return May be null to not load an attachment. */
+	function newMeshAttachment (skin:Skin, name:String, path:String) : MeshAttachment;
+
+	/** @return May be null to not load an attachment. */
+	function newBoundingBoxAttachment (skin:Skin, name:String) : BoundingBoxAttachment;
+	
+	/** @return May be null to not load an attachment */
+	function newPathAttachment(skin:Skin, name:String): PathAttachment;
+}
+
 }

+ 47 - 48
spine-as3/spine-as3/src/spine/attachments/AttachmentType.as

@@ -1,51 +1,50 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.attachments {
-
-public class AttachmentType {
-	public static const region:AttachmentType = new AttachmentType(0, "region");
-	public static const regionsequence:AttachmentType = new AttachmentType(1, "regionsequence");
-	public static const boundingbox:AttachmentType = new AttachmentType(2, "boundingbox");
-	public static const mesh:AttachmentType = new AttachmentType(3, "mesh");	
-	public static const linkedmesh:AttachmentType = new AttachmentType(3, "linkedmesh");
-	public static const path:AttachmentType = new AttachmentType(4, "path");
-
-	public var ordinal:int;
-	public var name:String;
-
-	public function AttachmentType (ordinal:int, name:String) {
-		this.ordinal = ordinal;
-		this.name = name;
-	}
-}
-
+package spine.attachments {
+
+public class AttachmentType {
+	public static const region:AttachmentType = new AttachmentType(0, "region");
+	public static const regionsequence:AttachmentType = new AttachmentType(1, "regionsequence");
+	public static const boundingbox:AttachmentType = new AttachmentType(2, "boundingbox");
+	public static const mesh:AttachmentType = new AttachmentType(3, "mesh");	
+	public static const linkedmesh:AttachmentType = new AttachmentType(3, "linkedmesh");
+	public static const path:AttachmentType = new AttachmentType(4, "path");
+
+	public var ordinal:int;
+	public var name:String;
+
+	public function AttachmentType (ordinal:int, name:String) {
+		this.ordinal = ordinal;
+		this.name = name;
+	}
+}
+
 }

+ 35 - 36
spine-as3/spine-as3/src/spine/attachments/BoundingBoxAttachment.as

@@ -1,39 +1,38 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.attachments {
-
-public dynamic class BoundingBoxAttachment extends VertexAttachment {	
-	public function BoundingBoxAttachment (name:String) {
-		super(name);
-	}		
-}
+package spine.attachments {
+
+public dynamic class BoundingBoxAttachment extends VertexAttachment {	
+	public function BoundingBoxAttachment (name:String) {
+		super(name);
+	}		
+}
 }

+ 107 - 108
spine-as3/spine-as3/src/spine/attachments/MeshAttachment.as

@@ -1,111 +1,110 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.attachments {
-
-public dynamic class MeshAttachment extends VertexAttachment {
-	public var worldVertices:Vector.<Number>;
-	public var uvs:Vector.<Number>;
-	public var regionUVs:Vector.<Number>;
-	public var triangles:Vector.<uint>;	
-	public var r:Number = 1;
-	public var g:Number = 1;
-	public var b:Number = 1;
-	public var a:Number = 1;
-	public var hullLength:int;
-	private var _parentMesh:MeshAttachment;
-	public var inheritDeform:Boolean;
-
-	public var path:String;
-	public var rendererObject:Object;
-	public var regionU:Number;
-	public var regionV:Number;
-	public var regionU2:Number;
-	public var regionV2:Number;
-	public var regionRotate:Boolean;
-	public var regionOffsetX:Number; // Pixels stripped from the bottom left, unrotated.
-	public var regionOffsetY:Number;
-	public var regionWidth:Number; // Unrotated, stripped size.
-	public var regionHeight:Number;
-	public var regionOriginalWidth:Number; // Unrotated, unstripped size.
-	public var regionOriginalHeight:Number;
-
-	// Nonessential.
-	public var edges:Vector.<int>;
-	public var width:Number;
-	public var height:Number;
-
-	public function MeshAttachment (name:String) {
-		super(name);
-	}
-
-	public function updateUVs () : void {
-		var width:Number = regionU2 - regionU, height:Number = regionV2 - regionV;
-		var i:int, n:int = regionUVs.length;
-		if (!uvs || uvs.length != n) uvs = new Vector.<Number>(n, true);
-		if (regionRotate) {
-			for (i = 0; i < n; i += 2) {
-				uvs[i] = regionU + regionUVs[int(i + 1)] * width;
-				uvs[int(i + 1)] = regionV + height - regionUVs[i] * height;
-			}
-		} else {
-			for (i = 0; i < n; i += 2) {
-				uvs[i] = regionU + regionUVs[i] * width;
-				uvs[int(i + 1)] = regionV + regionUVs[int(i + 1)] * height;
-			}
-		}
-	}
-
-	public function applyFFD (sourceAttachment:Attachment) : Boolean {
-		return this == sourceAttachment || (inheritDeform && _parentMesh == sourceAttachment);
-	}
-
-	public function get parentMesh () : MeshAttachment {
-		return _parentMesh;
-	}
-
-	public function set parentMesh (parentMesh:MeshAttachment) : void {
-		_parentMesh = parentMesh;
-		if (parentMesh != null) {
-			bones = parentMesh.bones;
-			vertices = parentMesh.vertices;
-			worldVerticesLength = parentMesh.worldVerticesLength;
-			regionUVs = parentMesh.regionUVs;
-			triangles = parentMesh.triangles;
-			hullLength = parentMesh.hullLength;
-			edges = parentMesh.edges;
-			width = parentMesh.width;
-			height = parentMesh.height;
-		}
-	}
-}
-
+package spine.attachments {
+
+public dynamic class MeshAttachment extends VertexAttachment {
+	public var worldVertices:Vector.<Number>;
+	public var uvs:Vector.<Number>;
+	public var regionUVs:Vector.<Number>;
+	public var triangles:Vector.<uint>;	
+	public var r:Number = 1;
+	public var g:Number = 1;
+	public var b:Number = 1;
+	public var a:Number = 1;
+	public var hullLength:int;
+	private var _parentMesh:MeshAttachment;
+	public var inheritDeform:Boolean;
+
+	public var path:String;
+	public var rendererObject:Object;
+	public var regionU:Number;
+	public var regionV:Number;
+	public var regionU2:Number;
+	public var regionV2:Number;
+	public var regionRotate:Boolean;
+	public var regionOffsetX:Number; // Pixels stripped from the bottom left, unrotated.
+	public var regionOffsetY:Number;
+	public var regionWidth:Number; // Unrotated, stripped size.
+	public var regionHeight:Number;
+	public var regionOriginalWidth:Number; // Unrotated, unstripped size.
+	public var regionOriginalHeight:Number;
+
+	// Nonessential.
+	public var edges:Vector.<int>;
+	public var width:Number;
+	public var height:Number;
+
+	public function MeshAttachment (name:String) {
+		super(name);
+	}
+
+	public function updateUVs () : void {
+		var width:Number = regionU2 - regionU, height:Number = regionV2 - regionV;
+		var i:int, n:int = regionUVs.length;
+		if (!uvs || uvs.length != n) uvs = new Vector.<Number>(n, true);
+		if (regionRotate) {
+			for (i = 0; i < n; i += 2) {
+				uvs[i] = regionU + regionUVs[int(i + 1)] * width;
+				uvs[int(i + 1)] = regionV + height - regionUVs[i] * height;
+			}
+		} else {
+			for (i = 0; i < n; i += 2) {
+				uvs[i] = regionU + regionUVs[i] * width;
+				uvs[int(i + 1)] = regionV + regionUVs[int(i + 1)] * height;
+			}
+		}
+	}
+
+	public function applyFFD (sourceAttachment:Attachment) : Boolean {
+		return this == sourceAttachment || (inheritDeform && _parentMesh == sourceAttachment);
+	}
+
+	public function get parentMesh () : MeshAttachment {
+		return _parentMesh;
+	}
+
+	public function set parentMesh (parentMesh:MeshAttachment) : void {
+		_parentMesh = parentMesh;
+		if (parentMesh != null) {
+			bones = parentMesh.bones;
+			vertices = parentMesh.vertices;
+			worldVerticesLength = parentMesh.worldVerticesLength;
+			regionUVs = parentMesh.regionUVs;
+			triangles = parentMesh.triangles;
+			hullLength = parentMesh.hullLength;
+			edges = parentMesh.edges;
+			width = parentMesh.width;
+			height = parentMesh.height;
+		}
+	}
+}
+
 }

+ 39 - 40
spine-as3/spine-as3/src/spine/attachments/PathAttachment.as

@@ -1,43 +1,42 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.attachments {
-
-public dynamic class PathAttachment extends VertexAttachment {
-	public var lengths:Vector.<Number>;
-	public var closed:Boolean, constantSpeed:Boolean;
-
-	public function PathAttachment (name:String) {
-		super(name);
-	}
-}
-
+package spine.attachments {
+
+public dynamic class PathAttachment extends VertexAttachment {
+	public var lengths:Vector.<Number>;
+	public var closed:Boolean, constantSpeed:Boolean;
+
+	public function PathAttachment (name:String) {
+		super(name);
+	}
+}
+
 }

+ 147 - 148
spine-as3/spine-as3/src/spine/attachments/RegionAttachment.as

@@ -1,151 +1,150 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.attachments {
-import spine.Bone;
-
-public dynamic class RegionAttachment extends Attachment {
-	public const X1:int = 0;
-	public const Y1:int = 1;
-	public const X2:int = 2;
-	public const Y2:int = 3;
-	public const X3:int = 4;
-	public const Y3:int = 5;
-	public const X4:int = 6;
-	public const Y4:int = 7;
-
-	public var x:Number;
-	public var y:Number;
-	public var scaleX:Number = 1;
-	public var scaleY:Number = 1;
-	public var rotation:Number;
-	public var width:Number;
-	public var height:Number;
-	public var r:Number = 1;
-	public var g:Number = 1;
-	public var b:Number = 1;
-	public var a:Number = 1;
-
-	public var path:String;
-	public var rendererObject:Object;
-	public var regionOffsetX:Number; // Pixels stripped from the bottom left, unrotated.
-	public var regionOffsetY:Number;
-	public var regionWidth:Number; // Unrotated, stripped size.
-	public var regionHeight:Number;
-	public var regionOriginalWidth:Number; // Unrotated, unstripped size.
-	public var regionOriginalHeight:Number;
-
-	public var offset:Vector.<Number> = new Vector.<Number>();
-	public var uvs:Vector.<Number> = new Vector.<Number>();
-
-	public function RegionAttachment (name:String) {
-		super(name);
-		offset.length = 8;
-		uvs.length = 8;
-	}
-
-	public function setUVs (u:Number, v:Number, u2:Number, v2:Number, rotate:Boolean) : void {
-		if (rotate) {
-			uvs[X2] = u;
-			uvs[Y2] = v2;
-			uvs[X3] = u;
-			uvs[Y3] = v;
-			uvs[X4] = u2;
-			uvs[Y4] = v;
-			uvs[X1] = u2;
-			uvs[Y1] = v2;
-		} else {
-			uvs[X1] = u;
-			uvs[Y1] = v2;
-			uvs[X2] = u;
-			uvs[Y2] = v;
-			uvs[X3] = u2;
-			uvs[Y3] = v;
-			uvs[X4] = u2;
-			uvs[Y4] = v2;
-		}
-	}
-
-	public function updateOffset () : void {
-		var regionScaleX:Number = width / regionOriginalWidth * scaleX;
-		var regionScaleY:Number = height / regionOriginalHeight * scaleY;
-		var localX:Number = -width / 2 * scaleX + regionOffsetX * regionScaleX;
-		var localY:Number = -height / 2 * scaleY + regionOffsetY * regionScaleY;
-		var localX2:Number = localX + regionWidth * regionScaleX;
-		var localY2:Number = localY + regionHeight * regionScaleY;
-		var radians:Number = rotation * Math.PI / 180;
-		var cos:Number = Math.cos(radians);
-		var sin:Number = Math.sin(radians);
-		var localXCos:Number = localX * cos + x;
-		var localXSin:Number = localX * sin;
-		var localYCos:Number = localY * cos + y;
-		var localYSin:Number = localY * sin;
-		var localX2Cos:Number = localX2 * cos + x;
-		var localX2Sin:Number = localX2 * sin;
-		var localY2Cos:Number = localY2 * cos + y;
-		var localY2Sin:Number = localY2 * sin;
-		offset[X1] = localXCos - localYSin;
-		offset[Y1] = localYCos + localXSin;
-		offset[X2] = localXCos - localY2Sin;
-		offset[Y2] = localY2Cos + localXSin;
-		offset[X3] = localX2Cos - localY2Sin;
-		offset[Y3] = localY2Cos + localX2Sin;
-		offset[X4] = localX2Cos - localYSin;
-		offset[Y4] = localYCos + localX2Sin;
-	}
-
-	public function computeWorldVertices (x:Number, y:Number, bone:Bone, worldVertices:Vector.<Number>) : void {
-		x += bone.worldX;
-		y += bone.worldY;
-		var m00:Number = bone.a;
-		var m01:Number = bone.b;
-		var m10:Number = bone.c;
-		var m11:Number = bone.d;
-		var x1:Number = offset[X1];
-		var y1:Number = offset[Y1];
-		var x2:Number = offset[X2];
-		var y2:Number = offset[Y2];
-		var x3:Number = offset[X3];
-		var y3:Number = offset[Y3];
-		var x4:Number = offset[X4];
-		var y4:Number = offset[Y4];
-		worldVertices[X1] = x1 * m00 + y1 * m01 + x;
-		worldVertices[Y1] = x1 * m10 + y1 * m11 + y;
-		worldVertices[X2] = x2 * m00 + y2 * m01 + x;
-		worldVertices[Y2] = x2 * m10 + y2 * m11 + y;
-		worldVertices[X3] = x3 * m00 + y3 * m01 + x;
-		worldVertices[Y3] = x3 * m10 + y3 * m11 + y;
-		worldVertices[X4] = x4 * m00 + y4 * m01 + x;
-		worldVertices[Y4] = x4 * m10 + y4 * m11 + y;
-	}
-}
-
+package spine.attachments {
+import spine.Bone;
+
+public dynamic class RegionAttachment extends Attachment {
+	public const X1:int = 0;
+	public const Y1:int = 1;
+	public const X2:int = 2;
+	public const Y2:int = 3;
+	public const X3:int = 4;
+	public const Y3:int = 5;
+	public const X4:int = 6;
+	public const Y4:int = 7;
+
+	public var x:Number;
+	public var y:Number;
+	public var scaleX:Number = 1;
+	public var scaleY:Number = 1;
+	public var rotation:Number;
+	public var width:Number;
+	public var height:Number;
+	public var r:Number = 1;
+	public var g:Number = 1;
+	public var b:Number = 1;
+	public var a:Number = 1;
+
+	public var path:String;
+	public var rendererObject:Object;
+	public var regionOffsetX:Number; // Pixels stripped from the bottom left, unrotated.
+	public var regionOffsetY:Number;
+	public var regionWidth:Number; // Unrotated, stripped size.
+	public var regionHeight:Number;
+	public var regionOriginalWidth:Number; // Unrotated, unstripped size.
+	public var regionOriginalHeight:Number;
+
+	public var offset:Vector.<Number> = new Vector.<Number>();
+	public var uvs:Vector.<Number> = new Vector.<Number>();
+
+	public function RegionAttachment (name:String) {
+		super(name);
+		offset.length = 8;
+		uvs.length = 8;
+	}
+
+	public function setUVs (u:Number, v:Number, u2:Number, v2:Number, rotate:Boolean) : void {
+		if (rotate) {
+			uvs[X2] = u;
+			uvs[Y2] = v2;
+			uvs[X3] = u;
+			uvs[Y3] = v;
+			uvs[X4] = u2;
+			uvs[Y4] = v;
+			uvs[X1] = u2;
+			uvs[Y1] = v2;
+		} else {
+			uvs[X1] = u;
+			uvs[Y1] = v2;
+			uvs[X2] = u;
+			uvs[Y2] = v;
+			uvs[X3] = u2;
+			uvs[Y3] = v;
+			uvs[X4] = u2;
+			uvs[Y4] = v2;
+		}
+	}
+
+	public function updateOffset () : void {
+		var regionScaleX:Number = width / regionOriginalWidth * scaleX;
+		var regionScaleY:Number = height / regionOriginalHeight * scaleY;
+		var localX:Number = -width / 2 * scaleX + regionOffsetX * regionScaleX;
+		var localY:Number = -height / 2 * scaleY + regionOffsetY * regionScaleY;
+		var localX2:Number = localX + regionWidth * regionScaleX;
+		var localY2:Number = localY + regionHeight * regionScaleY;
+		var radians:Number = rotation * Math.PI / 180;
+		var cos:Number = Math.cos(radians);
+		var sin:Number = Math.sin(radians);
+		var localXCos:Number = localX * cos + x;
+		var localXSin:Number = localX * sin;
+		var localYCos:Number = localY * cos + y;
+		var localYSin:Number = localY * sin;
+		var localX2Cos:Number = localX2 * cos + x;
+		var localX2Sin:Number = localX2 * sin;
+		var localY2Cos:Number = localY2 * cos + y;
+		var localY2Sin:Number = localY2 * sin;
+		offset[X1] = localXCos - localYSin;
+		offset[Y1] = localYCos + localXSin;
+		offset[X2] = localXCos - localY2Sin;
+		offset[Y2] = localY2Cos + localXSin;
+		offset[X3] = localX2Cos - localY2Sin;
+		offset[Y3] = localY2Cos + localX2Sin;
+		offset[X4] = localX2Cos - localYSin;
+		offset[Y4] = localYCos + localX2Sin;
+	}
+
+	public function computeWorldVertices (x:Number, y:Number, bone:Bone, worldVertices:Vector.<Number>) : void {
+		x += bone.worldX;
+		y += bone.worldY;
+		var m00:Number = bone.a;
+		var m01:Number = bone.b;
+		var m10:Number = bone.c;
+		var m11:Number = bone.d;
+		var x1:Number = offset[X1];
+		var y1:Number = offset[Y1];
+		var x2:Number = offset[X2];
+		var y2:Number = offset[Y2];
+		var x3:Number = offset[X3];
+		var y3:Number = offset[Y3];
+		var x4:Number = offset[X4];
+		var y4:Number = offset[Y4];
+		worldVertices[X1] = x1 * m00 + y1 * m01 + x;
+		worldVertices[Y1] = x1 * m10 + y1 * m11 + y;
+		worldVertices[X2] = x2 * m00 + y2 * m01 + x;
+		worldVertices[Y2] = x2 * m10 + y2 * m11 + y;
+		worldVertices[X3] = x3 * m00 + y3 * m01 + x;
+		worldVertices[Y3] = x3 * m10 + y3 * m11 + y;
+		worldVertices[X4] = x4 * m00 + y4 * m01 + x;
+		worldVertices[Y4] = x4 * m10 + y4 * m11 + y;
+	}
+}
+
 }

+ 123 - 124
spine-as3/spine-as3/src/spine/attachments/VertexAttachment.as

@@ -1,127 +1,126 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.attachments {
-	import spine.Bone;
-	import spine.Skeleton;
-	import spine.Slot;
-
-public dynamic class VertexAttachment extends Attachment {
-	public var bones:Vector.<int>;
-	public var vertices:Vector.<Number>;
-	public var worldVerticesLength:int;
-
-	public function VertexAttachment (name:String) {
-		super(name);
-	}
-
-	public function computeWorldVertices (slot:Slot, worldVertices:Vector.<Number>): void {
-		computeWorldVertices2(slot, 0, worldVerticesLength, worldVertices, 0);
-	}
-
-	/** Transforms local vertices to world coordinates.
-	 * @param start The index of the first local vertex value to transform. Each vertex has 2 values, x and y.
-	 * @param count The number of world vertex values to output. Must be <= {@link #getWorldVerticesLength()} - start.
-	 * @param worldVertices The output world vertices. Must have a length >= offset + count.
-	 * @param offset The worldVertices index to begin writing values. */
-	public function computeWorldVertices2 (slot:Slot, start:int, count:int, worldVertices:Vector.<Number>, offset:int): void {
-		count += offset;
-		var skeleton:Skeleton = slot.skeleton;
-		var x:Number = skeleton.x, y:Number = skeleton.y;
-		var deformArray:Vector.<Number> = slot.attachmentVertices;
-		var vertices:Vector.<Number> = this.vertices;
-		var bones:Vector.<int> = this.bones;
-		var deform:Vector.<Number>;
-		
-		var v:int, w:int, n:int, i:int, skip:int, b:int, f:int;
-		var vx:Number, vy:Number;
-		var wx:Number, wy:Number;
-		var bone:Bone;
-		
-		if (bones == null) {
-			if (deformArray.length > 0) vertices = deformArray;
-			bone = slot.bone;
-			x += bone.worldX;
-			y += bone.worldY;
-			var a:Number = bone.a, bb:Number = bone.b, c:Number = bone.c, d:Number = bone.d;
-			for (v = start, w = offset; w < count; v += 2, w += 2) {
-				vx = vertices[v], vy = vertices[v + 1];
-				worldVertices[w] = vx * a + vy * bb + x;
-				worldVertices[w + 1] = vx * c + vy * d + y;
-			}
-			return;
-		}
-		v = 0, skip = 0;
-		for (i = 0; i < start; i += 2) {
-			n = bones[v];
-			v += n + 1;
-			skip += n;
-		}
-		var skeletonBones:Vector.<Bone> = skeleton.bones;
-		if (deformArray.length == 0) {
-			for (w = offset, b = skip * 3; w < count; w += 2) {
-				wx = x, wy = y;
-				n = bones[v++];
-				n += v;
-				for (; v < n; v++, b += 3) {
-					bone = skeletonBones[bones[v]];
-					vx = vertices[b]; vy = vertices[b + 1]; var weight:Number = vertices[b + 2];
-					wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
-					wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
-				}
-				worldVertices[w] = wx;
-				worldVertices[w + 1] = wy;
-			}
-		} else {
-			deform = deformArray;
-			for (w = offset, b = skip * 3, f = skip << 1; w < count; w += 2) {
-				wx = x; wy = y;
-				n = bones[v++];
-				n += v;
-				for (; v < n; v++, b += 3, f += 2) {
-					bone = skeletonBones[bones[v]];
-					vx = vertices[b] + deform[f]; vy = vertices[b + 1] + deform[f + 1]; weight = vertices[b + 2];
-					wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
-					wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
-				}
-				worldVertices[w] = wx;
-				worldVertices[w + 1] = wy;
-			}
-		}
-	}
-
-	/** Returns true if a deform originally applied to the specified attachment should be applied to this attachment. */
-	public function applyDeform (sourceAttachment:VertexAttachment): Boolean {
-		return this == sourceAttachment;
-	}
-}
-
+package spine.attachments {
+	import spine.Bone;
+	import spine.Skeleton;
+	import spine.Slot;
+
+public dynamic class VertexAttachment extends Attachment {
+	public var bones:Vector.<int>;
+	public var vertices:Vector.<Number>;
+	public var worldVerticesLength:int;
+
+	public function VertexAttachment (name:String) {
+		super(name);
+	}
+
+	public function computeWorldVertices (slot:Slot, worldVertices:Vector.<Number>): void {
+		computeWorldVertices2(slot, 0, worldVerticesLength, worldVertices, 0);
+	}
+
+	/** Transforms local vertices to world coordinates.
+	 * @param start The index of the first local vertex value to transform. Each vertex has 2 values, x and y.
+	 * @param count The number of world vertex values to output. Must be <= {@link #getWorldVerticesLength()} - start.
+	 * @param worldVertices The output world vertices. Must have a length >= offset + count.
+	 * @param offset The worldVertices index to begin writing values. */
+	public function computeWorldVertices2 (slot:Slot, start:int, count:int, worldVertices:Vector.<Number>, offset:int): void {
+		count += offset;
+		var skeleton:Skeleton = slot.skeleton;
+		var x:Number = skeleton.x, y:Number = skeleton.y;
+		var deformArray:Vector.<Number> = slot.attachmentVertices;
+		var vertices:Vector.<Number> = this.vertices;
+		var bones:Vector.<int> = this.bones;
+		var deform:Vector.<Number>;
+		
+		var v:int, w:int, n:int, i:int, skip:int, b:int, f:int;
+		var vx:Number, vy:Number;
+		var wx:Number, wy:Number;
+		var bone:Bone;
+		
+		if (bones == null) {
+			if (deformArray.length > 0) vertices = deformArray;
+			bone = slot.bone;
+			x += bone.worldX;
+			y += bone.worldY;
+			var a:Number = bone.a, bb:Number = bone.b, c:Number = bone.c, d:Number = bone.d;
+			for (v = start, w = offset; w < count; v += 2, w += 2) {
+				vx = vertices[v], vy = vertices[v + 1];
+				worldVertices[w] = vx * a + vy * bb + x;
+				worldVertices[w + 1] = vx * c + vy * d + y;
+			}
+			return;
+		}
+		v = 0, skip = 0;
+		for (i = 0; i < start; i += 2) {
+			n = bones[v];
+			v += n + 1;
+			skip += n;
+		}
+		var skeletonBones:Vector.<Bone> = skeleton.bones;
+		if (deformArray.length == 0) {
+			for (w = offset, b = skip * 3; w < count; w += 2) {
+				wx = x, wy = y;
+				n = bones[v++];
+				n += v;
+				for (; v < n; v++, b += 3) {
+					bone = skeletonBones[bones[v]];
+					vx = vertices[b]; vy = vertices[b + 1]; var weight:Number = vertices[b + 2];
+					wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
+					wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
+				}
+				worldVertices[w] = wx;
+				worldVertices[w + 1] = wy;
+			}
+		} else {
+			deform = deformArray;
+			for (w = offset, b = skip * 3, f = skip << 1; w < count; w += 2) {
+				wx = x; wy = y;
+				n = bones[v++];
+				n += v;
+				for (; v < n; v++, b += 3, f += 2) {
+					bone = skeletonBones[bones[v]];
+					vx = vertices[b] + deform[f]; vy = vertices[b + 1] + deform[f + 1]; weight = vertices[b + 2];
+					wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
+					wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
+				}
+				worldVertices[w] = wx;
+				worldVertices[w + 1] = wy;
+			}
+		}
+	}
+
+	/** Returns true if a deform originally applied to the specified attachment should be applied to this attachment. */
+	public function applyDeform (sourceAttachment:VertexAttachment): Boolean {
+		return this == sourceAttachment;
+	}
+}
+
 }

+ 82 - 83
spine-as3/spine-as3/src/spine/flash/FlashTextureLoader.as

@@ -1,86 +1,85 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.flash {
-import flash.display.Bitmap;
-import flash.display.BitmapData;
-
-import spine.atlas.AtlasPage;
-import spine.atlas.AtlasRegion;
-import spine.atlas.TextureLoader;
-
-public class FlashTextureLoader implements TextureLoader {
-	public var bitmapDatas:Object = {};
-	public var singleBitmapData:BitmapData;
-
-	/** @param bitmaps A Bitmap or BitmapData for an atlas that has only one page, or for a multi page atlas an object where the 
-	 * key is the image path and the value is the Bitmap or BitmapData. */
-	public function FlashTextureLoader (bitmaps:Object) {
-		if (bitmaps is BitmapData) {
-			singleBitmapData = BitmapData(bitmaps);
-			return;
-		}
-		if (bitmaps is Bitmap) {
-			singleBitmapData = Bitmap(bitmaps).bitmapData;
-			return;
-		}
-
-		for (var path:* in bitmaps) {
-			var object:* = bitmaps[path];
-			var bitmapData:BitmapData;
-			if (object is BitmapData)
-				bitmapData = BitmapData(object);
-			else if (object is Bitmap)
-				bitmapData = Bitmap(object).bitmapData;
-			else
-				throw new ArgumentError("Object for path \"" + path + "\" must be a Bitmap or BitmapData: " + object);
-			bitmapDatas[path] = bitmapData;
-		}
-	}
-
-	public function loadPage (page:AtlasPage, path:String) : void {
-		var bitmapData:BitmapData = singleBitmapData || bitmapDatas[path];
-		if (!bitmapData)
-			throw new ArgumentError("BitmapData not found with name: " + path);
-		page.rendererObject = bitmapData;
-		page.width = bitmapData.width;
-		page.height = bitmapData.height;
-	}
-	
-	public function loadRegion (region:AtlasRegion) : void {
-	}
-
-	public function unloadPage (page:AtlasPage) : void {
-		BitmapData(page.rendererObject).dispose();
-	}
-}
-
+package spine.flash {
+import flash.display.Bitmap;
+import flash.display.BitmapData;
+
+import spine.atlas.AtlasPage;
+import spine.atlas.AtlasRegion;
+import spine.atlas.TextureLoader;
+
+public class FlashTextureLoader implements TextureLoader {
+	public var bitmapDatas:Object = {};
+	public var singleBitmapData:BitmapData;
+
+	/** @param bitmaps A Bitmap or BitmapData for an atlas that has only one page, or for a multi page atlas an object where the 
+	 * key is the image path and the value is the Bitmap or BitmapData. */
+	public function FlashTextureLoader (bitmaps:Object) {
+		if (bitmaps is BitmapData) {
+			singleBitmapData = BitmapData(bitmaps);
+			return;
+		}
+		if (bitmaps is Bitmap) {
+			singleBitmapData = Bitmap(bitmaps).bitmapData;
+			return;
+		}
+
+		for (var path:* in bitmaps) {
+			var object:* = bitmaps[path];
+			var bitmapData:BitmapData;
+			if (object is BitmapData)
+				bitmapData = BitmapData(object);
+			else if (object is Bitmap)
+				bitmapData = Bitmap(object).bitmapData;
+			else
+				throw new ArgumentError("Object for path \"" + path + "\" must be a Bitmap or BitmapData: " + object);
+			bitmapDatas[path] = bitmapData;
+		}
+	}
+
+	public function loadPage (page:AtlasPage, path:String) : void {
+		var bitmapData:BitmapData = singleBitmapData || bitmapDatas[path];
+		if (!bitmapData)
+			throw new ArgumentError("BitmapData not found with name: " + path);
+		page.rendererObject = bitmapData;
+		page.width = bitmapData.width;
+		page.height = bitmapData.height;
+	}
+	
+	public function loadRegion (region:AtlasRegion) : void {
+	}
+
+	public function unloadPage (page:AtlasPage) : void {
+		BitmapData(page.rendererObject).dispose();
+	}
+}
+
 }

+ 49 - 50
spine-as3/spine-as3/src/spine/flash/SkeletonAnimation.as

@@ -1,53 +1,52 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.flash {
-import spine.SkeletonData;
-import spine.animation.AnimationState;
-import spine.animation.AnimationStateData;
-
-public class SkeletonAnimation extends SkeletonSprite {
-	public var state:AnimationState;
-
-	public function SkeletonAnimation (skeletonData:SkeletonData, stateData:AnimationStateData = null) {
-		super(skeletonData);
-		state = new AnimationState(stateData ? stateData : new AnimationStateData(skeletonData));
-	}
-
-	override public function advanceTime (time:Number) : void {
-		state.update(time * timeScale);
-		state.apply(skeleton);
-		skeleton.updateWorldTransform();
-		super.advanceTime(time);
-	}
-}
-
+package spine.flash {
+import spine.SkeletonData;
+import spine.animation.AnimationState;
+import spine.animation.AnimationStateData;
+
+public class SkeletonAnimation extends SkeletonSprite {
+	public var state:AnimationState;
+
+	public function SkeletonAnimation (skeletonData:SkeletonData, stateData:AnimationStateData = null) {
+		super(skeletonData);
+		state = new AnimationState(stateData ? stateData : new AnimationStateData(skeletonData));
+	}
+
+	override public function advanceTime (time:Number) : void {
+		state.update(time * timeScale);
+		state.apply(skeleton);
+		skeleton.updateWorldTransform();
+		super.advanceTime(time);
+	}
+}
+
 }

+ 149 - 150
spine-as3/spine-as3/src/spine/flash/SkeletonSprite.as

@@ -1,153 +1,152 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-package spine.flash {
-import flash.utils.Dictionary;
-import flash.display.Bitmap;
-import flash.display.BitmapData;
-import flash.display.BlendMode;
-import flash.display.Sprite;
-import flash.events.Event;
-import flash.geom.ColorTransform;
-import flash.geom.Point;
-import flash.geom.Rectangle;
-import flash.utils.getTimer;
-
-import spine.Bone;
-import spine.Skeleton;
-import spine.SkeletonData;
-import spine.Slot;
-import spine.atlas.AtlasRegion;
-import spine.attachments.RegionAttachment;
-
-public class SkeletonSprite extends Sprite {
-	static private var blendModes:Vector.<String> = new <String>[
-		BlendMode.NORMAL, BlendMode.ADD, BlendMode.MULTIPLY, BlendMode.SCREEN];
-
-	private var _skeleton:Skeleton;
-	public var timeScale:Number = 1;
-	private var lastTime:int;
-	private var wrappers:Dictionary = new Dictionary(true);
-
-	public function SkeletonSprite (skeletonData:SkeletonData) {
-		Bone.yDown = true;
-
-		_skeleton = new Skeleton(skeletonData);
-		_skeleton.updateWorldTransform();
-
-		addEventListener(Event.ENTER_FRAME, enterFrame);
-	}
-
-	private function enterFrame (event:Event) : void {
-		var time:int = getTimer();
-		advanceTime((time - lastTime) / 1000);
-		lastTime = time;
-	}
-
-	public function advanceTime (delta:Number) : void {
-		_skeleton.update(delta * timeScale);
-
-		removeChildren();
-		var drawOrder:Vector.<Slot> = skeleton.drawOrder;
-		for (var i:int = 0, n:int = drawOrder.length; i < n; i++) {
-			var slot:Slot = drawOrder[i];
-			var regionAttachment:RegionAttachment = slot.attachment as RegionAttachment;
-			if (!regionAttachment) continue;
-
-			var wrapper:Sprite = wrappers[regionAttachment];
-			if (!wrapper) {
-				var region:AtlasRegion = AtlasRegion(regionAttachment.rendererObject);
-				var regionHeight:Number = region.rotate ? region.width : region.height;
-				var regionData:BitmapData = region.rendererObject as BitmapData;
-				if (!regionData) {
-					var bitmapData:BitmapData = region.page.rendererObject as BitmapData;
-					var regionWidth:Number = region.rotate ? region.height : region.width;
-					regionData = new BitmapData(regionWidth, regionHeight);
-					regionData.copyPixels(bitmapData, new Rectangle(region.x, region.y, regionWidth, regionHeight), new Point());
-					region.rendererObject = regionData;
-				}
-
-				var bitmap:Bitmap = new Bitmap(regionData);
-				bitmap.smoothing = true;
-
-				// Rotate and scale using default registration point (top left corner, y-down, CW) instead of image center.
-				bitmap.rotation = -regionAttachment.rotation;
-				bitmap.scaleX = regionAttachment.scaleX * (regionAttachment.width / region.width);
-				bitmap.scaleY = regionAttachment.scaleY * (regionAttachment.height / region.height);
-
-				// Position using attachment translation, shifted as if scale and rotation were at image center.
-				var radians:Number = -regionAttachment.rotation * Math.PI / 180;
-				var cos:Number = Math.cos(radians);
-				var sin:Number = Math.sin(radians);
-				var shiftX:Number = -regionAttachment.width / 2 * regionAttachment.scaleX;
-				var shiftY:Number = -regionAttachment.height / 2 * regionAttachment.scaleY;
-				if (region.rotate) {
-					bitmap.rotation += 90;
-					shiftX += regionHeight * (regionAttachment.width / region.width);
-				}
-				bitmap.x = regionAttachment.x + shiftX * cos - shiftY * sin;
-				bitmap.y = -regionAttachment.y + shiftX * sin + shiftY * cos;
-
-				// Use bone as registration point.
-				wrapper = new Sprite();
-				wrapper.transform.colorTransform = new ColorTransform();
-				wrapper.addChild(bitmap);
-				wrappers[regionAttachment] = wrapper;
-			}
-
-			wrapper.blendMode = blendModes[slot.data.blendMode.ordinal];
-
-			var colorTransform:ColorTransform = wrapper.transform.colorTransform;
-			colorTransform.redMultiplier = skeleton.r * slot.r * regionAttachment.r;
-			colorTransform.greenMultiplier = skeleton.g * slot.g * regionAttachment.g;
-			colorTransform.blueMultiplier = skeleton.b * slot.b * regionAttachment.b;
-			colorTransform.alphaMultiplier = skeleton.a * slot.a * regionAttachment.a;
-			wrapper.transform.colorTransform = colorTransform;
-
-			var bone:Bone = slot.bone;
-			var flipX:int = skeleton.flipX ? -1 : 1;
-			var flipY:int = skeleton.flipY ? -1 : 1;
-
-			wrapper.x = bone.worldX;
-			wrapper.y = bone.worldY;
-			wrapper.rotation = bone.worldRotationX * flipX * flipY;
-			wrapper.scaleX = bone.worldScaleX * flipX;
-			wrapper.scaleY = bone.worldScaleY * flipY;
-			addChild(wrapper);
-		}
-	}
-
-	public function get skeleton () : Skeleton {
-		return _skeleton;
-	}
-}
-
+package spine.flash {
+import flash.utils.Dictionary;
+import flash.display.Bitmap;
+import flash.display.BitmapData;
+import flash.display.BlendMode;
+import flash.display.Sprite;
+import flash.events.Event;
+import flash.geom.ColorTransform;
+import flash.geom.Point;
+import flash.geom.Rectangle;
+import flash.utils.getTimer;
+
+import spine.Bone;
+import spine.Skeleton;
+import spine.SkeletonData;
+import spine.Slot;
+import spine.atlas.AtlasRegion;
+import spine.attachments.RegionAttachment;
+
+public class SkeletonSprite extends Sprite {
+	static private var blendModes:Vector.<String> = new <String>[
+		BlendMode.NORMAL, BlendMode.ADD, BlendMode.MULTIPLY, BlendMode.SCREEN];
+
+	private var _skeleton:Skeleton;
+	public var timeScale:Number = 1;
+	private var lastTime:int;
+	private var wrappers:Dictionary = new Dictionary(true);
+
+	public function SkeletonSprite (skeletonData:SkeletonData) {
+		Bone.yDown = true;
+
+		_skeleton = new Skeleton(skeletonData);
+		_skeleton.updateWorldTransform();
+
+		addEventListener(Event.ENTER_FRAME, enterFrame);
+	}
+
+	private function enterFrame (event:Event) : void {
+		var time:int = getTimer();
+		advanceTime((time - lastTime) / 1000);
+		lastTime = time;
+	}
+
+	public function advanceTime (delta:Number) : void {
+		_skeleton.update(delta * timeScale);
+
+		removeChildren();
+		var drawOrder:Vector.<Slot> = skeleton.drawOrder;
+		for (var i:int = 0, n:int = drawOrder.length; i < n; i++) {
+			var slot:Slot = drawOrder[i];
+			var regionAttachment:RegionAttachment = slot.attachment as RegionAttachment;
+			if (!regionAttachment) continue;
+
+			var wrapper:Sprite = wrappers[regionAttachment];
+			if (!wrapper) {
+				var region:AtlasRegion = AtlasRegion(regionAttachment.rendererObject);
+				var regionHeight:Number = region.rotate ? region.width : region.height;
+				var regionData:BitmapData = region.rendererObject as BitmapData;
+				if (!regionData) {
+					var bitmapData:BitmapData = region.page.rendererObject as BitmapData;
+					var regionWidth:Number = region.rotate ? region.height : region.width;
+					regionData = new BitmapData(regionWidth, regionHeight);
+					regionData.copyPixels(bitmapData, new Rectangle(region.x, region.y, regionWidth, regionHeight), new Point());
+					region.rendererObject = regionData;
+				}
+
+				var bitmap:Bitmap = new Bitmap(regionData);
+				bitmap.smoothing = true;
+
+				// Rotate and scale using default registration point (top left corner, y-down, CW) instead of image center.
+				bitmap.rotation = -regionAttachment.rotation;
+				bitmap.scaleX = regionAttachment.scaleX * (regionAttachment.width / region.width);
+				bitmap.scaleY = regionAttachment.scaleY * (regionAttachment.height / region.height);
+
+				// Position using attachment translation, shifted as if scale and rotation were at image center.
+				var radians:Number = -regionAttachment.rotation * Math.PI / 180;
+				var cos:Number = Math.cos(radians);
+				var sin:Number = Math.sin(radians);
+				var shiftX:Number = -regionAttachment.width / 2 * regionAttachment.scaleX;
+				var shiftY:Number = -regionAttachment.height / 2 * regionAttachment.scaleY;
+				if (region.rotate) {
+					bitmap.rotation += 90;
+					shiftX += regionHeight * (regionAttachment.width / region.width);
+				}
+				bitmap.x = regionAttachment.x + shiftX * cos - shiftY * sin;
+				bitmap.y = -regionAttachment.y + shiftX * sin + shiftY * cos;
+
+				// Use bone as registration point.
+				wrapper = new Sprite();
+				wrapper.transform.colorTransform = new ColorTransform();
+				wrapper.addChild(bitmap);
+				wrappers[regionAttachment] = wrapper;
+			}
+
+			wrapper.blendMode = blendModes[slot.data.blendMode.ordinal];
+
+			var colorTransform:ColorTransform = wrapper.transform.colorTransform;
+			colorTransform.redMultiplier = skeleton.r * slot.r * regionAttachment.r;
+			colorTransform.greenMultiplier = skeleton.g * slot.g * regionAttachment.g;
+			colorTransform.blueMultiplier = skeleton.b * slot.b * regionAttachment.b;
+			colorTransform.alphaMultiplier = skeleton.a * slot.a * regionAttachment.a;
+			wrapper.transform.colorTransform = colorTransform;
+
+			var bone:Bone = slot.bone;
+			var flipX:int = skeleton.flipX ? -1 : 1;
+			var flipY:int = skeleton.flipY ? -1 : 1;
+
+			wrapper.x = bone.worldX;
+			wrapper.y = bone.worldY;
+			wrapper.rotation = bone.worldRotationX * flipX * flipY;
+			wrapper.scaleX = bone.worldScaleX * flipX;
+			wrapper.scaleY = bone.worldScaleY * flipY;
+			addChild(wrapper);
+		}
+	}
+
+	public function get skeleton () : Skeleton {
+		return _skeleton;
+	}
+}
+
 }

+ 547 - 548
spine-c/include/spine/Animation.h

@@ -1,551 +1,550 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_ANIMATION_H_
-#define SPINE_ANIMATION_H_
-
-#include <spine/Event.h>
-#include <spine/Attachment.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spTimeline spTimeline;
-struct spSkeleton;
-
-typedef struct spAnimation {
-	const char* const name;
-	float duration;
-
-	int timelinesCount;
-	spTimeline** timelines;
-
-#ifdef __cplusplus
-	spAnimation() :
-		name(0),
-		duration(0),
-		timelinesCount(0),
-		timelines(0) {
-	}
-#endif
-} spAnimation;
-
-spAnimation* spAnimation_create (const char* name, int timelinesCount);
-void spAnimation_dispose (spAnimation* self);
-
-/** Poses the skeleton at the specified time for this animation.
- * @param lastTime The last time the animation was applied.
- * @param events Any triggered events are added. May be null.*/
-void spAnimation_apply (const spAnimation* self, struct spSkeleton* skeleton, float lastTime, float time, int loop,
-		spEvent** events, int* eventsCount);
-
-/** Poses the skeleton at the specified time for this animation mixed with the current pose.
- * @param lastTime The last time the animation was applied.
- * @param events Any triggered events are added. May be null.
- * @param alpha The amount of this animation that affects the current pose. */
-void spAnimation_mix (const spAnimation* self, struct spSkeleton* skeleton, float lastTime, float time, int loop,
-		spEvent** events, int* eventsCount, float alpha);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spAnimation Animation;
-#define Animation_create(...) spAnimation_create(__VA_ARGS__)
-#define Animation_dispose(...) spAnimation_dispose(__VA_ARGS__)
-#define Animation_apply(...) spAnimation_apply(__VA_ARGS__)
-#define Animation_mix(...) spAnimation_mix(__VA_ARGS__)
-#endif
-
-/**/
-
-typedef enum {
-	SP_TIMELINE_SCALE,
-	SP_TIMELINE_ROTATE,
-	SP_TIMELINE_TRANSLATE,
-	SP_TIMELINE_SHEAR,
-	SP_TIMELINE_COLOR,
-	SP_TIMELINE_ATTACHMENT,
-	SP_TIMELINE_EVENT,
-	SP_TIMELINE_DRAWORDER,
-	SP_TIMELINE_DEFORM,
-	SP_TIMELINE_IKCONSTRAINT,
-	SP_TIMELINE_TRANSFORMCONSTRAINT,
-	SP_TIMELINE_PATHCONSTRAINTPOSITION,
-	SP_TIMELINE_PATHCONSTRAINTSPACING,
-	SP_TIMELINE_PATHCONSTRAINTMIX
-} spTimelineType;
-
-struct spTimeline {
-	const spTimelineType type;
-	const void* const vtable;
-
-#ifdef __cplusplus
-	spTimeline() :
-		type(SP_TIMELINE_SCALE),
-		vtable(0) {
-	}
-#endif
-};
-
-void spTimeline_dispose (spTimeline* self);
-void spTimeline_apply (const spTimeline* self, struct spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
-		int* eventsCount, float alpha);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spTimeline Timeline;
-#define TIMELINE_SCALE SP_TIMELINE_SCALE
-#define TIMELINE_ROTATE SP_TIMELINE_ROTATE
-#define TIMELINE_TRANSLATE SP_TIMELINE_TRANSLATE
-#define TIMELINE_COLOR SP_TIMELINE_COLOR
-#define TIMELINE_ATTACHMENT SP_TIMELINE_ATTACHMENT
-#define TIMELINE_EVENT SP_TIMELINE_EVENT
-#define TIMELINE_DRAWORDER SP_TIMELINE_DRAWORDER
-#define Timeline_dispose(...) spTimeline_dispose(__VA_ARGS__)
-#define Timeline_apply(...) spTimeline_apply(__VA_ARGS__)
-#endif
-
-/**/
-
-typedef struct spCurveTimeline {
-	spTimeline super;
-	float* curves; /* type, x, y, ... */
-
-#ifdef __cplusplus
-	spCurveTimeline() :
-		super(),
-		curves(0) {
-	}
-#endif
-} spCurveTimeline;
-
-void spCurveTimeline_setLinear (spCurveTimeline* self, int frameIndex);
-void spCurveTimeline_setStepped (spCurveTimeline* self, int frameIndex);
-
-/* Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next.
- * cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of
- * the difference between the keyframe's values. */
-void spCurveTimeline_setCurve (spCurveTimeline* self, int frameIndex, float cx1, float cy1, float cx2, float cy2);
-float spCurveTimeline_getCurvePercent (const spCurveTimeline* self, int frameIndex, float percent);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spCurveTimeline CurveTimeline;
-#define CurveTimeline_setLinear(...) spCurveTimeline_setLinear(__VA_ARGS__)
-#define CurveTimeline_setStepped(...) spCurveTimeline_setStepped(__VA_ARGS__)
-#define CurveTimeline_setCurve(...) spCurveTimeline_setCurve(__VA_ARGS__)
-#define CurveTimeline_getCurvePercent(...) spCurveTimeline_getCurvePercent(__VA_ARGS__)
-#endif
-
-/**/
-
-typedef struct spBaseTimeline {
-	spCurveTimeline super;
-	int const framesCount;
-	float* const frames; /* time, angle, ... for rotate. time, x, y, ... for translate and scale. */
-	int boneIndex;
-
-#ifdef __cplusplus
-	spBaseTimeline() :
-		super(),
-		framesCount(0),
-		frames(0),
-		boneIndex(0) {
-	}
-#endif
-} spBaseTimeline;
-
-/**/
-
-static const int ROTATE_ENTRIES = 2;
-
-typedef struct spBaseTimeline spRotateTimeline;
-
-spRotateTimeline* spRotateTimeline_create (int framesCount);
-
-void spRotateTimeline_setFrame (spRotateTimeline* self, int frameIndex, float time, float angle);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spRotateTimeline RotateTimeline;
-#define RotateTimeline_create(...) spRotateTimeline_create(__VA_ARGS__)
-#define RotateTimeline_setFrame(...) spRotateTimeline_setFrame(__VA_ARGS__)
-#endif
-
-/**/
-
-static const int TRANSLATE_ENTRIES = 3;
-
-typedef struct spBaseTimeline spTranslateTimeline;
-
-spTranslateTimeline* spTranslateTimeline_create (int framesCount);
-
-void spTranslateTimeline_setFrame (spTranslateTimeline* self, int frameIndex, float time, float x, float y);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spTranslateTimeline TranslateTimeline;
-#define TranslateTimeline_create(...) spTranslateTimeline_create(__VA_ARGS__)
-#define TranslateTimeline_setFrame(...) spTranslateTimeline_setFrame(__VA_ARGS__)
-#endif
-
-/**/
-
-typedef struct spBaseTimeline spScaleTimeline;
-
-spScaleTimeline* spScaleTimeline_create (int framesCount);
-
-void spScaleTimeline_setFrame (spScaleTimeline* self, int frameIndex, float time, float x, float y);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spScaleTimeline ScaleTimeline;
-#define ScaleTimeline_create(...) spScaleTimeline_create(__VA_ARGS__)
-#define ScaleTimeline_setFrame(...) spScaleTimeline_setFrame(__VA_ARGS__)
-#endif
-
-/**/
-
-typedef struct spBaseTimeline spShearTimeline;
-
-spShearTimeline* spShearTimeline_create (int framesCount);
-
-void spShearTimeline_setFrame (spShearTimeline* self, int frameIndex, float time, float x, float y);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spShearTimeline ShearTimeline;
-#define ShearTimeline_create(...) spShearTimeline_create(__VA_ARGS__)
-#define ShearTimeline_setFrame(...) spShearTimeline_setFrame(__VA_ARGS__)
-#endif
-
-/**/
-
-static const int COLOR_ENTRIES = 5;
-
-typedef struct spColorTimeline {
-	spCurveTimeline super;
-	int const framesCount;
-	float* const frames; /* time, r, g, b, a, ... */
-	int slotIndex;
-
-#ifdef __cplusplus
-	spColorTimeline() :
-		super(),
-		framesCount(0),
-		frames(0),
-		slotIndex(0) {
-	}
-#endif
-} spColorTimeline;
-
-spColorTimeline* spColorTimeline_create (int framesCount);
-
-void spColorTimeline_setFrame (spColorTimeline* self, int frameIndex, float time, float r, float g, float b, float a);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spColorTimeline ColorTimeline;
-#define ColorTimeline_create(...) spColorTimeline_create(__VA_ARGS__)
-#define ColorTimeline_setFrame(...) spColorTimeline_setFrame(__VA_ARGS__)
-#endif
-
-/**/
-
-typedef struct spAttachmentTimeline {
-	spTimeline super;
-	int const framesCount;
-	float* const frames; /* time, ... */
-	int slotIndex;
-	const char** const attachmentNames;
-
-#ifdef __cplusplus
-	spAttachmentTimeline() :
-		super(),
-		framesCount(0),
-		frames(0),
-		slotIndex(0),
-		attachmentNames(0) {
-	}
-#endif
-} spAttachmentTimeline;
-
-spAttachmentTimeline* spAttachmentTimeline_create (int framesCount);
-
-/* @param attachmentName May be 0. */
-void spAttachmentTimeline_setFrame (spAttachmentTimeline* self, int frameIndex, float time, const char* attachmentName);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spAttachmentTimeline AttachmentTimeline;
-#define AttachmentTimeline_create(...) spAttachmentTimeline_create(__VA_ARGS__)
-#define AttachmentTimeline_setFrame(...) spAttachmentTimeline_setFrame(__VA_ARGS__)
-#endif
-
-/**/
-
-typedef struct spEventTimeline {
-	spTimeline super;
-	int const framesCount;
-	float* const frames; /* time, ... */
-	spEvent** const events;
-
-#ifdef __cplusplus
-	spEventTimeline() :
-		super(),
-		framesCount(0),
-		frames(0),
-		events(0) {
-	}
-#endif
-} spEventTimeline;
-
-spEventTimeline* spEventTimeline_create (int framesCount);
-
-void spEventTimeline_setFrame (spEventTimeline* self, int frameIndex, spEvent* event);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spEventTimeline EventTimeline;
-#define EventTimeline_create(...) spEventTimeline_create(__VA_ARGS__)
-#define EventTimeline_setFrame(...) spEventTimeline_setFrame(__VA_ARGS__)
-#endif
-
-/**/
-
-typedef struct spDrawOrderTimeline {
-	spTimeline super;
-	int const framesCount;
-	float* const frames; /* time, ... */
-	const int** const drawOrders;
-	int const slotsCount;
-
-#ifdef __cplusplus
-	spDrawOrderTimeline() :
-		super(),
-		framesCount(0),
-		frames(0),
-		drawOrders(0),
-		slotsCount(0) {
-	}
-#endif
-} spDrawOrderTimeline;
-
-spDrawOrderTimeline* spDrawOrderTimeline_create (int framesCount, int slotsCount);
-
-void spDrawOrderTimeline_setFrame (spDrawOrderTimeline* self, int frameIndex, float time, const int* drawOrder);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spDrawOrderTimeline DrawOrderTimeline;
-#define DrawOrderTimeline_create(...) spDrawOrderTimeline_create(__VA_ARGS__)
-#define DrawOrderTimeline_setFrame(...) spDrawOrderTimeline_setFrame(__VA_ARGS__)
-#endif
-
-/**/
-
-typedef struct spDeformTimeline {
-	spCurveTimeline super;
-	int const framesCount;
-	float* const frames; /* time, ... */
-	int const frameVerticesCount;
-	const float** const frameVertices;
-	int slotIndex;
-	spAttachment* attachment;
-
-#ifdef __cplusplus
-	spDeformTimeline() :
-		super(),
-		framesCount(0),
-		frames(0),
-		frameVerticesCount(0),
-		frameVertices(0),
-		slotIndex(0) {
-	}
-#endif
-} spDeformTimeline;
-
-spDeformTimeline* spDeformTimeline_create (int framesCount, int frameVerticesCount);
-
-void spDeformTimeline_setFrame (spDeformTimeline* self, int frameIndex, float time, float* vertices);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spDeformTimeline DeformTimeline;
-#define DeformTimeline_create(...) spDeformTimeline_create(__VA_ARGS__)
-#define DeformTimeline_setFrame(...) spDeformTimeline_setFrame(__VA_ARGS__)
-#endif
-
-/**/
-
-static const int IKCONSTRAINT_ENTRIES = 3;
-
-typedef struct spIkConstraintTimeline {
-	spCurveTimeline super;
-	int const framesCount;
-	float* const frames; /* time, mix, bendDirection, ... */
-	int ikConstraintIndex;
-
-#ifdef __cplusplus
-	spIkConstraintTimeline() :
-		super(),
-		framesCount(0),
-		frames(0),
-		ikConstraintIndex(0) {
-	}
-#endif
-} spIkConstraintTimeline;
-
-spIkConstraintTimeline* spIkConstraintTimeline_create (int framesCount);
-
-void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameIndex, float time, float mix, int bendDirection);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spIkConstraintTimeline IkConstraintTimeline;
-#define IkConstraintTimeline_create(...) spIkConstraintTimeline_create(__VA_ARGS__)
-#define IkConstraintTimeline_setFrame(...) spIkConstraintTimeline_setFrame(__VA_ARGS__)
-#endif
-
-/**/
-
-static const int TRANSFORMCONSTRAINT_ENTRIES = 5;
-
-typedef struct spTransformConstraintTimeline {
-	spCurveTimeline super;
-	int const framesCount;
-	float* const frames; /* time, rotate mix, translate mix, scale mix, shear mix, ... */
-	int transformConstraintIndex;
-
-#ifdef __cplusplus
-	spTransformConstraintTimeline() :
-		super(),
-		framesCount(0),
-		frames(0),
-		transformConstraintIndex(0) {
-	}
-#endif
-} spTransformConstraintTimeline;
-
-spTransformConstraintTimeline* spTransformConstraintTimeline_create (int framesCount);
-
-void spTransformConstraintTimeline_setFrame (spTransformConstraintTimeline* self, int frameIndex, float time, float rotateMix, float translateMix, float scaleMix, float shearMix);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spTransformConstraintTimeline TransformConstraintTimeline;
-#define TransformConstraintTimeline_create(...) spTransformConstraintTimeline_create(__VA_ARGS__)
-#define TransformConstraintTimeline_setFrame(...) spTransformConstraintTimeline_setFrame(__VA_ARGS__)
-#endif
-
-/**/
-
-static const int PATHCONSTRAINTPOSITION_ENTRIES = 2;
-
-typedef struct spPathConstraintPositionTimeline {
-	spCurveTimeline super;
-	int const framesCount;
-	float* const frames; /* time, rotate mix, translate mix, scale mix, shear mix, ... */
-	int pathConstraintIndex;
-
-#ifdef __cplusplus
-	spPathConstraintPositionTimeline() :
-		super(),
-		framesCount(0),
-		frames(0),
-		pathConstraintIndex(0) {
-	}
-#endif
-} spPathConstraintPositionTimeline;
-
-spPathConstraintPositionTimeline* spPathConstraintPositionTimeline_create (int framesCount);
-
-void spPathConstraintPositionTimeline_setFrame (spPathConstraintPositionTimeline* self, int frameIndex, float time, float value);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spPathConstraintPositionTimeline PathConstraintPositionTimeline;
-#define PathConstraintPositionTimeline_create(...) spPathConstraintPositionTimeline_create(__VA_ARGS__)
-#define PathConstraintPositionTimeline_setFrame(...) spPathConstraintPositionTimeline_setFrame(__VA_ARGS__)
-#endif
-
-/**/
-
-static const int PATHCONSTRAINTSPACING_ENTRIES = 2;
-
-typedef struct spPathConstraintSpacingTimeline {
-	spCurveTimeline super;
-	int const framesCount;
-	float* const frames; /* time, rotate mix, translate mix, scale mix, shear mix, ... */
-	int pathConstraintIndex;
-
-#ifdef __cplusplus
-	spPathConstraintSpacingTimeline() :
-		super(),
-		framesCount(0),
-		frames(0),
-		pathConstraintIndex(0) {
-	}
-#endif
-} spPathConstraintSpacingTimeline;
-
-spPathConstraintSpacingTimeline* spPathConstraintSpacingTimeline_create (int framesCount);
-
-void spPathConstraintSpacingTimeline_setFrame (spPathConstraintSpacingTimeline* self, int frameIndex, float time, float value);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spPathConstraintSpacingTimeline PathConstraintSpacingTimeline;
-#define PathConstraintSpacingTimeline_create(...) spPathConstraintSpacingTimeline_create(__VA_ARGS__)
-#define PathConstraintSpacingTimeline_setFrame(...) spPathConstraintSpacingTimeline_setFrame(__VA_ARGS__)
-#endif
-
-/**/
-
-static const int PATHCONSTRAINTMIX_ENTRIES = 3;
-
-typedef struct spPathConstraintMixTimeline {
-	spCurveTimeline super;
-	int const framesCount;
-	float* const frames; /* time, rotate mix, translate mix, scale mix, shear mix, ... */
-	int pathConstraintIndex;
-
-#ifdef __cplusplus
-	spPathConstraintMixTimeline() :
-		super(),
-		framesCount(0),
-		frames(0),
-		pathConstraintIndex(0) {
-	}
-#endif
-} spPathConstraintMixTimeline;
-
-spPathConstraintMixTimeline* spPathConstraintMixTimeline_create (int framesCount);
-
-void spPathConstraintMixTimeline_setFrame (spPathConstraintMixTimeline* self, int frameIndex, float time, float rotateMix, float translateMix);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spPathConstraintMixTimeline PathConstraintMixTimeline;
-#define PathConstraintMixTimeline_create(...) spPathConstraintMixTimeline_create(__VA_ARGS__)
-#define PathConstraintMixTimeline_setFrame(...) spPathConstraintMixTimeline_setFrame(__VA_ARGS__)
-#endif
-
-/**/
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_ANIMATION_H_
+#define SPINE_ANIMATION_H_
+
+#include <spine/Event.h>
+#include <spine/Attachment.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spTimeline spTimeline;
+struct spSkeleton;
+
+typedef struct spAnimation {
+	const char* const name;
+	float duration;
+
+	int timelinesCount;
+	spTimeline** timelines;
+
+#ifdef __cplusplus
+	spAnimation() :
+		name(0),
+		duration(0),
+		timelinesCount(0),
+		timelines(0) {
+	}
+#endif
+} spAnimation;
+
+spAnimation* spAnimation_create (const char* name, int timelinesCount);
+void spAnimation_dispose (spAnimation* self);
+
+/** Poses the skeleton at the specified time for this animation.
+ * @param lastTime The last time the animation was applied.
+ * @param events Any triggered events are added. May be null.*/
+void spAnimation_apply (const spAnimation* self, struct spSkeleton* skeleton, float lastTime, float time, int loop,
+		spEvent** events, int* eventsCount);
+
+/** Poses the skeleton at the specified time for this animation mixed with the current pose.
+ * @param lastTime The last time the animation was applied.
+ * @param events Any triggered events are added. May be null.
+ * @param alpha The amount of this animation that affects the current pose. */
+void spAnimation_mix (const spAnimation* self, struct spSkeleton* skeleton, float lastTime, float time, int loop,
+		spEvent** events, int* eventsCount, float alpha);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spAnimation Animation;
+#define Animation_create(...) spAnimation_create(__VA_ARGS__)
+#define Animation_dispose(...) spAnimation_dispose(__VA_ARGS__)
+#define Animation_apply(...) spAnimation_apply(__VA_ARGS__)
+#define Animation_mix(...) spAnimation_mix(__VA_ARGS__)
+#endif
+
+/**/
+
+typedef enum {
+	SP_TIMELINE_SCALE,
+	SP_TIMELINE_ROTATE,
+	SP_TIMELINE_TRANSLATE,
+	SP_TIMELINE_SHEAR,
+	SP_TIMELINE_COLOR,
+	SP_TIMELINE_ATTACHMENT,
+	SP_TIMELINE_EVENT,
+	SP_TIMELINE_DRAWORDER,
+	SP_TIMELINE_DEFORM,
+	SP_TIMELINE_IKCONSTRAINT,
+	SP_TIMELINE_TRANSFORMCONSTRAINT,
+	SP_TIMELINE_PATHCONSTRAINTPOSITION,
+	SP_TIMELINE_PATHCONSTRAINTSPACING,
+	SP_TIMELINE_PATHCONSTRAINTMIX
+} spTimelineType;
+
+struct spTimeline {
+	const spTimelineType type;
+	const void* const vtable;
+
+#ifdef __cplusplus
+	spTimeline() :
+		type(SP_TIMELINE_SCALE),
+		vtable(0) {
+	}
+#endif
+};
+
+void spTimeline_dispose (spTimeline* self);
+void spTimeline_apply (const spTimeline* self, struct spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
+		int* eventsCount, float alpha);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spTimeline Timeline;
+#define TIMELINE_SCALE SP_TIMELINE_SCALE
+#define TIMELINE_ROTATE SP_TIMELINE_ROTATE
+#define TIMELINE_TRANSLATE SP_TIMELINE_TRANSLATE
+#define TIMELINE_COLOR SP_TIMELINE_COLOR
+#define TIMELINE_ATTACHMENT SP_TIMELINE_ATTACHMENT
+#define TIMELINE_EVENT SP_TIMELINE_EVENT
+#define TIMELINE_DRAWORDER SP_TIMELINE_DRAWORDER
+#define Timeline_dispose(...) spTimeline_dispose(__VA_ARGS__)
+#define Timeline_apply(...) spTimeline_apply(__VA_ARGS__)
+#endif
+
+/**/
+
+typedef struct spCurveTimeline {
+	spTimeline super;
+	float* curves; /* type, x, y, ... */
+
+#ifdef __cplusplus
+	spCurveTimeline() :
+		super(),
+		curves(0) {
+	}
+#endif
+} spCurveTimeline;
+
+void spCurveTimeline_setLinear (spCurveTimeline* self, int frameIndex);
+void spCurveTimeline_setStepped (spCurveTimeline* self, int frameIndex);
+
+/* Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next.
+ * cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of
+ * the difference between the keyframe's values. */
+void spCurveTimeline_setCurve (spCurveTimeline* self, int frameIndex, float cx1, float cy1, float cx2, float cy2);
+float spCurveTimeline_getCurvePercent (const spCurveTimeline* self, int frameIndex, float percent);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spCurveTimeline CurveTimeline;
+#define CurveTimeline_setLinear(...) spCurveTimeline_setLinear(__VA_ARGS__)
+#define CurveTimeline_setStepped(...) spCurveTimeline_setStepped(__VA_ARGS__)
+#define CurveTimeline_setCurve(...) spCurveTimeline_setCurve(__VA_ARGS__)
+#define CurveTimeline_getCurvePercent(...) spCurveTimeline_getCurvePercent(__VA_ARGS__)
+#endif
+
+/**/
+
+typedef struct spBaseTimeline {
+	spCurveTimeline super;
+	int const framesCount;
+	float* const frames; /* time, angle, ... for rotate. time, x, y, ... for translate and scale. */
+	int boneIndex;
+
+#ifdef __cplusplus
+	spBaseTimeline() :
+		super(),
+		framesCount(0),
+		frames(0),
+		boneIndex(0) {
+	}
+#endif
+} spBaseTimeline;
+
+/**/
+
+static const int ROTATE_ENTRIES = 2;
+
+typedef struct spBaseTimeline spRotateTimeline;
+
+spRotateTimeline* spRotateTimeline_create (int framesCount);
+
+void spRotateTimeline_setFrame (spRotateTimeline* self, int frameIndex, float time, float angle);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spRotateTimeline RotateTimeline;
+#define RotateTimeline_create(...) spRotateTimeline_create(__VA_ARGS__)
+#define RotateTimeline_setFrame(...) spRotateTimeline_setFrame(__VA_ARGS__)
+#endif
+
+/**/
+
+static const int TRANSLATE_ENTRIES = 3;
+
+typedef struct spBaseTimeline spTranslateTimeline;
+
+spTranslateTimeline* spTranslateTimeline_create (int framesCount);
+
+void spTranslateTimeline_setFrame (spTranslateTimeline* self, int frameIndex, float time, float x, float y);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spTranslateTimeline TranslateTimeline;
+#define TranslateTimeline_create(...) spTranslateTimeline_create(__VA_ARGS__)
+#define TranslateTimeline_setFrame(...) spTranslateTimeline_setFrame(__VA_ARGS__)
+#endif
+
+/**/
+
+typedef struct spBaseTimeline spScaleTimeline;
+
+spScaleTimeline* spScaleTimeline_create (int framesCount);
+
+void spScaleTimeline_setFrame (spScaleTimeline* self, int frameIndex, float time, float x, float y);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spScaleTimeline ScaleTimeline;
+#define ScaleTimeline_create(...) spScaleTimeline_create(__VA_ARGS__)
+#define ScaleTimeline_setFrame(...) spScaleTimeline_setFrame(__VA_ARGS__)
+#endif
+
+/**/
+
+typedef struct spBaseTimeline spShearTimeline;
+
+spShearTimeline* spShearTimeline_create (int framesCount);
+
+void spShearTimeline_setFrame (spShearTimeline* self, int frameIndex, float time, float x, float y);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spShearTimeline ShearTimeline;
+#define ShearTimeline_create(...) spShearTimeline_create(__VA_ARGS__)
+#define ShearTimeline_setFrame(...) spShearTimeline_setFrame(__VA_ARGS__)
+#endif
+
+/**/
+
+static const int COLOR_ENTRIES = 5;
+
+typedef struct spColorTimeline {
+	spCurveTimeline super;
+	int const framesCount;
+	float* const frames; /* time, r, g, b, a, ... */
+	int slotIndex;
+
+#ifdef __cplusplus
+	spColorTimeline() :
+		super(),
+		framesCount(0),
+		frames(0),
+		slotIndex(0) {
+	}
+#endif
+} spColorTimeline;
+
+spColorTimeline* spColorTimeline_create (int framesCount);
+
+void spColorTimeline_setFrame (spColorTimeline* self, int frameIndex, float time, float r, float g, float b, float a);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spColorTimeline ColorTimeline;
+#define ColorTimeline_create(...) spColorTimeline_create(__VA_ARGS__)
+#define ColorTimeline_setFrame(...) spColorTimeline_setFrame(__VA_ARGS__)
+#endif
+
+/**/
+
+typedef struct spAttachmentTimeline {
+	spTimeline super;
+	int const framesCount;
+	float* const frames; /* time, ... */
+	int slotIndex;
+	const char** const attachmentNames;
+
+#ifdef __cplusplus
+	spAttachmentTimeline() :
+		super(),
+		framesCount(0),
+		frames(0),
+		slotIndex(0),
+		attachmentNames(0) {
+	}
+#endif
+} spAttachmentTimeline;
+
+spAttachmentTimeline* spAttachmentTimeline_create (int framesCount);
+
+/* @param attachmentName May be 0. */
+void spAttachmentTimeline_setFrame (spAttachmentTimeline* self, int frameIndex, float time, const char* attachmentName);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spAttachmentTimeline AttachmentTimeline;
+#define AttachmentTimeline_create(...) spAttachmentTimeline_create(__VA_ARGS__)
+#define AttachmentTimeline_setFrame(...) spAttachmentTimeline_setFrame(__VA_ARGS__)
+#endif
+
+/**/
+
+typedef struct spEventTimeline {
+	spTimeline super;
+	int const framesCount;
+	float* const frames; /* time, ... */
+	spEvent** const events;
+
+#ifdef __cplusplus
+	spEventTimeline() :
+		super(),
+		framesCount(0),
+		frames(0),
+		events(0) {
+	}
+#endif
+} spEventTimeline;
+
+spEventTimeline* spEventTimeline_create (int framesCount);
+
+void spEventTimeline_setFrame (spEventTimeline* self, int frameIndex, spEvent* event);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spEventTimeline EventTimeline;
+#define EventTimeline_create(...) spEventTimeline_create(__VA_ARGS__)
+#define EventTimeline_setFrame(...) spEventTimeline_setFrame(__VA_ARGS__)
+#endif
+
+/**/
+
+typedef struct spDrawOrderTimeline {
+	spTimeline super;
+	int const framesCount;
+	float* const frames; /* time, ... */
+	const int** const drawOrders;
+	int const slotsCount;
+
+#ifdef __cplusplus
+	spDrawOrderTimeline() :
+		super(),
+		framesCount(0),
+		frames(0),
+		drawOrders(0),
+		slotsCount(0) {
+	}
+#endif
+} spDrawOrderTimeline;
+
+spDrawOrderTimeline* spDrawOrderTimeline_create (int framesCount, int slotsCount);
+
+void spDrawOrderTimeline_setFrame (spDrawOrderTimeline* self, int frameIndex, float time, const int* drawOrder);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spDrawOrderTimeline DrawOrderTimeline;
+#define DrawOrderTimeline_create(...) spDrawOrderTimeline_create(__VA_ARGS__)
+#define DrawOrderTimeline_setFrame(...) spDrawOrderTimeline_setFrame(__VA_ARGS__)
+#endif
+
+/**/
+
+typedef struct spDeformTimeline {
+	spCurveTimeline super;
+	int const framesCount;
+	float* const frames; /* time, ... */
+	int const frameVerticesCount;
+	const float** const frameVertices;
+	int slotIndex;
+	spAttachment* attachment;
+
+#ifdef __cplusplus
+	spDeformTimeline() :
+		super(),
+		framesCount(0),
+		frames(0),
+		frameVerticesCount(0),
+		frameVertices(0),
+		slotIndex(0) {
+	}
+#endif
+} spDeformTimeline;
+
+spDeformTimeline* spDeformTimeline_create (int framesCount, int frameVerticesCount);
+
+void spDeformTimeline_setFrame (spDeformTimeline* self, int frameIndex, float time, float* vertices);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spDeformTimeline DeformTimeline;
+#define DeformTimeline_create(...) spDeformTimeline_create(__VA_ARGS__)
+#define DeformTimeline_setFrame(...) spDeformTimeline_setFrame(__VA_ARGS__)
+#endif
+
+/**/
+
+static const int IKCONSTRAINT_ENTRIES = 3;
+
+typedef struct spIkConstraintTimeline {
+	spCurveTimeline super;
+	int const framesCount;
+	float* const frames; /* time, mix, bendDirection, ... */
+	int ikConstraintIndex;
+
+#ifdef __cplusplus
+	spIkConstraintTimeline() :
+		super(),
+		framesCount(0),
+		frames(0),
+		ikConstraintIndex(0) {
+	}
+#endif
+} spIkConstraintTimeline;
+
+spIkConstraintTimeline* spIkConstraintTimeline_create (int framesCount);
+
+void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameIndex, float time, float mix, int bendDirection);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spIkConstraintTimeline IkConstraintTimeline;
+#define IkConstraintTimeline_create(...) spIkConstraintTimeline_create(__VA_ARGS__)
+#define IkConstraintTimeline_setFrame(...) spIkConstraintTimeline_setFrame(__VA_ARGS__)
+#endif
+
+/**/
+
+static const int TRANSFORMCONSTRAINT_ENTRIES = 5;
+
+typedef struct spTransformConstraintTimeline {
+	spCurveTimeline super;
+	int const framesCount;
+	float* const frames; /* time, rotate mix, translate mix, scale mix, shear mix, ... */
+	int transformConstraintIndex;
+
+#ifdef __cplusplus
+	spTransformConstraintTimeline() :
+		super(),
+		framesCount(0),
+		frames(0),
+		transformConstraintIndex(0) {
+	}
+#endif
+} spTransformConstraintTimeline;
+
+spTransformConstraintTimeline* spTransformConstraintTimeline_create (int framesCount);
+
+void spTransformConstraintTimeline_setFrame (spTransformConstraintTimeline* self, int frameIndex, float time, float rotateMix, float translateMix, float scaleMix, float shearMix);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spTransformConstraintTimeline TransformConstraintTimeline;
+#define TransformConstraintTimeline_create(...) spTransformConstraintTimeline_create(__VA_ARGS__)
+#define TransformConstraintTimeline_setFrame(...) spTransformConstraintTimeline_setFrame(__VA_ARGS__)
+#endif
+
+/**/
+
+static const int PATHCONSTRAINTPOSITION_ENTRIES = 2;
+
+typedef struct spPathConstraintPositionTimeline {
+	spCurveTimeline super;
+	int const framesCount;
+	float* const frames; /* time, rotate mix, translate mix, scale mix, shear mix, ... */
+	int pathConstraintIndex;
+
+#ifdef __cplusplus
+	spPathConstraintPositionTimeline() :
+		super(),
+		framesCount(0),
+		frames(0),
+		pathConstraintIndex(0) {
+	}
+#endif
+} spPathConstraintPositionTimeline;
+
+spPathConstraintPositionTimeline* spPathConstraintPositionTimeline_create (int framesCount);
+
+void spPathConstraintPositionTimeline_setFrame (spPathConstraintPositionTimeline* self, int frameIndex, float time, float value);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spPathConstraintPositionTimeline PathConstraintPositionTimeline;
+#define PathConstraintPositionTimeline_create(...) spPathConstraintPositionTimeline_create(__VA_ARGS__)
+#define PathConstraintPositionTimeline_setFrame(...) spPathConstraintPositionTimeline_setFrame(__VA_ARGS__)
+#endif
+
+/**/
+
+static const int PATHCONSTRAINTSPACING_ENTRIES = 2;
+
+typedef struct spPathConstraintSpacingTimeline {
+	spCurveTimeline super;
+	int const framesCount;
+	float* const frames; /* time, rotate mix, translate mix, scale mix, shear mix, ... */
+	int pathConstraintIndex;
+
+#ifdef __cplusplus
+	spPathConstraintSpacingTimeline() :
+		super(),
+		framesCount(0),
+		frames(0),
+		pathConstraintIndex(0) {
+	}
+#endif
+} spPathConstraintSpacingTimeline;
+
+spPathConstraintSpacingTimeline* spPathConstraintSpacingTimeline_create (int framesCount);
+
+void spPathConstraintSpacingTimeline_setFrame (spPathConstraintSpacingTimeline* self, int frameIndex, float time, float value);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spPathConstraintSpacingTimeline PathConstraintSpacingTimeline;
+#define PathConstraintSpacingTimeline_create(...) spPathConstraintSpacingTimeline_create(__VA_ARGS__)
+#define PathConstraintSpacingTimeline_setFrame(...) spPathConstraintSpacingTimeline_setFrame(__VA_ARGS__)
+#endif
+
+/**/
+
+static const int PATHCONSTRAINTMIX_ENTRIES = 3;
+
+typedef struct spPathConstraintMixTimeline {
+	spCurveTimeline super;
+	int const framesCount;
+	float* const frames; /* time, rotate mix, translate mix, scale mix, shear mix, ... */
+	int pathConstraintIndex;
+
+#ifdef __cplusplus
+	spPathConstraintMixTimeline() :
+		super(),
+		framesCount(0),
+		frames(0),
+		pathConstraintIndex(0) {
+	}
+#endif
+} spPathConstraintMixTimeline;
+
+spPathConstraintMixTimeline* spPathConstraintMixTimeline_create (int framesCount);
+
+void spPathConstraintMixTimeline_setFrame (spPathConstraintMixTimeline* self, int frameIndex, float time, float rotateMix, float translateMix);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spPathConstraintMixTimeline PathConstraintMixTimeline;
+#define PathConstraintMixTimeline_create(...) spPathConstraintMixTimeline_create(__VA_ARGS__)
+#define PathConstraintMixTimeline_setFrame(...) spPathConstraintMixTimeline_setFrame(__VA_ARGS__)
+#endif
+
+/**/
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_ANIMATION_H_ */

+ 148 - 149
spine-c/include/spine/AnimationState.h

@@ -1,152 +1,151 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_ANIMATIONSTATE_H_
-#define SPINE_ANIMATIONSTATE_H_
-
-#include <spine/Animation.h>
-#include <spine/AnimationStateData.h>
-#include <spine/Event.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
-	SP_ANIMATION_START, SP_ANIMATION_END, SP_ANIMATION_COMPLETE, SP_ANIMATION_EVENT
-} spEventType;
-
-typedef struct spAnimationState spAnimationState;
-
-typedef void (*spAnimationStateListener) (spAnimationState* state, int trackIndex, spEventType type, spEvent* event,
-		int loopCount);
-
-typedef struct spTrackEntry spTrackEntry;
-struct spTrackEntry {
-	spAnimationState* const state;
-	spTrackEntry* next;
-	spTrackEntry* previous;
-	spAnimation* animation;
-	int/*bool*/loop;
-	float delay, time, lastTime, endTime, timeScale;
-	spAnimationStateListener listener;
-	float mixTime, mixDuration, mix;
-
-	void* rendererObject;
-
-#ifdef __cplusplus
-	spTrackEntry() :
-		state(0),
-		next(0),
-		previous(0),
-		animation(0),
-		loop(0),
-		delay(0), time(0), lastTime(0), endTime(0), timeScale(0),
-		listener(0),
-		mixTime(0), mixDuration(0), mix(0),
-		rendererObject(0) {
-	}
-#endif
-};
-
-struct spAnimationState {
-	spAnimationStateData* const data;
-	float timeScale;
-	spAnimationStateListener listener;
-
-	int tracksCount;
-	spTrackEntry** tracks;
-
-	void* rendererObject;
-
-#ifdef __cplusplus
-	spAnimationState() :
-		data(0),
-		timeScale(0),
-		listener(0),
-		tracksCount(0),
-		tracks(0),
-		rendererObject(0) {
-	}
-#endif
-};
-
-/* @param data May be 0 for no mixing. */
-spAnimationState* spAnimationState_create (spAnimationStateData* data);
-void spAnimationState_dispose (spAnimationState* self);
-
-void spAnimationState_update (spAnimationState* self, float delta);
-void spAnimationState_apply (spAnimationState* self, struct spSkeleton* skeleton);
-
-void spAnimationState_clearTracks (spAnimationState* self);
-void spAnimationState_clearTrack (spAnimationState* self, int trackIndex);
-
-/** Set the current animation. Any queued animations are cleared. */
-spTrackEntry* spAnimationState_setAnimationByName (spAnimationState* self, int trackIndex, const char* animationName,
-		int/*bool*/loop);
-spTrackEntry* spAnimationState_setAnimation (spAnimationState* self, int trackIndex, spAnimation* animation, int/*bool*/loop);
-
-/** Adds an animation to be played delay seconds after the current or last queued animation, taking into account any mix
- * duration. */
-spTrackEntry* spAnimationState_addAnimationByName (spAnimationState* self, int trackIndex, const char* animationName,
-		int/*bool*/loop, float delay);
-spTrackEntry* spAnimationState_addAnimation (spAnimationState* self, int trackIndex, spAnimation* animation, int/*bool*/loop,
-		float delay);
-
-spTrackEntry* spAnimationState_getCurrent (spAnimationState* self, int trackIndex);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spEventType EventType;
-#define ANIMATION_START SP_ANIMATION_START
-#define ANIMATION_END SP_ANIMATION_END
-#define ANIMATION_COMPLETE SP_ANIMATION_COMPLETE
-#define ANIMATION_EVENT SP_ANIMATION_EVENT
-typedef spAnimationStateListener AnimationStateListener;
-typedef spTrackEntry TrackEntry;
-typedef spAnimationState AnimationState;
-#define AnimationState_create(...) spAnimationState_create(__VA_ARGS__)
-#define AnimationState_dispose(...) spAnimationState_dispose(__VA_ARGS__)
-#define AnimationState_update(...) spAnimationState_update(__VA_ARGS__)
-#define AnimationState_apply(...) spAnimationState_apply(__VA_ARGS__)
-#define AnimationState_clearTracks(...) spAnimationState_clearTracks(__VA_ARGS__)
-#define AnimationState_clearTrack(...) spAnimationState_clearTrack(__VA_ARGS__)
-#define AnimationState_setAnimationByName(...) spAnimationState_setAnimationByName(__VA_ARGS__)
-#define AnimationState_setAnimation(...) spAnimationState_setAnimation(__VA_ARGS__)
-#define AnimationState_addAnimationByName(...) spAnimationState_addAnimationByName(__VA_ARGS__)
-#define AnimationState_addAnimation(...) spAnimationState_addAnimation(__VA_ARGS__)
-#define AnimationState_getCurrent(...) spAnimationState_getCurrent(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_ANIMATIONSTATE_H_
+#define SPINE_ANIMATIONSTATE_H_
+
+#include <spine/Animation.h>
+#include <spine/AnimationStateData.h>
+#include <spine/Event.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+	SP_ANIMATION_START, SP_ANIMATION_END, SP_ANIMATION_COMPLETE, SP_ANIMATION_EVENT
+} spEventType;
+
+typedef struct spAnimationState spAnimationState;
+
+typedef void (*spAnimationStateListener) (spAnimationState* state, int trackIndex, spEventType type, spEvent* event,
+		int loopCount);
+
+typedef struct spTrackEntry spTrackEntry;
+struct spTrackEntry {
+	spAnimationState* const state;
+	spTrackEntry* next;
+	spTrackEntry* previous;
+	spAnimation* animation;
+	int/*bool*/loop;
+	float delay, time, lastTime, endTime, timeScale;
+	spAnimationStateListener listener;
+	float mixTime, mixDuration, mix;
+
+	void* rendererObject;
+
+#ifdef __cplusplus
+	spTrackEntry() :
+		state(0),
+		next(0),
+		previous(0),
+		animation(0),
+		loop(0),
+		delay(0), time(0), lastTime(0), endTime(0), timeScale(0),
+		listener(0),
+		mixTime(0), mixDuration(0), mix(0),
+		rendererObject(0) {
+	}
+#endif
+};
+
+struct spAnimationState {
+	spAnimationStateData* const data;
+	float timeScale;
+	spAnimationStateListener listener;
+
+	int tracksCount;
+	spTrackEntry** tracks;
+
+	void* rendererObject;
+
+#ifdef __cplusplus
+	spAnimationState() :
+		data(0),
+		timeScale(0),
+		listener(0),
+		tracksCount(0),
+		tracks(0),
+		rendererObject(0) {
+	}
+#endif
+};
+
+/* @param data May be 0 for no mixing. */
+spAnimationState* spAnimationState_create (spAnimationStateData* data);
+void spAnimationState_dispose (spAnimationState* self);
+
+void spAnimationState_update (spAnimationState* self, float delta);
+void spAnimationState_apply (spAnimationState* self, struct spSkeleton* skeleton);
+
+void spAnimationState_clearTracks (spAnimationState* self);
+void spAnimationState_clearTrack (spAnimationState* self, int trackIndex);
+
+/** Set the current animation. Any queued animations are cleared. */
+spTrackEntry* spAnimationState_setAnimationByName (spAnimationState* self, int trackIndex, const char* animationName,
+		int/*bool*/loop);
+spTrackEntry* spAnimationState_setAnimation (spAnimationState* self, int trackIndex, spAnimation* animation, int/*bool*/loop);
+
+/** Adds an animation to be played delay seconds after the current or last queued animation, taking into account any mix
+ * duration. */
+spTrackEntry* spAnimationState_addAnimationByName (spAnimationState* self, int trackIndex, const char* animationName,
+		int/*bool*/loop, float delay);
+spTrackEntry* spAnimationState_addAnimation (spAnimationState* self, int trackIndex, spAnimation* animation, int/*bool*/loop,
+		float delay);
+
+spTrackEntry* spAnimationState_getCurrent (spAnimationState* self, int trackIndex);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spEventType EventType;
+#define ANIMATION_START SP_ANIMATION_START
+#define ANIMATION_END SP_ANIMATION_END
+#define ANIMATION_COMPLETE SP_ANIMATION_COMPLETE
+#define ANIMATION_EVENT SP_ANIMATION_EVENT
+typedef spAnimationStateListener AnimationStateListener;
+typedef spTrackEntry TrackEntry;
+typedef spAnimationState AnimationState;
+#define AnimationState_create(...) spAnimationState_create(__VA_ARGS__)
+#define AnimationState_dispose(...) spAnimationState_dispose(__VA_ARGS__)
+#define AnimationState_update(...) spAnimationState_update(__VA_ARGS__)
+#define AnimationState_apply(...) spAnimationState_apply(__VA_ARGS__)
+#define AnimationState_clearTracks(...) spAnimationState_clearTracks(__VA_ARGS__)
+#define AnimationState_clearTrack(...) spAnimationState_clearTrack(__VA_ARGS__)
+#define AnimationState_setAnimationByName(...) spAnimationState_setAnimationByName(__VA_ARGS__)
+#define AnimationState_setAnimation(...) spAnimationState_setAnimation(__VA_ARGS__)
+#define AnimationState_addAnimationByName(...) spAnimationState_addAnimationByName(__VA_ARGS__)
+#define AnimationState_addAnimation(...) spAnimationState_addAnimation(__VA_ARGS__)
+#define AnimationState_getCurrent(...) spAnimationState_getCurrent(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_ANIMATIONSTATE_H_ */

+ 73 - 74
spine-c/include/spine/AnimationStateData.h

@@ -1,77 +1,76 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_ANIMATIONSTATEDATA_H_
-#define SPINE_ANIMATIONSTATEDATA_H_
-
-#include <spine/Animation.h>
-#include <spine/SkeletonData.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spAnimationStateData {
-	spSkeletonData* const skeletonData;
-	float defaultMix;
-	const void* const entries;
-
-#ifdef __cplusplus
-	spAnimationStateData() :
-		skeletonData(0),
-		defaultMix(0),
-		entries(0) {
-	}
-#endif
-} spAnimationStateData;
-
-spAnimationStateData* spAnimationStateData_create (spSkeletonData* skeletonData);
-void spAnimationStateData_dispose (spAnimationStateData* self);
-
-void spAnimationStateData_setMixByName (spAnimationStateData* self, const char* fromName, const char* toName, float duration);
-void spAnimationStateData_setMix (spAnimationStateData* self, spAnimation* from, spAnimation* to, float duration);
-/* Returns 0 if there is no mixing between the animations. */
-float spAnimationStateData_getMix (spAnimationStateData* self, spAnimation* from, spAnimation* to);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spAnimationStateData AnimationStateData;
-#define AnimationStateData_create(...) spAnimationStateData_create(__VA_ARGS__)
-#define AnimationStateData_dispose(...) spAnimationStateData_dispose(__VA_ARGS__)
-#define AnimationStateData_setMixByName(...) spAnimationStateData_setMixByName(__VA_ARGS__)
-#define AnimationStateData_setMix(...) spAnimationStateData_setMix(__VA_ARGS__)
-#define AnimationStateData_getMix(...) spAnimationStateData_getMix(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_ANIMATIONSTATEDATA_H_
+#define SPINE_ANIMATIONSTATEDATA_H_
+
+#include <spine/Animation.h>
+#include <spine/SkeletonData.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spAnimationStateData {
+	spSkeletonData* const skeletonData;
+	float defaultMix;
+	const void* const entries;
+
+#ifdef __cplusplus
+	spAnimationStateData() :
+		skeletonData(0),
+		defaultMix(0),
+		entries(0) {
+	}
+#endif
+} spAnimationStateData;
+
+spAnimationStateData* spAnimationStateData_create (spSkeletonData* skeletonData);
+void spAnimationStateData_dispose (spAnimationStateData* self);
+
+void spAnimationStateData_setMixByName (spAnimationStateData* self, const char* fromName, const char* toName, float duration);
+void spAnimationStateData_setMix (spAnimationStateData* self, spAnimation* from, spAnimation* to, float duration);
+/* Returns 0 if there is no mixing between the animations. */
+float spAnimationStateData_getMix (spAnimationStateData* self, spAnimation* from, spAnimation* to);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spAnimationStateData AnimationStateData;
+#define AnimationStateData_create(...) spAnimationStateData_create(__VA_ARGS__)
+#define AnimationStateData_dispose(...) spAnimationStateData_dispose(__VA_ARGS__)
+#define AnimationStateData_setMixByName(...) spAnimationStateData_setMixByName(__VA_ARGS__)
+#define AnimationStateData_setMix(...) spAnimationStateData_setMix(__VA_ARGS__)
+#define AnimationStateData_getMix(...) spAnimationStateData_getMix(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_ANIMATIONSTATEDATA_H_ */

+ 169 - 170
spine-c/include/spine/Atlas.h

@@ -1,173 +1,172 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_ATLAS_H_
-#define SPINE_ATLAS_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spAtlas spAtlas;
-
-typedef enum {
-	SP_ATLAS_UNKNOWN_FORMAT,
-	SP_ATLAS_ALPHA,
-	SP_ATLAS_INTENSITY,
-	SP_ATLAS_LUMINANCE_ALPHA,
-	SP_ATLAS_RGB565,
-	SP_ATLAS_RGBA4444,
-	SP_ATLAS_RGB888,
-	SP_ATLAS_RGBA8888
-} spAtlasFormat;
-
-typedef enum {
-	SP_ATLAS_UNKNOWN_FILTER,
-	SP_ATLAS_NEAREST,
-	SP_ATLAS_LINEAR,
-	SP_ATLAS_MIPMAP,
-	SP_ATLAS_MIPMAP_NEAREST_NEAREST,
-	SP_ATLAS_MIPMAP_LINEAR_NEAREST,
-	SP_ATLAS_MIPMAP_NEAREST_LINEAR,
-	SP_ATLAS_MIPMAP_LINEAR_LINEAR
-} spAtlasFilter;
-
-typedef enum {
-	SP_ATLAS_MIRROREDREPEAT,
-	SP_ATLAS_CLAMPTOEDGE,
-	SP_ATLAS_REPEAT
-} spAtlasWrap;
-
-typedef struct spAtlasPage spAtlasPage;
-struct spAtlasPage {
-	const spAtlas* atlas;
-	const char* name;
-	spAtlasFormat format;
-	spAtlasFilter minFilter, magFilter;
-	spAtlasWrap uWrap, vWrap;
-
-	void* rendererObject;
-	int width, height;
-
-	spAtlasPage* next;
-};
-
-spAtlasPage* spAtlasPage_create (spAtlas* atlas, const char* name);
-void spAtlasPage_dispose (spAtlasPage* self);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spAtlasFormat AtlasFormat;
-#define ATLAS_UNKNOWN_FORMAT SP_ATLAS_UNKNOWN_FORMAT
-#define ATLAS_ALPHA SP_ATLAS_ALPHA
-#define ATLAS_INTENSITY SP_ATLAS_INTENSITY
-#define ATLAS_LUMINANCE_ALPHA SP_ATLAS_LUMINANCE_ALPHA
-#define ATLAS_RGB565 SP_ATLAS_RGB565
-#define ATLAS_RGBA4444 SP_ATLAS_RGBA4444
-#define ATLAS_RGB888 SP_ATLAS_RGB888
-#define ATLAS_RGBA8888 SP_ATLAS_RGBA8888
-typedef spAtlasFilter AtlasFilter;
-#define ATLAS_UNKNOWN_FILTER SP_ATLAS_UNKNOWN_FILTER
-#define ATLAS_NEAREST SP_ATLAS_NEAREST
-#define ATLAS_LINEAR SP_ATLAS_LINEAR
-#define ATLAS_MIPMAP SP_ATLAS_MIPMAP
-#define ATLAS_MIPMAP_NEAREST_NEAREST SP_ATLAS_MIPMAP_NEAREST_NEAREST
-#define ATLAS_MIPMAP_LINEAR_NEAREST SP_ATLAS_MIPMAP_LINEAR_NEAREST
-#define ATLAS_MIPMAP_NEAREST_LINEAR SP_ATLAS_MIPMAP_NEAREST_LINEAR
-#define ATLAS_MIPMAP_LINEAR_LINEAR SP_ATLAS_MIPMAP_LINEAR_LINEAR
-typedef spAtlasWrap AtlasWrap;
-#define ATLAS_MIRROREDREPEAT SP_ATLAS_MIRROREDREPEAT
-#define ATLAS_CLAMPTOEDGE SP_ATLAS_CLAMPTOEDGE
-#define ATLAS_REPEAT SP_ATLAS_REPEAT
-typedef spAtlasPage AtlasPage;
-#define AtlasPage_create(...) spAtlasPage_create(__VA_ARGS__)
-#define AtlasPage_dispose(...) spAtlasPage_dispose(__VA_ARGS__)
-#endif
-
-/**/
-
-typedef struct spAtlasRegion spAtlasRegion;
-struct spAtlasRegion {
-	const char* name;
-	int x, y, width, height;
-	float u, v, u2, v2;
-	int offsetX, offsetY;
-	int originalWidth, originalHeight;
-	int index;
-	int/*bool*/rotate;
-	int/*bool*/flip;
-	int* splits;
-	int* pads;
-
-	spAtlasPage* page;
-
-	spAtlasRegion* next;
-};
-
-spAtlasRegion* spAtlasRegion_create ();
-void spAtlasRegion_dispose (spAtlasRegion* self);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spAtlasRegion AtlasRegion;
-#define AtlasRegion_create(...) spAtlasRegion_create(__VA_ARGS__)
-#define AtlasRegion_dispose(...) spAtlasRegion_dispose(__VA_ARGS__)
-#endif
-
-/**/
-
-struct spAtlas {
-	spAtlasPage* pages;
-	spAtlasRegion* regions;
-
-	void* rendererObject;
-};
-
-/* Image files referenced in the atlas file will be prefixed with dir. */
-spAtlas* spAtlas_create (const char* data, int length, const char* dir, void* rendererObject);
-/* Image files referenced in the atlas file will be prefixed with the directory containing the atlas file. */
-spAtlas* spAtlas_createFromFile (const char* path, void* rendererObject);
-void spAtlas_dispose (spAtlas* atlas);
-
-/* Returns 0 if the region was not found. */
-spAtlasRegion* spAtlas_findRegion (const spAtlas* self, const char* name);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spAtlas Atlas;
-#define Atlas_create(...) spAtlas_create(__VA_ARGS__)
-#define Atlas_createFromFile(...) spAtlas_createFromFile(__VA_ARGS__)
-#define Atlas_dispose(...) spAtlas_dispose(__VA_ARGS__)
-#define Atlas_findRegion(...) spAtlas_findRegion(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_ATLAS_H_
+#define SPINE_ATLAS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spAtlas spAtlas;
+
+typedef enum {
+	SP_ATLAS_UNKNOWN_FORMAT,
+	SP_ATLAS_ALPHA,
+	SP_ATLAS_INTENSITY,
+	SP_ATLAS_LUMINANCE_ALPHA,
+	SP_ATLAS_RGB565,
+	SP_ATLAS_RGBA4444,
+	SP_ATLAS_RGB888,
+	SP_ATLAS_RGBA8888
+} spAtlasFormat;
+
+typedef enum {
+	SP_ATLAS_UNKNOWN_FILTER,
+	SP_ATLAS_NEAREST,
+	SP_ATLAS_LINEAR,
+	SP_ATLAS_MIPMAP,
+	SP_ATLAS_MIPMAP_NEAREST_NEAREST,
+	SP_ATLAS_MIPMAP_LINEAR_NEAREST,
+	SP_ATLAS_MIPMAP_NEAREST_LINEAR,
+	SP_ATLAS_MIPMAP_LINEAR_LINEAR
+} spAtlasFilter;
+
+typedef enum {
+	SP_ATLAS_MIRROREDREPEAT,
+	SP_ATLAS_CLAMPTOEDGE,
+	SP_ATLAS_REPEAT
+} spAtlasWrap;
+
+typedef struct spAtlasPage spAtlasPage;
+struct spAtlasPage {
+	const spAtlas* atlas;
+	const char* name;
+	spAtlasFormat format;
+	spAtlasFilter minFilter, magFilter;
+	spAtlasWrap uWrap, vWrap;
+
+	void* rendererObject;
+	int width, height;
+
+	spAtlasPage* next;
+};
+
+spAtlasPage* spAtlasPage_create (spAtlas* atlas, const char* name);
+void spAtlasPage_dispose (spAtlasPage* self);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spAtlasFormat AtlasFormat;
+#define ATLAS_UNKNOWN_FORMAT SP_ATLAS_UNKNOWN_FORMAT
+#define ATLAS_ALPHA SP_ATLAS_ALPHA
+#define ATLAS_INTENSITY SP_ATLAS_INTENSITY
+#define ATLAS_LUMINANCE_ALPHA SP_ATLAS_LUMINANCE_ALPHA
+#define ATLAS_RGB565 SP_ATLAS_RGB565
+#define ATLAS_RGBA4444 SP_ATLAS_RGBA4444
+#define ATLAS_RGB888 SP_ATLAS_RGB888
+#define ATLAS_RGBA8888 SP_ATLAS_RGBA8888
+typedef spAtlasFilter AtlasFilter;
+#define ATLAS_UNKNOWN_FILTER SP_ATLAS_UNKNOWN_FILTER
+#define ATLAS_NEAREST SP_ATLAS_NEAREST
+#define ATLAS_LINEAR SP_ATLAS_LINEAR
+#define ATLAS_MIPMAP SP_ATLAS_MIPMAP
+#define ATLAS_MIPMAP_NEAREST_NEAREST SP_ATLAS_MIPMAP_NEAREST_NEAREST
+#define ATLAS_MIPMAP_LINEAR_NEAREST SP_ATLAS_MIPMAP_LINEAR_NEAREST
+#define ATLAS_MIPMAP_NEAREST_LINEAR SP_ATLAS_MIPMAP_NEAREST_LINEAR
+#define ATLAS_MIPMAP_LINEAR_LINEAR SP_ATLAS_MIPMAP_LINEAR_LINEAR
+typedef spAtlasWrap AtlasWrap;
+#define ATLAS_MIRROREDREPEAT SP_ATLAS_MIRROREDREPEAT
+#define ATLAS_CLAMPTOEDGE SP_ATLAS_CLAMPTOEDGE
+#define ATLAS_REPEAT SP_ATLAS_REPEAT
+typedef spAtlasPage AtlasPage;
+#define AtlasPage_create(...) spAtlasPage_create(__VA_ARGS__)
+#define AtlasPage_dispose(...) spAtlasPage_dispose(__VA_ARGS__)
+#endif
+
+/**/
+
+typedef struct spAtlasRegion spAtlasRegion;
+struct spAtlasRegion {
+	const char* name;
+	int x, y, width, height;
+	float u, v, u2, v2;
+	int offsetX, offsetY;
+	int originalWidth, originalHeight;
+	int index;
+	int/*bool*/rotate;
+	int/*bool*/flip;
+	int* splits;
+	int* pads;
+
+	spAtlasPage* page;
+
+	spAtlasRegion* next;
+};
+
+spAtlasRegion* spAtlasRegion_create ();
+void spAtlasRegion_dispose (spAtlasRegion* self);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spAtlasRegion AtlasRegion;
+#define AtlasRegion_create(...) spAtlasRegion_create(__VA_ARGS__)
+#define AtlasRegion_dispose(...) spAtlasRegion_dispose(__VA_ARGS__)
+#endif
+
+/**/
+
+struct spAtlas {
+	spAtlasPage* pages;
+	spAtlasRegion* regions;
+
+	void* rendererObject;
+};
+
+/* Image files referenced in the atlas file will be prefixed with dir. */
+spAtlas* spAtlas_create (const char* data, int length, const char* dir, void* rendererObject);
+/* Image files referenced in the atlas file will be prefixed with the directory containing the atlas file. */
+spAtlas* spAtlas_createFromFile (const char* path, void* rendererObject);
+void spAtlas_dispose (spAtlas* atlas);
+
+/* Returns 0 if the region was not found. */
+spAtlasRegion* spAtlas_findRegion (const spAtlas* self, const char* name);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spAtlas Atlas;
+#define Atlas_create(...) spAtlas_create(__VA_ARGS__)
+#define Atlas_createFromFile(...) spAtlas_createFromFile(__VA_ARGS__)
+#define Atlas_dispose(...) spAtlas_dispose(__VA_ARGS__)
+#define Atlas_findRegion(...) spAtlas_findRegion(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_ATLAS_H_ */

+ 54 - 55
spine-c/include/spine/AtlasAttachmentLoader.h

@@ -1,58 +1,57 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_ATLASATTACHMENTLOADER_H_
-#define SPINE_ATLASATTACHMENTLOADER_H_
-
-#include <spine/AttachmentLoader.h>
-#include <spine/Atlas.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spAtlasAttachmentLoader {
-	spAttachmentLoader super;
-	spAtlas* atlas;
-} spAtlasAttachmentLoader;
-
-spAtlasAttachmentLoader* spAtlasAttachmentLoader_create (spAtlas* atlas);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spAtlasAttachmentLoader AtlasAttachmentLoader;
-#define AtlasAttachmentLoader_create(...) spAtlasAttachmentLoader_create(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_ATLASATTACHMENTLOADER_H_
+#define SPINE_ATLASATTACHMENTLOADER_H_
+
+#include <spine/AttachmentLoader.h>
+#include <spine/Atlas.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spAtlasAttachmentLoader {
+	spAttachmentLoader super;
+	spAtlas* atlas;
+} spAtlasAttachmentLoader;
+
+spAtlasAttachmentLoader* spAtlasAttachmentLoader_create (spAtlas* atlas);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spAtlasAttachmentLoader AtlasAttachmentLoader;
+#define AtlasAttachmentLoader_create(...) spAtlasAttachmentLoader_create(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_ATLASATTACHMENTLOADER_H_ */

+ 76 - 77
spine-c/include/spine/Attachment.h

@@ -1,80 +1,79 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_ATTACHMENT_H_
-#define SPINE_ATTACHMENT_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct spAttachmentLoader;
-
-typedef enum {
-	SP_ATTACHMENT_REGION,
-	SP_ATTACHMENT_BOUNDING_BOX,
-	SP_ATTACHMENT_MESH,
-	SP_ATTACHMENT_LINKED_MESH,
-	SP_ATTACHMENT_PATH
-} spAttachmentType;
-
-typedef struct spAttachment {
-	const char* const name;
-	const spAttachmentType type;
-	const void* const vtable;
-	struct spAttachmentLoader* attachmentLoader;
-
-#ifdef __cplusplus
-	spAttachment() :
-		name(0),
-		type(SP_ATTACHMENT_REGION),
-		vtable(0) {
-	}
-#endif
-} spAttachment;
-
-void spAttachment_dispose (spAttachment* self);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spAttachmentType AttachmentType;
-#define ATTACHMENT_REGION SP_ATTACHMENT_REGION
-#define ATTACHMENT_BOUNDING_BOX SP_ATTACHMENT_BOUNDING_BOX
-#define ATTACHMENT_MESH SP_ATTACHMENT_MESH
-#define ATTACHMENT_LINKED_MESH SP_ATTACHMENT_LINKED_MESH
-typedef spAttachment Attachment;
-#define Attachment_dispose(...) spAttachment_dispose(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_ATTACHMENT_H_
+#define SPINE_ATTACHMENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct spAttachmentLoader;
+
+typedef enum {
+	SP_ATTACHMENT_REGION,
+	SP_ATTACHMENT_BOUNDING_BOX,
+	SP_ATTACHMENT_MESH,
+	SP_ATTACHMENT_LINKED_MESH,
+	SP_ATTACHMENT_PATH
+} spAttachmentType;
+
+typedef struct spAttachment {
+	const char* const name;
+	const spAttachmentType type;
+	const void* const vtable;
+	struct spAttachmentLoader* attachmentLoader;
+
+#ifdef __cplusplus
+	spAttachment() :
+		name(0),
+		type(SP_ATTACHMENT_REGION),
+		vtable(0) {
+	}
+#endif
+} spAttachment;
+
+void spAttachment_dispose (spAttachment* self);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spAttachmentType AttachmentType;
+#define ATTACHMENT_REGION SP_ATTACHMENT_REGION
+#define ATTACHMENT_BOUNDING_BOX SP_ATTACHMENT_BOUNDING_BOX
+#define ATTACHMENT_MESH SP_ATTACHMENT_MESH
+#define ATTACHMENT_LINKED_MESH SP_ATTACHMENT_LINKED_MESH
+typedef spAttachment Attachment;
+#define Attachment_dispose(...) spAttachment_dispose(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_ATTACHMENT_H_ */

+ 75 - 76
spine-c/include/spine/AttachmentLoader.h

@@ -1,79 +1,78 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_ATTACHMENTLOADER_H_
-#define SPINE_ATTACHMENTLOADER_H_
-
-#include <spine/Attachment.h>
-#include <spine/Skin.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spAttachmentLoader {
-	const char* error1;
-	const char* error2;
-
-	const void* const vtable;
-#ifdef __cplusplus
-	spAttachmentLoader () :
-					error1(0),
-					error2(0),
-					vtable(0) {
-	}
-#endif
-} spAttachmentLoader;
-
-void spAttachmentLoader_dispose (spAttachmentLoader* self);
-
-/* Called to create each attachment. Returns 0 to not load an attachment. If 0 is returned and _spAttachmentLoader_setError was
- * called, an error occurred. */
-spAttachment* spAttachmentLoader_createAttachment (spAttachmentLoader* self, spSkin* skin, spAttachmentType type, const char* name,
-		const char* path);
-/* Called after the attachment has been fully configured. */
-void spAttachmentLoader_configureAttachment (spAttachmentLoader* self, spAttachment* attachment);
-/* Called just before the attachment is disposed. This can release allocations made in spAttachmentLoader_configureAttachment. */
-void spAttachmentLoader_disposeAttachment (spAttachmentLoader* self, spAttachment* attachment);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spAttachmentLoader AttachmentLoader;
-#define AttachmentLoader_dispose(...) spAttachmentLoader_dispose(__VA_ARGS__)
-#define AttachmentLoader_createAttachment(...) spAttachmentLoader_createAttachment(__VA_ARGS__)
-#define AttachmentLoader_configureAttachment(...) spAttachmentLoader_configureAttachment(__VA_ARGS__)
-#define AttachmentLoader_disposeAttachment(...) spAttachmentLoader_disposeAttachment(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_ATTACHMENTLOADER_H_
+#define SPINE_ATTACHMENTLOADER_H_
+
+#include <spine/Attachment.h>
+#include <spine/Skin.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spAttachmentLoader {
+	const char* error1;
+	const char* error2;
+
+	const void* const vtable;
+#ifdef __cplusplus
+	spAttachmentLoader () :
+					error1(0),
+					error2(0),
+					vtable(0) {
+	}
+#endif
+} spAttachmentLoader;
+
+void spAttachmentLoader_dispose (spAttachmentLoader* self);
+
+/* Called to create each attachment. Returns 0 to not load an attachment. If 0 is returned and _spAttachmentLoader_setError was
+ * called, an error occurred. */
+spAttachment* spAttachmentLoader_createAttachment (spAttachmentLoader* self, spSkin* skin, spAttachmentType type, const char* name,
+		const char* path);
+/* Called after the attachment has been fully configured. */
+void spAttachmentLoader_configureAttachment (spAttachmentLoader* self, spAttachment* attachment);
+/* Called just before the attachment is disposed. This can release allocations made in spAttachmentLoader_configureAttachment. */
+void spAttachmentLoader_disposeAttachment (spAttachmentLoader* self, spAttachment* attachment);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spAttachmentLoader AttachmentLoader;
+#define AttachmentLoader_dispose(...) spAttachmentLoader_dispose(__VA_ARGS__)
+#define AttachmentLoader_createAttachment(...) spAttachmentLoader_createAttachment(__VA_ARGS__)
+#define AttachmentLoader_configureAttachment(...) spAttachmentLoader_configureAttachment(__VA_ARGS__)
+#define AttachmentLoader_disposeAttachment(...) spAttachmentLoader_disposeAttachment(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_ATTACHMENTLOADER_H_ */

+ 123 - 124
spine-c/include/spine/Bone.h

@@ -1,127 +1,126 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_BONE_H_
-#define SPINE_BONE_H_
-
-#include <spine/BoneData.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct spSkeleton;
-
-typedef struct spBone spBone;
-struct spBone {
-	spBoneData* const data;
-	struct spSkeleton* const skeleton;
-	spBone* const parent;
-	int childrenCount;
-	spBone** const children;
-	float x, y, rotation, scaleX, scaleY, shearX, shearY;
-	float appliedRotation;
-
-	float const a, b, worldX;
-	float const c, d, worldY;
-	float const worldSignX, worldSignY;
-
-	int/*bool*/ sorted;
-
-#ifdef __cplusplus
-	spBone() :
-		data(0),
-		skeleton(0),
-		parent(0),
-		childrenCount(0), children(0),
-		x(0), y(0), rotation(0), scaleX(0), scaleY(0),
-		appliedRotation(0),
-
-		a(0), b(0), worldX(0),
-		c(0), d(0), worldY(0),
-		worldSignX(0), worldSignY(0),
-		
-		sorted(0) {
-	}
-#endif
-};
-
-void spBone_setYDown (int/*bool*/yDown);
-int/*bool*/spBone_isYDown ();
-
-/* @param parent May be 0. */
-spBone* spBone_create (spBoneData* data, struct spSkeleton* skeleton, spBone* parent);
-void spBone_dispose (spBone* self);
-
-void spBone_setToSetupPose (spBone* self);
-
-void spBone_updateWorldTransform (spBone* self);
-void spBone_updateWorldTransformWith (spBone* self, float x, float y, float rotation, float scaleX, float scaleY, float shearX, float shearY);
-
-float spBone_getWorldRotationX (spBone* self);
-float spBone_getWorldRotationY (spBone* self);
-float spBone_getWorldScaleX (spBone* self);
-float spBone_getWorldScaleY (spBone* self);
-
-float spBone_worldToLocalRotationX (spBone* self);
-float spBone_worldToLocalRotationY (spBone* self);
-void spBone_rotateWorld (spBone* self, float degrees);
-void spBone_updateLocalTransform (spBone* self);
-
-void spBone_worldToLocal (spBone* self, float worldX, float worldY, float* localX, float* localY);
-void spBone_localToWorld (spBone* self, float localX, float localY, float* worldX, float* worldY);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spBone Bone;
-#define Bone_setYDown(...) spBone_setYDown(__VA_ARGS__)
-#define Bone_isYDown() spBone_isYDown()
-#define Bone_create(...) spBone_create(__VA_ARGS__)
-#define Bone_dispose(...) spBone_dispose(__VA_ARGS__)
-#define Bone_setToSetupPose(...) spBone_setToSetupPose(__VA_ARGS__)
-#define Bone_updateWorldTransform(...) spBone_updateWorldTransform(__VA_ARGS__)
-#define Bone_updateWorldTransformWith(...) spBone_updateWorldTransformWith(__VA_ARGS__)
-#define Bone_getWorldRotationX(...) spBone_getWorldRotationX(__VA_ARGS__)
-#define Bone_getWorldRotationY(...) spBone_getWorldRotationY(__VA_ARGS__)
-#define Bone_getWorldScaleX(...) spBone_getWorldScaleX(__VA_ARGS__)
-#define Bone_getWorldScaleY(...) spBone_getWorldScaleY(__VA_ARGS__)
-#define Bone_worldToLocalRotationX(...) spBone_worldToLocalRotationX(__VA_ARGS__)
-#define Bone_worldToLocalRotationY(...) spBone_worldToLocalRotationY(__VA_ARGS__)
-#define Bone_rotateWorld(...) spBone_rotateWorld(__VA_ARGS__)
-#define Bone_updateLocalTransform(...) spBone_updateLocalTransform(__VA_ARGS__)
-#define Bone_worldToLocal(...) spBone_worldToLocal(__VA_ARGS__)
-#define Bone_localToWorld(...) spBone_localToWorld(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_BONE_H_
+#define SPINE_BONE_H_
+
+#include <spine/BoneData.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct spSkeleton;
+
+typedef struct spBone spBone;
+struct spBone {
+	spBoneData* const data;
+	struct spSkeleton* const skeleton;
+	spBone* const parent;
+	int childrenCount;
+	spBone** const children;
+	float x, y, rotation, scaleX, scaleY, shearX, shearY;
+	float appliedRotation;
+
+	float const a, b, worldX;
+	float const c, d, worldY;
+	float const worldSignX, worldSignY;
+
+	int/*bool*/ sorted;
+
+#ifdef __cplusplus
+	spBone() :
+		data(0),
+		skeleton(0),
+		parent(0),
+		childrenCount(0), children(0),
+		x(0), y(0), rotation(0), scaleX(0), scaleY(0),
+		appliedRotation(0),
+
+		a(0), b(0), worldX(0),
+		c(0), d(0), worldY(0),
+		worldSignX(0), worldSignY(0),
+		
+		sorted(0) {
+	}
+#endif
+};
+
+void spBone_setYDown (int/*bool*/yDown);
+int/*bool*/spBone_isYDown ();
+
+/* @param parent May be 0. */
+spBone* spBone_create (spBoneData* data, struct spSkeleton* skeleton, spBone* parent);
+void spBone_dispose (spBone* self);
+
+void spBone_setToSetupPose (spBone* self);
+
+void spBone_updateWorldTransform (spBone* self);
+void spBone_updateWorldTransformWith (spBone* self, float x, float y, float rotation, float scaleX, float scaleY, float shearX, float shearY);
+
+float spBone_getWorldRotationX (spBone* self);
+float spBone_getWorldRotationY (spBone* self);
+float spBone_getWorldScaleX (spBone* self);
+float spBone_getWorldScaleY (spBone* self);
+
+float spBone_worldToLocalRotationX (spBone* self);
+float spBone_worldToLocalRotationY (spBone* self);
+void spBone_rotateWorld (spBone* self, float degrees);
+void spBone_updateLocalTransform (spBone* self);
+
+void spBone_worldToLocal (spBone* self, float worldX, float worldY, float* localX, float* localY);
+void spBone_localToWorld (spBone* self, float localX, float localY, float* worldX, float* worldY);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spBone Bone;
+#define Bone_setYDown(...) spBone_setYDown(__VA_ARGS__)
+#define Bone_isYDown() spBone_isYDown()
+#define Bone_create(...) spBone_create(__VA_ARGS__)
+#define Bone_dispose(...) spBone_dispose(__VA_ARGS__)
+#define Bone_setToSetupPose(...) spBone_setToSetupPose(__VA_ARGS__)
+#define Bone_updateWorldTransform(...) spBone_updateWorldTransform(__VA_ARGS__)
+#define Bone_updateWorldTransformWith(...) spBone_updateWorldTransformWith(__VA_ARGS__)
+#define Bone_getWorldRotationX(...) spBone_getWorldRotationX(__VA_ARGS__)
+#define Bone_getWorldRotationY(...) spBone_getWorldRotationY(__VA_ARGS__)
+#define Bone_getWorldScaleX(...) spBone_getWorldScaleX(__VA_ARGS__)
+#define Bone_getWorldScaleY(...) spBone_getWorldScaleY(__VA_ARGS__)
+#define Bone_worldToLocalRotationX(...) spBone_worldToLocalRotationX(__VA_ARGS__)
+#define Bone_worldToLocalRotationY(...) spBone_worldToLocalRotationY(__VA_ARGS__)
+#define Bone_rotateWorld(...) spBone_rotateWorld(__VA_ARGS__)
+#define Bone_updateLocalTransform(...) spBone_updateLocalTransform(__VA_ARGS__)
+#define Bone_worldToLocal(...) spBone_worldToLocal(__VA_ARGS__)
+#define Bone_localToWorld(...) spBone_localToWorld(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_BONE_H_ */

+ 72 - 73
spine-c/include/spine/BoneData.h

@@ -1,76 +1,75 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_BONEDATA_H_
-#define SPINE_BONEDATA_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spBoneData spBoneData;
-struct spBoneData {
-	const int index;
-	const char* const name;
-	spBoneData* const parent;
-	float length;
-	float x, y, rotation, scaleX, scaleY, shearX, shearY;
-	int/*bool*/inheritRotation, inheritScale;
-
-#ifdef __cplusplus
-	spBoneData() :
-		index(0),
-		name(0),
-		parent(0),
-		length(0),
-		x(0), y(0),
-		rotation(0),
-		scaleX(0), scaleY(0),
-		shearX(0), shearY(0),
-		inheritRotation(0), inheritScale(0) {
-	}
-#endif
-};
-
-spBoneData* spBoneData_create (int index, const char* name, spBoneData* parent);
-void spBoneData_dispose (spBoneData* self);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spBoneData BoneData;
-#define BoneData_create(...) spBoneData_create(__VA_ARGS__)
-#define BoneData_dispose(...) spBoneData_dispose(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_BONEDATA_H_
+#define SPINE_BONEDATA_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spBoneData spBoneData;
+struct spBoneData {
+	const int index;
+	const char* const name;
+	spBoneData* const parent;
+	float length;
+	float x, y, rotation, scaleX, scaleY, shearX, shearY;
+	int/*bool*/inheritRotation, inheritScale;
+
+#ifdef __cplusplus
+	spBoneData() :
+		index(0),
+		name(0),
+		parent(0),
+		length(0),
+		x(0), y(0),
+		rotation(0),
+		scaleX(0), scaleY(0),
+		shearX(0), shearY(0),
+		inheritRotation(0), inheritScale(0) {
+	}
+#endif
+};
+
+spBoneData* spBoneData_create (int index, const char* name, spBoneData* parent);
+void spBoneData_dispose (spBoneData* self);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spBoneData BoneData;
+#define BoneData_create(...) spBoneData_create(__VA_ARGS__)
+#define BoneData_dispose(...) spBoneData_dispose(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_BONEDATA_H_ */

+ 57 - 58
spine-c/include/spine/BoundingBoxAttachment.h

@@ -1,61 +1,60 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_BOUNDINGBOXATTACHMENT_H_
-#define SPINE_BOUNDINGBOXATTACHMENT_H_
-
-#include <spine/Attachment.h>
-#include <spine/VertexAttachment.h>
-#include <spine/Atlas.h>
-#include <spine/Slot.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spBoundingBoxAttachment {
-	spVertexAttachment super;
-} spBoundingBoxAttachment;
-
-spBoundingBoxAttachment* spBoundingBoxAttachment_create (const char* name);
-void spBoundingBoxAttachment_computeWorldVertices (spBoundingBoxAttachment* self, spSlot* slot, float* worldVertices);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spBoundingBoxAttachment BoundingBoxAttachment;
-#define BoundingBoxAttachment_create(...) spBoundingBoxAttachment_create(__VA_ARGS__)
-#define BoundingBoxAttachment_computeWorldVertices(...) spBoundingBoxAttachment_computeWorldVertices(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_BOUNDINGBOXATTACHMENT_H_
+#define SPINE_BOUNDINGBOXATTACHMENT_H_
+
+#include <spine/Attachment.h>
+#include <spine/VertexAttachment.h>
+#include <spine/Atlas.h>
+#include <spine/Slot.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spBoundingBoxAttachment {
+	spVertexAttachment super;
+} spBoundingBoxAttachment;
+
+spBoundingBoxAttachment* spBoundingBoxAttachment_create (const char* name);
+void spBoundingBoxAttachment_computeWorldVertices (spBoundingBoxAttachment* self, spSlot* slot, float* worldVertices);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spBoundingBoxAttachment BoundingBoxAttachment;
+#define BoundingBoxAttachment_create(...) spBoundingBoxAttachment_create(__VA_ARGS__)
+#define BoundingBoxAttachment_computeWorldVertices(...) spBoundingBoxAttachment_computeWorldVertices(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_BOUNDINGBOXATTACHMENT_H_ */

+ 68 - 69
spine-c/include/spine/Event.h

@@ -1,72 +1,71 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_EVENT_H_
-#define SPINE_EVENT_H_
-
-#include <spine/EventData.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spEvent {
-	spEventData* const data;
-	float const time;
-	int intValue;
-	float floatValue;
-	const char* stringValue;
-
-#ifdef __cplusplus
-	spEvent() :
-		data(0),
-		time(0),
-		intValue(0),
-		floatValue(0),
-		stringValue(0) {
-	}
-#endif
-} spEvent;
-
-spEvent* spEvent_create (float time, spEventData* data);
-void spEvent_dispose (spEvent* self);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spEvent Event;
-#define Event_create(...) spEvent_create(__VA_ARGS__)
-#define Event_dispose(...) spEvent_dispose(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_EVENT_H_
+#define SPINE_EVENT_H_
+
+#include <spine/EventData.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spEvent {
+	spEventData* const data;
+	float const time;
+	int intValue;
+	float floatValue;
+	const char* stringValue;
+
+#ifdef __cplusplus
+	spEvent() :
+		data(0),
+		time(0),
+		intValue(0),
+		floatValue(0),
+		stringValue(0) {
+	}
+#endif
+} spEvent;
+
+spEvent* spEvent_create (float time, spEventData* data);
+void spEvent_dispose (spEvent* self);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spEvent Event;
+#define Event_create(...) spEvent_create(__VA_ARGS__)
+#define Event_dispose(...) spEvent_dispose(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_EVENT_H_ */

+ 64 - 65
spine-c/include/spine/EventData.h

@@ -1,68 +1,67 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_EVENTDATA_H_
-#define SPINE_EVENTDATA_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spEventData {
-	const char* const name;
-	int intValue;
-	float floatValue;
-	const char* stringValue;
-
-#ifdef __cplusplus
-	spEventData() :
-		name(0),
-		intValue(0),
-		floatValue(0),
-		stringValue(0) {
-	}
-#endif
-} spEventData;
-
-spEventData* spEventData_create (const char* name);
-void spEventData_dispose (spEventData* self);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spEventData EventData;
-#define EventData_create(...) spEventData_create(__VA_ARGS__)
-#define EventData_dispose(...) spEventData_dispose(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_EVENTDATA_H_
+#define SPINE_EVENTDATA_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spEventData {
+	const char* const name;
+	int intValue;
+	float floatValue;
+	const char* stringValue;
+
+#ifdef __cplusplus
+	spEventData() :
+		name(0),
+		intValue(0),
+		floatValue(0),
+		stringValue(0) {
+	}
+#endif
+} spEventData;
+
+spEventData* spEventData_create (const char* name);
+void spEventData_dispose (spEventData* self);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spEventData EventData;
+#define EventData_create(...) spEventData_create(__VA_ARGS__)
+#define EventData_dispose(...) spEventData_dispose(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_EVENTDATA_H_ */

+ 86 - 87
spine-c/include/spine/IkConstraint.h

@@ -1,90 +1,89 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_IKCONSTRAINT_H_
-#define SPINE_IKCONSTRAINT_H_
-
-#include <spine/IkConstraintData.h>
-#include <spine/Bone.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct spSkeleton;
-
-typedef struct spIkConstraint {
-	spIkConstraintData* const data;
-	
-	int bonesCount;
-	spBone** bones;
-	
-	spBone* target;
-	int bendDirection;
-	float mix;
-
-	int level;
-
-#ifdef __cplusplus
-	spIkConstraint() :
-		data(0),
-		bonesCount(0),
-		bones(0),
-		target(0),
-		bendDirection(0),
-		mix(0),
-		level(0) {
-	}
-#endif
-} spIkConstraint;
-
-spIkConstraint* spIkConstraint_create (spIkConstraintData* data, const struct spSkeleton* skeleton);
-void spIkConstraint_dispose (spIkConstraint* self);
-
-void spIkConstraint_apply (spIkConstraint* self);
-
-void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, float alpha);
-void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float targetY, int bendDirection, float alpha);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spIkConstraint IkConstraint;
-#define IkConstraint_create(...) spIkConstraint_create(__VA_ARGS__)
-#define IkConstraint_dispose(...) spIkConstraint_dispose(__VA_ARGS__)
-#define IkConstraint_apply(...) spIkConstraint_apply(__VA_ARGS__)
-#define IkConstraint_apply1(...) spIkConstraint_apply1(__VA_ARGS__)
-#define IkConstraint_apply2(...) spIkConstraint_apply2(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_IKCONSTRAINT_H_
+#define SPINE_IKCONSTRAINT_H_
+
+#include <spine/IkConstraintData.h>
+#include <spine/Bone.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct spSkeleton;
+
+typedef struct spIkConstraint {
+	spIkConstraintData* const data;
+	
+	int bonesCount;
+	spBone** bones;
+	
+	spBone* target;
+	int bendDirection;
+	float mix;
+
+	int level;
+
+#ifdef __cplusplus
+	spIkConstraint() :
+		data(0),
+		bonesCount(0),
+		bones(0),
+		target(0),
+		bendDirection(0),
+		mix(0),
+		level(0) {
+	}
+#endif
+} spIkConstraint;
+
+spIkConstraint* spIkConstraint_create (spIkConstraintData* data, const struct spSkeleton* skeleton);
+void spIkConstraint_dispose (spIkConstraint* self);
+
+void spIkConstraint_apply (spIkConstraint* self);
+
+void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, float alpha);
+void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float targetY, int bendDirection, float alpha);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spIkConstraint IkConstraint;
+#define IkConstraint_create(...) spIkConstraint_create(__VA_ARGS__)
+#define IkConstraint_dispose(...) spIkConstraint_dispose(__VA_ARGS__)
+#define IkConstraint_apply(...) spIkConstraint_apply(__VA_ARGS__)
+#define IkConstraint_apply1(...) spIkConstraint_apply1(__VA_ARGS__)
+#define IkConstraint_apply2(...) spIkConstraint_apply2(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_IKCONSTRAINT_H_ */

+ 72 - 73
spine-c/include/spine/IkConstraintData.h

@@ -1,76 +1,75 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_IKCONSTRAINTDATA_H_
-#define SPINE_IKCONSTRAINTDATA_H_
-
-#include <spine/BoneData.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spIkConstraintData {
-	const char* const name;
-	
-	int bonesCount;
-	spBoneData** bones;
-	
-	spBoneData* target;
-	int bendDirection;
-	float mix;
-
-#ifdef __cplusplus
-	spIkConstraintData() :
-		name(0),
-		bonesCount(0),
-		bones(0),
-		target(0),
-		bendDirection(0),
-		mix(0) {
-	}
-#endif
-} spIkConstraintData;
-
-spIkConstraintData* spIkConstraintData_create (const char* name);
-void spIkConstraintData_dispose (spIkConstraintData* self);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spIkConstraintData IkConstraintData;
-#define IkConstraintData_create(...) spIkConstraintData_create(__VA_ARGS__)
-#define IkConstraintData_dispose(...) spIkConstraintData_dispose(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_IKCONSTRAINTDATA_H_
+#define SPINE_IKCONSTRAINTDATA_H_
+
+#include <spine/BoneData.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spIkConstraintData {
+	const char* const name;
+	
+	int bonesCount;
+	spBoneData** bones;
+	
+	spBoneData* target;
+	int bendDirection;
+	float mix;
+
+#ifdef __cplusplus
+	spIkConstraintData() :
+		name(0),
+		bonesCount(0),
+		bones(0),
+		target(0),
+		bendDirection(0),
+		mix(0) {
+	}
+#endif
+} spIkConstraintData;
+
+spIkConstraintData* spIkConstraintData_create (const char* name);
+void spIkConstraintData_dispose (spIkConstraintData* self);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spIkConstraintData IkConstraintData;
+#define IkConstraintData_create(...) spIkConstraintData_create(__VA_ARGS__)
+#define IkConstraintData_dispose(...) spIkConstraintData_dispose(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_IKCONSTRAINTDATA_H_ */

+ 89 - 90
spine-c/include/spine/MeshAttachment.h

@@ -1,93 +1,92 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_MESHATTACHMENT_H_
-#define SPINE_MESHATTACHMENT_H_
-
-#include <spine/Attachment.h>
-#include <spine/VertexAttachment.h>
-#include <spine/Atlas.h>
-#include <spine/Slot.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spMeshAttachment spMeshAttachment;
-struct spMeshAttachment {
-	spVertexAttachment super;
-
-	void* rendererObject;
-	int regionOffsetX, regionOffsetY; /* Pixels stripped from the bottom left, unrotated. */
-	int regionWidth, regionHeight; /* Unrotated, stripped pixel size. */
-	int regionOriginalWidth, regionOriginalHeight; /* Unrotated, unstripped pixel size. */
-	float regionU, regionV, regionU2, regionV2;
-	int/*bool*/regionRotate;
-
-	const char* path;
-
-	float* regionUVs;
-	float* uvs;
-
-	int trianglesCount;
-	unsigned short* triangles;
-
-	float r, g, b, a;
-
-	int hullLength;
-
-	spMeshAttachment* const parentMesh;
-	int/*bool*/inheritDeform;
-
-	/* Nonessential. */
-	int edgesCount;
-	int* edges;
-	float width, height;
-};
-
-spMeshAttachment* spMeshAttachment_create (const char* name);
-void spMeshAttachment_updateUVs (spMeshAttachment* self);
-void spMeshAttachment_computeWorldVertices (spMeshAttachment* self, spSlot* slot, float* worldVertices);
-void spMeshAttachment_setParentMesh (spMeshAttachment* self, spMeshAttachment* parentMesh);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spMeshAttachment MeshAttachment;
-#define MeshAttachment_create(...) spMeshAttachment_create(__VA_ARGS__)
-#define MeshAttachment_updateUVs(...) spMeshAttachment_updateUVs(__VA_ARGS__)
-#define MeshAttachment_computeWorldVertices(...) spMeshAttachment_computeWorldVertices(__VA_ARGS__)
-#define MeshAttachment_setParentMesh(...) spMeshAttachment_setParentMesh(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_MESHATTACHMENT_H_
+#define SPINE_MESHATTACHMENT_H_
+
+#include <spine/Attachment.h>
+#include <spine/VertexAttachment.h>
+#include <spine/Atlas.h>
+#include <spine/Slot.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spMeshAttachment spMeshAttachment;
+struct spMeshAttachment {
+	spVertexAttachment super;
+
+	void* rendererObject;
+	int regionOffsetX, regionOffsetY; /* Pixels stripped from the bottom left, unrotated. */
+	int regionWidth, regionHeight; /* Unrotated, stripped pixel size. */
+	int regionOriginalWidth, regionOriginalHeight; /* Unrotated, unstripped pixel size. */
+	float regionU, regionV, regionU2, regionV2;
+	int/*bool*/regionRotate;
+
+	const char* path;
+
+	float* regionUVs;
+	float* uvs;
+
+	int trianglesCount;
+	unsigned short* triangles;
+
+	float r, g, b, a;
+
+	int hullLength;
+
+	spMeshAttachment* const parentMesh;
+	int/*bool*/inheritDeform;
+
+	/* Nonessential. */
+	int edgesCount;
+	int* edges;
+	float width, height;
+};
+
+spMeshAttachment* spMeshAttachment_create (const char* name);
+void spMeshAttachment_updateUVs (spMeshAttachment* self);
+void spMeshAttachment_computeWorldVertices (spMeshAttachment* self, spSlot* slot, float* worldVertices);
+void spMeshAttachment_setParentMesh (spMeshAttachment* self, spMeshAttachment* parentMesh);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spMeshAttachment MeshAttachment;
+#define MeshAttachment_create(...) spMeshAttachment_create(__VA_ARGS__)
+#define MeshAttachment_updateUVs(...) spMeshAttachment_updateUVs(__VA_ARGS__)
+#define MeshAttachment_computeWorldVertices(...) spMeshAttachment_computeWorldVertices(__VA_ARGS__)
+#define MeshAttachment_setParentMesh(...) spMeshAttachment_setParentMesh(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_MESHATTACHMENT_H_ */

+ 61 - 62
spine-c/include/spine/PathAttachment.h

@@ -1,65 +1,64 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- *
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- *
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- *
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_PATHATTACHMENT_H_
-#define SPINE_PATHATTACHMENT_H_
-
-#include <spine/Attachment.h>
-#include <spine/VertexAttachment.h>
-#include <spine/Atlas.h>
-#include <spine/Slot.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spPathAttachment {
-	spVertexAttachment super;
-	int lengthsLength;
-	float* lengths;
-	int/*bool*/ closed, constantSpeed;
-} spPathAttachment;
-
-spPathAttachment* spPathAttachment_create (const char* name);
-void spPathAttachment_computeWorldVertices (spPathAttachment* self, spSlot* slot, float* worldVertices);
-void spPathAttachment_computeWorldVertices1 (spPathAttachment* self, spSlot* slot, int start, int count, float* worldVertices, int offset);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spPathAttachment PathAttachment;
-#define PathAttachment_create(...) spPathAttachment_create(__VA_ARGS__)
-#define PathAttachment_computeWorldVertices(...) spPathAttachment_computeWorldVertices(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_PATHATTACHMENT_H_
+#define SPINE_PATHATTACHMENT_H_
+
+#include <spine/Attachment.h>
+#include <spine/VertexAttachment.h>
+#include <spine/Atlas.h>
+#include <spine/Slot.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spPathAttachment {
+	spVertexAttachment super;
+	int lengthsLength;
+	float* lengths;
+	int/*bool*/ closed, constantSpeed;
+} spPathAttachment;
+
+spPathAttachment* spPathAttachment_create (const char* name);
+void spPathAttachment_computeWorldVertices (spPathAttachment* self, spSlot* slot, float* worldVertices);
+void spPathAttachment_computeWorldVertices1 (spPathAttachment* self, spSlot* slot, int start, int count, float* worldVertices, int offset);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spPathAttachment PathAttachment;
+#define PathAttachment_create(...) spPathAttachment_create(__VA_ARGS__)
+#define PathAttachment_computeWorldVertices(...) spPathAttachment_computeWorldVertices(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_PATHATTACHMENT_H_ */

+ 109 - 110
spine-c/include/spine/PathConstraint.h

@@ -1,113 +1,112 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- *
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- *
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- *
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_PATHCONSTRAINT_H_
-#define SPINE_PATHCONSTRAINT_H_
-
-#include <spine/PathConstraintData.h>
-#include <spine/Bone.h>
-#include <spine/Slot.h>
-#include "PathAttachment.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct spSkeleton;
-
-typedef struct spPathConstraint {
-	spPathConstraintData* const data;
-	int bonesCount;
-	spBone** const bones;
-	spSlot* target;
-	float position, spacing, rotateMix, translateMix;
-
-	int spacesCount;
-	float* spaces;
-
-	int positionsCount;
-	float* positions;
-
-	int worldCount;
-	float* world;
-
-	int curvesCount;
-	float* curves;
-
-	int lengthsCount;
-	float* lengths;
-
-	float segments[10];
-
-#ifdef __cplusplus
-	spPathConstraint() :
-		data(0),
-		bonesCount(0),
-		bones(0),
-		target(0),
-		position(0),
-		spacing(0),
-		rotateMix(0),
-		translateMix(0),
-		spacesCount(0),
-		spaces(0),
-		positionsCount(0),
-		positions(0),
-		worldCount(0),
-		world(0),
-		curvesCount(0),
-		curves(0),
-		lengthsCount(0),
-		lengths(0) {
-	}
-#endif
-} spPathConstraint;
-
-#define SP_PATHCONSTRAINT_
-
-spPathConstraint* spPathConstraint_create (spPathConstraintData* data, const struct spSkeleton* skeleton);
-void spPathConstraint_dispose (spPathConstraint* self);
-
-void spPathConstraint_apply (spPathConstraint* self);
-float* spPathConstraint_computeWorldPositions(spPathConstraint* self, spPathAttachment* path, int spacesCount, int/*bool*/ tangents, int/*bool*/percentPosition, int/**/percentSpacing);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spPathConstraint PathConstraint;
-#define PathConstraint_create(...) spPathConstraint_create(__VA_ARGS__)
-#define PathConstraint_dispose(...) spPathConstraint_dispose(__VA_ARGS__)
-#define PathConstraint_apply(...) spPathConstraint_apply(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_PATHCONSTRAINT_H_
+#define SPINE_PATHCONSTRAINT_H_
+
+#include <spine/PathConstraintData.h>
+#include <spine/Bone.h>
+#include <spine/Slot.h>
+#include "PathAttachment.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct spSkeleton;
+
+typedef struct spPathConstraint {
+	spPathConstraintData* const data;
+	int bonesCount;
+	spBone** const bones;
+	spSlot* target;
+	float position, spacing, rotateMix, translateMix;
+
+	int spacesCount;
+	float* spaces;
+
+	int positionsCount;
+	float* positions;
+
+	int worldCount;
+	float* world;
+
+	int curvesCount;
+	float* curves;
+
+	int lengthsCount;
+	float* lengths;
+
+	float segments[10];
+
+#ifdef __cplusplus
+	spPathConstraint() :
+		data(0),
+		bonesCount(0),
+		bones(0),
+		target(0),
+		position(0),
+		spacing(0),
+		rotateMix(0),
+		translateMix(0),
+		spacesCount(0),
+		spaces(0),
+		positionsCount(0),
+		positions(0),
+		worldCount(0),
+		world(0),
+		curvesCount(0),
+		curves(0),
+		lengthsCount(0),
+		lengths(0) {
+	}
+#endif
+} spPathConstraint;
+
+#define SP_PATHCONSTRAINT_
+
+spPathConstraint* spPathConstraint_create (spPathConstraintData* data, const struct spSkeleton* skeleton);
+void spPathConstraint_dispose (spPathConstraint* self);
+
+void spPathConstraint_apply (spPathConstraint* self);
+float* spPathConstraint_computeWorldPositions(spPathConstraint* self, spPathAttachment* path, int spacesCount, int/*bool*/ tangents, int/*bool*/percentPosition, int/**/percentSpacing);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spPathConstraint PathConstraint;
+#define PathConstraint_create(...) spPathConstraint_create(__VA_ARGS__)
+#define PathConstraint_dispose(...) spPathConstraint_dispose(__VA_ARGS__)
+#define PathConstraint_apply(...) spPathConstraint_apply(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_PATHCONSTRAINT_H_ */

+ 92 - 93
spine-c/include/spine/PathConstraintData.h

@@ -1,96 +1,95 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- *
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- *
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- *
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_PATHCONSTRAINTDATA_H_
-#define SPINE_PATHCONSTRAINTDATA_H_
-
-#include <spine/BoneData.h>
-#include <spine/SlotData.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
-	SP_POSITION_MODE_FIXED, SP_POSITION_MODE_PERCENT
-} spPositionMode;
-
-typedef enum {
-	SP_SPACING_MODE_LENGTH, SP_SPACING_MODE_FIXED, SP_SPACING_MODE_PERCENT
-} spSpacingMode;
-
-typedef enum {
-	SP_ROTATE_MODE_TANGENT, SP_ROTATE_MODE_CHAIN, SP_ROTATE_MODE_CHAIN_SCALE
-} spRotateMode;
-
-typedef struct spPathConstraintData {
-	const char* const name;
-	int bonesCount;
-	spBoneData** const bones;
-	spSlotData* target;
-	spPositionMode positionMode;
-	spSpacingMode spacingMode;
-	spRotateMode rotateMode;
-	float offsetRotation;
-	float position, spacing, rotateMix, translateMix;
-
-#ifdef __cplusplus
-	spPathConstraintData() :
-		name(0),
-		bonesCount(0),
-		bones(0),
-		target(0),
-		positionMode(SP_POSITION_MODE_FIXED),
-		spacingMode(SP_SPACING_MODE_LENGTH),
-		rotateMode(SP_ROTATE_MODE_TANGENT),
-		offsetRotation(0),
-		position(0),
-		spacing(0),
-		rotateMix(0),
-		translateMix(0) {
-	}
-#endif
-} spPathConstraintData;
-
-spPathConstraintData* spPathConstraintData_create (const char* name);
-void spPathConstraintData_dispose (spPathConstraintData* self);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spPathConstraintData PathConstraintData;
-#define PathConstraintData_create(...) spPathConstraintData_create(__VA_ARGS__)
-#define PathConstraintData_dispose(...) spPathConstraintData_dispose(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_PATHCONSTRAINTDATA_H_
+#define SPINE_PATHCONSTRAINTDATA_H_
+
+#include <spine/BoneData.h>
+#include <spine/SlotData.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+	SP_POSITION_MODE_FIXED, SP_POSITION_MODE_PERCENT
+} spPositionMode;
+
+typedef enum {
+	SP_SPACING_MODE_LENGTH, SP_SPACING_MODE_FIXED, SP_SPACING_MODE_PERCENT
+} spSpacingMode;
+
+typedef enum {
+	SP_ROTATE_MODE_TANGENT, SP_ROTATE_MODE_CHAIN, SP_ROTATE_MODE_CHAIN_SCALE
+} spRotateMode;
+
+typedef struct spPathConstraintData {
+	const char* const name;
+	int bonesCount;
+	spBoneData** const bones;
+	spSlotData* target;
+	spPositionMode positionMode;
+	spSpacingMode spacingMode;
+	spRotateMode rotateMode;
+	float offsetRotation;
+	float position, spacing, rotateMix, translateMix;
+
+#ifdef __cplusplus
+	spPathConstraintData() :
+		name(0),
+		bonesCount(0),
+		bones(0),
+		target(0),
+		positionMode(SP_POSITION_MODE_FIXED),
+		spacingMode(SP_SPACING_MODE_LENGTH),
+		rotateMode(SP_ROTATE_MODE_TANGENT),
+		offsetRotation(0),
+		position(0),
+		spacing(0),
+		rotateMix(0),
+		translateMix(0) {
+	}
+#endif
+} spPathConstraintData;
+
+spPathConstraintData* spPathConstraintData_create (const char* name);
+void spPathConstraintData_dispose (spPathConstraintData* self);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spPathConstraintData PathConstraintData;
+#define PathConstraintData_create(...) spPathConstraintData_create(__VA_ARGS__)
+#define PathConstraintData_dispose(...) spPathConstraintData_dispose(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_PATHCONSTRAINTDATA_H_ */

+ 84 - 85
spine-c/include/spine/RegionAttachment.h

@@ -1,88 +1,87 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_REGIONATTACHMENT_H_
-#define SPINE_REGIONATTACHMENT_H_
-
-#include <spine/Attachment.h>
-#include <spine/Atlas.h>
-#include <spine/Slot.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
-	SP_VERTEX_X1 = 0, SP_VERTEX_Y1, SP_VERTEX_X2, SP_VERTEX_Y2, SP_VERTEX_X3, SP_VERTEX_Y3, SP_VERTEX_X4, SP_VERTEX_Y4
-} spVertexIndex;
-
-typedef struct spRegionAttachment {
-	spAttachment super;
-	const char* path;
-	float x, y, scaleX, scaleY, rotation, width, height;
-	float r, g, b, a;
-
-	void* rendererObject;
-	int regionOffsetX, regionOffsetY; /* Pixels stripped from the bottom left, unrotated. */
-	int regionWidth, regionHeight; /* Unrotated, stripped pixel size. */
-	int regionOriginalWidth, regionOriginalHeight; /* Unrotated, unstripped pixel size. */
-
-	float offset[8];
-	float uvs[8];
-} spRegionAttachment;
-
-spRegionAttachment* spRegionAttachment_create (const char* name);
-void spRegionAttachment_setUVs (spRegionAttachment* self, float u, float v, float u2, float v2, int/*bool*/rotate);
-void spRegionAttachment_updateOffset (spRegionAttachment* self);
-void spRegionAttachment_computeWorldVertices (spRegionAttachment* self, spBone* bone, float* vertices);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spVertexIndex VertexIndex;
-#define VERTEX_X1 SP_VERTEX_X1
-#define VERTEX_Y1 SP_VERTEX_Y1
-#define VERTEX_X2 SP_VERTEX_X2
-#define VERTEX_Y2 SP_VERTEX_Y2
-#define VERTEX_X3 SP_VERTEX_X3
-#define VERTEX_Y3 SP_VERTEX_Y3
-#define VERTEX_X4 SP_VERTEX_X4
-#define VERTEX_Y4 SP_VERTEX_Y4
-typedef spRegionAttachment RegionAttachment;
-#define RegionAttachment_create(...) spRegionAttachment_create(__VA_ARGS__)
-#define RegionAttachment_setUVs(...) spRegionAttachment_setUVs(__VA_ARGS__)
-#define RegionAttachment_updateOffset(...) spRegionAttachment_updateOffset(__VA_ARGS__)
-#define RegionAttachment_computeWorldVertices(...) spRegionAttachment_computeWorldVertices(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_REGIONATTACHMENT_H_
+#define SPINE_REGIONATTACHMENT_H_
+
+#include <spine/Attachment.h>
+#include <spine/Atlas.h>
+#include <spine/Slot.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+	SP_VERTEX_X1 = 0, SP_VERTEX_Y1, SP_VERTEX_X2, SP_VERTEX_Y2, SP_VERTEX_X3, SP_VERTEX_Y3, SP_VERTEX_X4, SP_VERTEX_Y4
+} spVertexIndex;
+
+typedef struct spRegionAttachment {
+	spAttachment super;
+	const char* path;
+	float x, y, scaleX, scaleY, rotation, width, height;
+	float r, g, b, a;
+
+	void* rendererObject;
+	int regionOffsetX, regionOffsetY; /* Pixels stripped from the bottom left, unrotated. */
+	int regionWidth, regionHeight; /* Unrotated, stripped pixel size. */
+	int regionOriginalWidth, regionOriginalHeight; /* Unrotated, unstripped pixel size. */
+
+	float offset[8];
+	float uvs[8];
+} spRegionAttachment;
+
+spRegionAttachment* spRegionAttachment_create (const char* name);
+void spRegionAttachment_setUVs (spRegionAttachment* self, float u, float v, float u2, float v2, int/*bool*/rotate);
+void spRegionAttachment_updateOffset (spRegionAttachment* self);
+void spRegionAttachment_computeWorldVertices (spRegionAttachment* self, spBone* bone, float* vertices);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spVertexIndex VertexIndex;
+#define VERTEX_X1 SP_VERTEX_X1
+#define VERTEX_Y1 SP_VERTEX_Y1
+#define VERTEX_X2 SP_VERTEX_X2
+#define VERTEX_Y2 SP_VERTEX_Y2
+#define VERTEX_X3 SP_VERTEX_X3
+#define VERTEX_Y3 SP_VERTEX_Y3
+#define VERTEX_X4 SP_VERTEX_X4
+#define VERTEX_Y4 SP_VERTEX_Y4
+typedef spRegionAttachment RegionAttachment;
+#define RegionAttachment_create(...) spRegionAttachment_create(__VA_ARGS__)
+#define RegionAttachment_setUVs(...) spRegionAttachment_setUVs(__VA_ARGS__)
+#define RegionAttachment_updateOffset(...) spRegionAttachment_updateOffset(__VA_ARGS__)
+#define RegionAttachment_computeWorldVertices(...) spRegionAttachment_computeWorldVertices(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_REGIONATTACHMENT_H_ */

+ 172 - 173
spine-c/include/spine/Skeleton.h

@@ -1,176 +1,175 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_SKELETON_H_
-#define SPINE_SKELETON_H_
-
-#include <spine/SkeletonData.h>
-#include <spine/Slot.h>
-#include <spine/Skin.h>
-#include <spine/IkConstraint.h>
-#include <spine/TransformConstraint.h>
-#include <spine/PathConstraint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spSkeleton {
-	spSkeletonData* const data;
-
-	int bonesCount;
-	spBone** bones;
-	spBone* const root;
-
-	int slotsCount;
-	spSlot** slots;
-	spSlot** drawOrder;
-
-	int ikConstraintsCount;
-	spIkConstraint** ikConstraints;
-	spIkConstraint** ikConstraintsSorted;
-
-	int transformConstraintsCount;
-	spTransformConstraint** transformConstraints;
-
-	int pathConstraintsCount;
-	spPathConstraint** pathConstraints;
-
-	spSkin* const skin;
-	float r, g, b, a;
-	float time;
-	int/*bool*/flipX, flipY;
-	float x, y;
-
-#ifdef __cplusplus
-	spSkeleton() :
-		data(0),
-		bonesCount(0),
-		bones(0),
-		root(0),
-		slotsCount(0),
-		slots(0),
-		drawOrder(0),
-
-		ikConstraintsCount(0),
-		ikConstraints(0),
-		ikConstraintsSorted(0),
-
-		transformConstraintsCount(0),
-		transformConstraints(0),
-
-		skin(0),
-		r(0), g(0), b(0), a(0),
-		time(0),
-		flipX(0),
-		flipY(0),
-		x(0), y(0) {
-	}
-#endif
-} spSkeleton;
-
-spSkeleton* spSkeleton_create (spSkeletonData* data);
-void spSkeleton_dispose (spSkeleton* self);
-
-/* Caches information about bones and constraints. Must be called if bones or constraints, or weighted path attachments
- * are added or removed. */
-void spSkeleton_updateCache (spSkeleton* self);
-void spSkeleton_updateWorldTransform (const spSkeleton* self);
-
-/* Sets the bones, constraints, and slots to their setup pose values. */
-void spSkeleton_setToSetupPose (const spSkeleton* self);
-/* Sets the bones and constraints to their setup pose values. */
-void spSkeleton_setBonesToSetupPose (const spSkeleton* self);
-void spSkeleton_setSlotsToSetupPose (const spSkeleton* self);
-
-/* Returns 0 if the bone was not found. */
-spBone* spSkeleton_findBone (const spSkeleton* self, const char* boneName);
-/* Returns -1 if the bone was not found. */
-int spSkeleton_findBoneIndex (const spSkeleton* self, const char* boneName);
-
-/* Returns 0 if the slot was not found. */
-spSlot* spSkeleton_findSlot (const spSkeleton* self, const char* slotName);
-/* Returns -1 if the slot was not found. */
-int spSkeleton_findSlotIndex (const spSkeleton* self, const char* slotName);
-
-/* Sets the skin used to look up attachments before looking in the SkeletonData defaultSkin. Attachments from the new skin are
- * attached if the corresponding attachment from the old skin was attached. If there was no old skin, each slot's setup mode
- * attachment is attached from the new skin.
- * @param skin May be 0.*/
-void spSkeleton_setSkin (spSkeleton* self, spSkin* skin);
-/* Returns 0 if the skin was not found. See spSkeleton_setSkin.
- * @param skinName May be 0. */
-int spSkeleton_setSkinByName (spSkeleton* self, const char* skinName);
-
-/* Returns 0 if the slot or attachment was not found. */
-spAttachment* spSkeleton_getAttachmentForSlotName (const spSkeleton* self, const char* slotName, const char* attachmentName);
-/* Returns 0 if the slot or attachment was not found. */
-spAttachment* spSkeleton_getAttachmentForSlotIndex (const spSkeleton* self, int slotIndex, const char* attachmentName);
-/* Returns 0 if the slot or attachment was not found.
- * @param attachmentName May be 0. */
-int spSkeleton_setAttachment (spSkeleton* self, const char* slotName, const char* attachmentName);
-
-/* Returns 0 if the IK constraint was not found. */
-spIkConstraint* spSkeleton_findIkConstraint (const spSkeleton* self, const char* constraintName);
-
-/* Returns 0 if the transform constraint was not found. */
-spTransformConstraint* spSkeleton_findTransformConstraint (const spSkeleton* self, const char* constraintName);
-
-/* Returns 0 if the path constraint was not found. */
-spPathConstraint* spSkeleton_findPathConstraint (const spSkeleton* self, const char* constraintName);
-
-void spSkeleton_update (spSkeleton* self, float deltaTime);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spSkeleton Skeleton;
-#define Skeleton_create(...) spSkeleton_create(__VA_ARGS__)
-#define Skeleton_dispose(...) spSkeleton_dispose(__VA_ARGS__)
-#define Skeleton_updateWorldTransform(...) spSkeleton_updateWorldTransform(__VA_ARGS__)
-#define Skeleton_setToSetupPose(...) spSkeleton_setToSetupPose(__VA_ARGS__)
-#define Skeleton_setBonesToSetupPose(...) spSkeleton_setBonesToSetupPose(__VA_ARGS__)
-#define Skeleton_setSlotsToSetupPose(...) spSkeleton_setSlotsToSetupPose(__VA_ARGS__)
-#define Skeleton_findBone(...) spSkeleton_findBone(__VA_ARGS__)
-#define Skeleton_findBoneIndex(...) spSkeleton_findBoneIndex(__VA_ARGS__)
-#define Skeleton_findSlot(...) spSkeleton_findSlot(__VA_ARGS__)
-#define Skeleton_findSlotIndex(...) spSkeleton_findSlotIndex(__VA_ARGS__)
-#define Skeleton_setSkin(...) spSkeleton_setSkin(__VA_ARGS__)
-#define Skeleton_setSkinByName(...) spSkeleton_setSkinByName(__VA_ARGS__)
-#define Skeleton_getAttachmentForSlotName(...) spSkeleton_getAttachmentForSlotName(__VA_ARGS__)
-#define Skeleton_getAttachmentForSlotIndex(...) spSkeleton_getAttachmentForSlotIndex(__VA_ARGS__)
-#define Skeleton_setAttachment(...) spSkeleton_setAttachment(__VA_ARGS__)
-#define Skeleton_update(...) spSkeleton_update(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_SKELETON_H_
+#define SPINE_SKELETON_H_
+
+#include <spine/SkeletonData.h>
+#include <spine/Slot.h>
+#include <spine/Skin.h>
+#include <spine/IkConstraint.h>
+#include <spine/TransformConstraint.h>
+#include <spine/PathConstraint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spSkeleton {
+	spSkeletonData* const data;
+
+	int bonesCount;
+	spBone** bones;
+	spBone* const root;
+
+	int slotsCount;
+	spSlot** slots;
+	spSlot** drawOrder;
+
+	int ikConstraintsCount;
+	spIkConstraint** ikConstraints;
+	spIkConstraint** ikConstraintsSorted;
+
+	int transformConstraintsCount;
+	spTransformConstraint** transformConstraints;
+
+	int pathConstraintsCount;
+	spPathConstraint** pathConstraints;
+
+	spSkin* const skin;
+	float r, g, b, a;
+	float time;
+	int/*bool*/flipX, flipY;
+	float x, y;
+
+#ifdef __cplusplus
+	spSkeleton() :
+		data(0),
+		bonesCount(0),
+		bones(0),
+		root(0),
+		slotsCount(0),
+		slots(0),
+		drawOrder(0),
+
+		ikConstraintsCount(0),
+		ikConstraints(0),
+		ikConstraintsSorted(0),
+
+		transformConstraintsCount(0),
+		transformConstraints(0),
+
+		skin(0),
+		r(0), g(0), b(0), a(0),
+		time(0),
+		flipX(0),
+		flipY(0),
+		x(0), y(0) {
+	}
+#endif
+} spSkeleton;
+
+spSkeleton* spSkeleton_create (spSkeletonData* data);
+void spSkeleton_dispose (spSkeleton* self);
+
+/* Caches information about bones and constraints. Must be called if bones or constraints, or weighted path attachments
+ * are added or removed. */
+void spSkeleton_updateCache (spSkeleton* self);
+void spSkeleton_updateWorldTransform (const spSkeleton* self);
+
+/* Sets the bones, constraints, and slots to their setup pose values. */
+void spSkeleton_setToSetupPose (const spSkeleton* self);
+/* Sets the bones and constraints to their setup pose values. */
+void spSkeleton_setBonesToSetupPose (const spSkeleton* self);
+void spSkeleton_setSlotsToSetupPose (const spSkeleton* self);
+
+/* Returns 0 if the bone was not found. */
+spBone* spSkeleton_findBone (const spSkeleton* self, const char* boneName);
+/* Returns -1 if the bone was not found. */
+int spSkeleton_findBoneIndex (const spSkeleton* self, const char* boneName);
+
+/* Returns 0 if the slot was not found. */
+spSlot* spSkeleton_findSlot (const spSkeleton* self, const char* slotName);
+/* Returns -1 if the slot was not found. */
+int spSkeleton_findSlotIndex (const spSkeleton* self, const char* slotName);
+
+/* Sets the skin used to look up attachments before looking in the SkeletonData defaultSkin. Attachments from the new skin are
+ * attached if the corresponding attachment from the old skin was attached. If there was no old skin, each slot's setup mode
+ * attachment is attached from the new skin.
+ * @param skin May be 0.*/
+void spSkeleton_setSkin (spSkeleton* self, spSkin* skin);
+/* Returns 0 if the skin was not found. See spSkeleton_setSkin.
+ * @param skinName May be 0. */
+int spSkeleton_setSkinByName (spSkeleton* self, const char* skinName);
+
+/* Returns 0 if the slot or attachment was not found. */
+spAttachment* spSkeleton_getAttachmentForSlotName (const spSkeleton* self, const char* slotName, const char* attachmentName);
+/* Returns 0 if the slot or attachment was not found. */
+spAttachment* spSkeleton_getAttachmentForSlotIndex (const spSkeleton* self, int slotIndex, const char* attachmentName);
+/* Returns 0 if the slot or attachment was not found.
+ * @param attachmentName May be 0. */
+int spSkeleton_setAttachment (spSkeleton* self, const char* slotName, const char* attachmentName);
+
+/* Returns 0 if the IK constraint was not found. */
+spIkConstraint* spSkeleton_findIkConstraint (const spSkeleton* self, const char* constraintName);
+
+/* Returns 0 if the transform constraint was not found. */
+spTransformConstraint* spSkeleton_findTransformConstraint (const spSkeleton* self, const char* constraintName);
+
+/* Returns 0 if the path constraint was not found. */
+spPathConstraint* spSkeleton_findPathConstraint (const spSkeleton* self, const char* constraintName);
+
+void spSkeleton_update (spSkeleton* self, float deltaTime);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spSkeleton Skeleton;
+#define Skeleton_create(...) spSkeleton_create(__VA_ARGS__)
+#define Skeleton_dispose(...) spSkeleton_dispose(__VA_ARGS__)
+#define Skeleton_updateWorldTransform(...) spSkeleton_updateWorldTransform(__VA_ARGS__)
+#define Skeleton_setToSetupPose(...) spSkeleton_setToSetupPose(__VA_ARGS__)
+#define Skeleton_setBonesToSetupPose(...) spSkeleton_setBonesToSetupPose(__VA_ARGS__)
+#define Skeleton_setSlotsToSetupPose(...) spSkeleton_setSlotsToSetupPose(__VA_ARGS__)
+#define Skeleton_findBone(...) spSkeleton_findBone(__VA_ARGS__)
+#define Skeleton_findBoneIndex(...) spSkeleton_findBoneIndex(__VA_ARGS__)
+#define Skeleton_findSlot(...) spSkeleton_findSlot(__VA_ARGS__)
+#define Skeleton_findSlotIndex(...) spSkeleton_findSlotIndex(__VA_ARGS__)
+#define Skeleton_setSkin(...) spSkeleton_setSkin(__VA_ARGS__)
+#define Skeleton_setSkinByName(...) spSkeleton_setSkinByName(__VA_ARGS__)
+#define Skeleton_getAttachmentForSlotName(...) spSkeleton_getAttachmentForSlotName(__VA_ARGS__)
+#define Skeleton_getAttachmentForSlotIndex(...) spSkeleton_getAttachmentForSlotIndex(__VA_ARGS__)
+#define Skeleton_setAttachment(...) spSkeleton_setAttachment(__VA_ARGS__)
+#define Skeleton_update(...) spSkeleton_update(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_SKELETON_H_*/

+ 68 - 69
spine-c/include/spine/SkeletonBinary.h

@@ -1,72 +1,71 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2016, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_SKELETONBINARY_H_
-#define SPINE_SKELETONBINARY_H_
-
-#include <spine/Attachment.h>
-#include <spine/AttachmentLoader.h>
-#include <spine/SkeletonData.h>
-#include <spine/Atlas.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct spAtlasAttachmentLoader;
-
-typedef struct spSkeletonBinary {
-	float scale;
-	spAttachmentLoader* attachmentLoader;
-	const char* const error;
-} spSkeletonBinary;
-
-spSkeletonBinary* spSkeletonBinary_createWithLoader (spAttachmentLoader* attachmentLoader);
-spSkeletonBinary* spSkeletonBinary_create (spAtlas* atlas);
-void spSkeletonBinary_dispose (spSkeletonBinary* self);
-
-spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const unsigned char* binary, const int length);
-spSkeletonData* spSkeletonBinary_readSkeletonDataFile (spSkeletonBinary* self, const char* path);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spSkeletonBinary SkeletonBinary;
-#define SkeletonBinary_createWithLoader(...) spSkeletonBinary_createWithLoader(__VA_ARGS__)
-#define SkeletonBinary_create(...) spSkeletonBinary_create(__VA_ARGS__)
-#define SkeletonBinary_dispose(...) spSkeletonBinary_dispose(__VA_ARGS__)
-#define SkeletonBinary_readSkeletonData(...) spSkeletonBinary_readSkeletonData(__VA_ARGS__)
-#define SkeletonBinary_readSkeletonDataFile(...) spSkeletonBinary_readSkeletonDataFile(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_SKELETONBINARY_H_
+#define SPINE_SKELETONBINARY_H_
+
+#include <spine/Attachment.h>
+#include <spine/AttachmentLoader.h>
+#include <spine/SkeletonData.h>
+#include <spine/Atlas.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct spAtlasAttachmentLoader;
+
+typedef struct spSkeletonBinary {
+	float scale;
+	spAttachmentLoader* attachmentLoader;
+	const char* const error;
+} spSkeletonBinary;
+
+spSkeletonBinary* spSkeletonBinary_createWithLoader (spAttachmentLoader* attachmentLoader);
+spSkeletonBinary* spSkeletonBinary_create (spAtlas* atlas);
+void spSkeletonBinary_dispose (spSkeletonBinary* self);
+
+spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const unsigned char* binary, const int length);
+spSkeletonData* spSkeletonBinary_readSkeletonDataFile (spSkeletonBinary* self, const char* path);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spSkeletonBinary SkeletonBinary;
+#define SkeletonBinary_createWithLoader(...) spSkeletonBinary_createWithLoader(__VA_ARGS__)
+#define SkeletonBinary_create(...) spSkeletonBinary_create(__VA_ARGS__)
+#define SkeletonBinary_dispose(...) spSkeletonBinary_dispose(__VA_ARGS__)
+#define SkeletonBinary_readSkeletonData(...) spSkeletonBinary_readSkeletonData(__VA_ARGS__)
+#define SkeletonBinary_readSkeletonDataFile(...) spSkeletonBinary_readSkeletonDataFile(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_SKELETONBINARY_H_ */

+ 109 - 110
spine-c/include/spine/SkeletonBounds.h

@@ -1,113 +1,112 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_SKELETONBOUNDS_H_
-#define SPINE_SKELETONBOUNDS_H_
-
-#include <spine/BoundingBoxAttachment.h>
-#include <spine/Skeleton.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spPolygon {
-	float* const vertices;
-	int count;
-	int capacity;
-} spPolygon;
-
-spPolygon* spPolygon_create (int capacity);
-void spPolygon_dispose (spPolygon* self);
-
-int/*bool*/spPolygon_containsPoint (spPolygon* polygon, float x, float y);
-int/*bool*/spPolygon_intersectsSegment (spPolygon* polygon, float x1, float y1, float x2, float y2);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spPolygon Polygon;
-#define Polygon_create(...) spPolygon_create(__VA_ARGS__)
-#define Polygon_dispose(...) spPolygon_dispose(__VA_ARGS__)
-#define Polygon_containsPoint(...) spPolygon_containsPoint(__VA_ARGS__)
-#define Polygon_intersectsSegment(...) spPolygon_intersectsSegment(__VA_ARGS__)
-#endif
-
-/**/
-
-typedef struct spSkeletonBounds {
-	int count;
-	spBoundingBoxAttachment** boundingBoxes;
-	spPolygon** polygons;
-
-	float minX, minY, maxX, maxY;
-} spSkeletonBounds;
-
-spSkeletonBounds* spSkeletonBounds_create ();
-void spSkeletonBounds_dispose (spSkeletonBounds* self);
-void spSkeletonBounds_update (spSkeletonBounds* self, spSkeleton* skeleton, int/*bool*/updateAabb);
-
-/** Returns true if the axis aligned bounding box contains the point. */
-int/*bool*/spSkeletonBounds_aabbContainsPoint (spSkeletonBounds* self, float x, float y);
-
-/** Returns true if the axis aligned bounding box intersects the line segment. */
-int/*bool*/spSkeletonBounds_aabbIntersectsSegment (spSkeletonBounds* self, float x1, float y1, float x2, float y2);
-
-/** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */
-int/*bool*/spSkeletonBounds_aabbIntersectsSkeleton (spSkeletonBounds* self, spSkeletonBounds* bounds);
-
-/** Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more
- * efficient to only call this method if spSkeletonBounds_aabbContainsPoint returns true. */
-spBoundingBoxAttachment* spSkeletonBounds_containsPoint (spSkeletonBounds* self, float x, float y);
-
-/** Returns the first bounding box attachment that contains the line segment, or null. When doing many checks, it is usually
- * more efficient to only call this method if spSkeletonBounds_aabbIntersectsSegment returns true. */
-spBoundingBoxAttachment* spSkeletonBounds_intersectsSegment (spSkeletonBounds* self, float x1, float y1, float x2, float y2);
-
-/** Returns the polygon for the specified bounding box, or null. */
-spPolygon* spSkeletonBounds_getPolygon (spSkeletonBounds* self, spBoundingBoxAttachment* boundingBox);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spSkeletonBounds SkeletonBounds;
-#define SkeletonBounds_create(...) spSkeletonBounds_create(__VA_ARGS__)
-#define SkeletonBounds_dispose(...) spSkeletonBounds_dispose(__VA_ARGS__)
-#define SkeletonBounds_update(...) spSkeletonBounds_update(__VA_ARGS__)
-#define SkeletonBounds_aabbContainsPoint(...) spSkeletonBounds_aabbContainsPoint(__VA_ARGS__)
-#define SkeletonBounds_aabbIntersectsSegment(...) spSkeletonBounds_aabbIntersectsSegment(__VA_ARGS__)
-#define SkeletonBounds_aabbIntersectsSkeleton(...) spSkeletonBounds_aabbIntersectsSkeleton(__VA_ARGS__)
-#define SkeletonBounds_containsPoint(...) spSkeletonBounds_containsPoint(__VA_ARGS__)
-#define SkeletonBounds_intersectsSegment(...) spSkeletonBounds_intersectsSegment(__VA_ARGS__)
-#define SkeletonBounds_getPolygon(...) spSkeletonBounds_getPolygon(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_SKELETONBOUNDS_H_
+#define SPINE_SKELETONBOUNDS_H_
+
+#include <spine/BoundingBoxAttachment.h>
+#include <spine/Skeleton.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spPolygon {
+	float* const vertices;
+	int count;
+	int capacity;
+} spPolygon;
+
+spPolygon* spPolygon_create (int capacity);
+void spPolygon_dispose (spPolygon* self);
+
+int/*bool*/spPolygon_containsPoint (spPolygon* polygon, float x, float y);
+int/*bool*/spPolygon_intersectsSegment (spPolygon* polygon, float x1, float y1, float x2, float y2);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spPolygon Polygon;
+#define Polygon_create(...) spPolygon_create(__VA_ARGS__)
+#define Polygon_dispose(...) spPolygon_dispose(__VA_ARGS__)
+#define Polygon_containsPoint(...) spPolygon_containsPoint(__VA_ARGS__)
+#define Polygon_intersectsSegment(...) spPolygon_intersectsSegment(__VA_ARGS__)
+#endif
+
+/**/
+
+typedef struct spSkeletonBounds {
+	int count;
+	spBoundingBoxAttachment** boundingBoxes;
+	spPolygon** polygons;
+
+	float minX, minY, maxX, maxY;
+} spSkeletonBounds;
+
+spSkeletonBounds* spSkeletonBounds_create ();
+void spSkeletonBounds_dispose (spSkeletonBounds* self);
+void spSkeletonBounds_update (spSkeletonBounds* self, spSkeleton* skeleton, int/*bool*/updateAabb);
+
+/** Returns true if the axis aligned bounding box contains the point. */
+int/*bool*/spSkeletonBounds_aabbContainsPoint (spSkeletonBounds* self, float x, float y);
+
+/** Returns true if the axis aligned bounding box intersects the line segment. */
+int/*bool*/spSkeletonBounds_aabbIntersectsSegment (spSkeletonBounds* self, float x1, float y1, float x2, float y2);
+
+/** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */
+int/*bool*/spSkeletonBounds_aabbIntersectsSkeleton (spSkeletonBounds* self, spSkeletonBounds* bounds);
+
+/** Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more
+ * efficient to only call this method if spSkeletonBounds_aabbContainsPoint returns true. */
+spBoundingBoxAttachment* spSkeletonBounds_containsPoint (spSkeletonBounds* self, float x, float y);
+
+/** Returns the first bounding box attachment that contains the line segment, or null. When doing many checks, it is usually
+ * more efficient to only call this method if spSkeletonBounds_aabbIntersectsSegment returns true. */
+spBoundingBoxAttachment* spSkeletonBounds_intersectsSegment (spSkeletonBounds* self, float x1, float y1, float x2, float y2);
+
+/** Returns the polygon for the specified bounding box, or null. */
+spPolygon* spSkeletonBounds_getPolygon (spSkeletonBounds* self, spBoundingBoxAttachment* boundingBox);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spSkeletonBounds SkeletonBounds;
+#define SkeletonBounds_create(...) spSkeletonBounds_create(__VA_ARGS__)
+#define SkeletonBounds_dispose(...) spSkeletonBounds_dispose(__VA_ARGS__)
+#define SkeletonBounds_update(...) spSkeletonBounds_update(__VA_ARGS__)
+#define SkeletonBounds_aabbContainsPoint(...) spSkeletonBounds_aabbContainsPoint(__VA_ARGS__)
+#define SkeletonBounds_aabbIntersectsSegment(...) spSkeletonBounds_aabbIntersectsSegment(__VA_ARGS__)
+#define SkeletonBounds_aabbIntersectsSkeleton(...) spSkeletonBounds_aabbIntersectsSkeleton(__VA_ARGS__)
+#define SkeletonBounds_containsPoint(...) spSkeletonBounds_containsPoint(__VA_ARGS__)
+#define SkeletonBounds_intersectsSegment(...) spSkeletonBounds_intersectsSegment(__VA_ARGS__)
+#define SkeletonBounds_getPolygon(...) spSkeletonBounds_getPolygon(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_SKELETONBOUNDS_H_ */

+ 113 - 114
spine-c/include/spine/SkeletonData.h

@@ -1,117 +1,116 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_SKELETONDATA_H_
-#define SPINE_SKELETONDATA_H_
-
-#include <spine/BoneData.h>
-#include <spine/SlotData.h>
-#include <spine/Skin.h>
-#include <spine/EventData.h>
-#include <spine/Animation.h>
-#include <spine/IkConstraintData.h>
-#include <spine/TransformConstraintData.h>
-#include <spine/PathConstraintData.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spSkeletonData {
-	const char* version;
-	const char* hash;
-	float width, height;
-
-	int bonesCount;
-	spBoneData** bones;
-
-	int slotsCount;
-	spSlotData** slots;
-
-	int skinsCount;
-	spSkin** skins;
-	spSkin* defaultSkin;
-
-	int eventsCount;
-	spEventData** events;
-
-	int animationsCount;
-	spAnimation** animations;
-
-	int ikConstraintsCount;
-	spIkConstraintData** ikConstraints;
-
-	int transformConstraintsCount;
-	spTransformConstraintData** transformConstraints;
-
-	int pathConstraintsCount;
-	spPathConstraintData** pathConstraints;
-} spSkeletonData;
-
-spSkeletonData* spSkeletonData_create ();
-void spSkeletonData_dispose (spSkeletonData* self);
-
-spBoneData* spSkeletonData_findBone (const spSkeletonData* self, const char* boneName);
-int spSkeletonData_findBoneIndex (const spSkeletonData* self, const char* boneName);
-
-spSlotData* spSkeletonData_findSlot (const spSkeletonData* self, const char* slotName);
-int spSkeletonData_findSlotIndex (const spSkeletonData* self, const char* slotName);
-
-spSkin* spSkeletonData_findSkin (const spSkeletonData* self, const char* skinName);
-
-spEventData* spSkeletonData_findEvent (const spSkeletonData* self, const char* eventName);
-
-spAnimation* spSkeletonData_findAnimation (const spSkeletonData* self, const char* animationName);
-
-spIkConstraintData* spSkeletonData_findIkConstraint (const spSkeletonData* self, const char* constraintName);
-
-spTransformConstraintData* spSkeletonData_findTransformConstraint (const spSkeletonData* self, const char* constraintName);
-
-spPathConstraintData* spSkeletonData_findPathConstraint (const spSkeletonData* self, const char* constraintName);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spSkeletonData SkeletonData;
-#define SkeletonData_create(...) spSkeletonData_create(__VA_ARGS__)
-#define SkeletonData_dispose(...) spSkeletonData_dispose(__VA_ARGS__)
-#define SkeletonData_findBone(...) spSkeletonData_findBone(__VA_ARGS__)
-#define SkeletonData_findBoneIndex(...) spSkeletonData_findBoneIndex(__VA_ARGS__)
-#define SkeletonData_findSlot(...) spSkeletonData_findSlot(__VA_ARGS__)
-#define SkeletonData_findSlotIndex(...) spSkeletonData_findSlotIndex(__VA_ARGS__)
-#define SkeletonData_findSkin(...) spSkeletonData_findSkin(__VA_ARGS__)
-#define SkeletonData_findEvent(...) spSkeletonData_findEvent(__VA_ARGS__)
-#define SkeletonData_findAnimation(...) spSkeletonData_findAnimation(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_SKELETONDATA_H_
+#define SPINE_SKELETONDATA_H_
+
+#include <spine/BoneData.h>
+#include <spine/SlotData.h>
+#include <spine/Skin.h>
+#include <spine/EventData.h>
+#include <spine/Animation.h>
+#include <spine/IkConstraintData.h>
+#include <spine/TransformConstraintData.h>
+#include <spine/PathConstraintData.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spSkeletonData {
+	const char* version;
+	const char* hash;
+	float width, height;
+
+	int bonesCount;
+	spBoneData** bones;
+
+	int slotsCount;
+	spSlotData** slots;
+
+	int skinsCount;
+	spSkin** skins;
+	spSkin* defaultSkin;
+
+	int eventsCount;
+	spEventData** events;
+
+	int animationsCount;
+	spAnimation** animations;
+
+	int ikConstraintsCount;
+	spIkConstraintData** ikConstraints;
+
+	int transformConstraintsCount;
+	spTransformConstraintData** transformConstraints;
+
+	int pathConstraintsCount;
+	spPathConstraintData** pathConstraints;
+} spSkeletonData;
+
+spSkeletonData* spSkeletonData_create ();
+void spSkeletonData_dispose (spSkeletonData* self);
+
+spBoneData* spSkeletonData_findBone (const spSkeletonData* self, const char* boneName);
+int spSkeletonData_findBoneIndex (const spSkeletonData* self, const char* boneName);
+
+spSlotData* spSkeletonData_findSlot (const spSkeletonData* self, const char* slotName);
+int spSkeletonData_findSlotIndex (const spSkeletonData* self, const char* slotName);
+
+spSkin* spSkeletonData_findSkin (const spSkeletonData* self, const char* skinName);
+
+spEventData* spSkeletonData_findEvent (const spSkeletonData* self, const char* eventName);
+
+spAnimation* spSkeletonData_findAnimation (const spSkeletonData* self, const char* animationName);
+
+spIkConstraintData* spSkeletonData_findIkConstraint (const spSkeletonData* self, const char* constraintName);
+
+spTransformConstraintData* spSkeletonData_findTransformConstraint (const spSkeletonData* self, const char* constraintName);
+
+spPathConstraintData* spSkeletonData_findPathConstraint (const spSkeletonData* self, const char* constraintName);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spSkeletonData SkeletonData;
+#define SkeletonData_create(...) spSkeletonData_create(__VA_ARGS__)
+#define SkeletonData_dispose(...) spSkeletonData_dispose(__VA_ARGS__)
+#define SkeletonData_findBone(...) spSkeletonData_findBone(__VA_ARGS__)
+#define SkeletonData_findBoneIndex(...) spSkeletonData_findBoneIndex(__VA_ARGS__)
+#define SkeletonData_findSlot(...) spSkeletonData_findSlot(__VA_ARGS__)
+#define SkeletonData_findSlotIndex(...) spSkeletonData_findSlotIndex(__VA_ARGS__)
+#define SkeletonData_findSkin(...) spSkeletonData_findSkin(__VA_ARGS__)
+#define SkeletonData_findEvent(...) spSkeletonData_findEvent(__VA_ARGS__)
+#define SkeletonData_findAnimation(...) spSkeletonData_findAnimation(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_SKELETONDATA_H_ */

+ 69 - 70
spine-c/include/spine/SkeletonJson.h

@@ -1,73 +1,72 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_SKELETONJSON_H_
-#define SPINE_SKELETONJSON_H_
-
-#include <spine/Attachment.h>
-#include <spine/AttachmentLoader.h>
-#include <spine/SkeletonData.h>
-#include <spine/Atlas.h>
-#include <spine/Animation.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct spAtlasAttachmentLoader;
-
-typedef struct spSkeletonJson {
-	float scale;
-	spAttachmentLoader* attachmentLoader;
-	const char* const error;
-} spSkeletonJson;
-
-spSkeletonJson* spSkeletonJson_createWithLoader (spAttachmentLoader* attachmentLoader);
-spSkeletonJson* spSkeletonJson_create (spAtlas* atlas);
-void spSkeletonJson_dispose (spSkeletonJson* self);
-
-spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const char* json);
-spSkeletonData* spSkeletonJson_readSkeletonDataFile (spSkeletonJson* self, const char* path);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spSkeletonJson SkeletonJson;
-#define SkeletonJson_createWithLoader(...) spSkeletonJson_createWithLoader(__VA_ARGS__)
-#define SkeletonJson_create(...) spSkeletonJson_create(__VA_ARGS__)
-#define SkeletonJson_dispose(...) spSkeletonJson_dispose(__VA_ARGS__)
-#define SkeletonJson_readSkeletonData(...) spSkeletonJson_readSkeletonData(__VA_ARGS__)
-#define SkeletonJson_readSkeletonDataFile(...) spSkeletonJson_readSkeletonDataFile(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_SKELETONJSON_H_
+#define SPINE_SKELETONJSON_H_
+
+#include <spine/Attachment.h>
+#include <spine/AttachmentLoader.h>
+#include <spine/SkeletonData.h>
+#include <spine/Atlas.h>
+#include <spine/Animation.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct spAtlasAttachmentLoader;
+
+typedef struct spSkeletonJson {
+	float scale;
+	spAttachmentLoader* attachmentLoader;
+	const char* const error;
+} spSkeletonJson;
+
+spSkeletonJson* spSkeletonJson_createWithLoader (spAttachmentLoader* attachmentLoader);
+spSkeletonJson* spSkeletonJson_create (spAtlas* atlas);
+void spSkeletonJson_dispose (spSkeletonJson* self);
+
+spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const char* json);
+spSkeletonData* spSkeletonJson_readSkeletonDataFile (spSkeletonJson* self, const char* path);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spSkeletonJson SkeletonJson;
+#define SkeletonJson_createWithLoader(...) spSkeletonJson_createWithLoader(__VA_ARGS__)
+#define SkeletonJson_create(...) spSkeletonJson_create(__VA_ARGS__)
+#define SkeletonJson_dispose(...) spSkeletonJson_dispose(__VA_ARGS__)
+#define SkeletonJson_readSkeletonData(...) spSkeletonJson_readSkeletonData(__VA_ARGS__)
+#define SkeletonJson_readSkeletonDataFile(...) spSkeletonJson_readSkeletonDataFile(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_SKELETONJSON_H_ */

+ 91 - 92
spine-c/include/spine/Skin.h

@@ -1,95 +1,94 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_SKIN_H_
-#define SPINE_SKIN_H_
-
-#include <spine/Attachment.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct spSkeleton;
-
-typedef struct spSkin {
-	const char* const name;
-
-#ifdef __cplusplus
-	spSkin() :
-		name(0) {
-	}
-#endif
-} spSkin;
-
-/* Private structs, needed by Skeleton */
-typedef struct _Entry _Entry;
-struct _Entry {
-	int slotIndex;
-	const char* name;
-	spAttachment* attachment;
-	_Entry* next;
-};
-
-typedef struct {
-	spSkin super;
-	_Entry* entries;
-} _spSkin;
-
-spSkin* spSkin_create (const char* name);
-void spSkin_dispose (spSkin* self);
-
-/* The Skin owns the attachment. */
-void spSkin_addAttachment (spSkin* self, int slotIndex, const char* name, spAttachment* attachment);
-/* Returns 0 if the attachment was not found. */
-spAttachment* spSkin_getAttachment (const spSkin* self, int slotIndex, const char* name);
-
-/* Returns 0 if the slot or attachment was not found. */
-const char* spSkin_getAttachmentName (const spSkin* self, int slotIndex, int attachmentIndex);
-
-/** Attach each attachment in this skin if the corresponding attachment in oldSkin is currently attached. */
-void spSkin_attachAll (const spSkin* self, struct spSkeleton* skeleton, const spSkin* oldspSkin);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spSkin Skin;
-#define Skin_create(...) spSkin_create(__VA_ARGS__)
-#define Skin_dispose(...) spSkin_dispose(__VA_ARGS__)
-#define Skin_addAttachment(...) spSkin_addAttachment(__VA_ARGS__)
-#define Skin_getAttachment(...) spSkin_getAttachment(__VA_ARGS__)
-#define Skin_getAttachmentName(...) spSkin_getAttachmentName(__VA_ARGS__)
-#define Skin_attachAll(...) spSkin_attachAll(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_SKIN_H_
+#define SPINE_SKIN_H_
+
+#include <spine/Attachment.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct spSkeleton;
+
+typedef struct spSkin {
+	const char* const name;
+
+#ifdef __cplusplus
+	spSkin() :
+		name(0) {
+	}
+#endif
+} spSkin;
+
+/* Private structs, needed by Skeleton */
+typedef struct _Entry _Entry;
+struct _Entry {
+	int slotIndex;
+	const char* name;
+	spAttachment* attachment;
+	_Entry* next;
+};
+
+typedef struct {
+	spSkin super;
+	_Entry* entries;
+} _spSkin;
+
+spSkin* spSkin_create (const char* name);
+void spSkin_dispose (spSkin* self);
+
+/* The Skin owns the attachment. */
+void spSkin_addAttachment (spSkin* self, int slotIndex, const char* name, spAttachment* attachment);
+/* Returns 0 if the attachment was not found. */
+spAttachment* spSkin_getAttachment (const spSkin* self, int slotIndex, const char* name);
+
+/* Returns 0 if the slot or attachment was not found. */
+const char* spSkin_getAttachmentName (const spSkin* self, int slotIndex, int attachmentIndex);
+
+/** Attach each attachment in this skin if the corresponding attachment in oldSkin is currently attached. */
+void spSkin_attachAll (const spSkin* self, struct spSkeleton* skeleton, const spSkin* oldspSkin);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spSkin Skin;
+#define Skin_create(...) spSkin_create(__VA_ARGS__)
+#define Skin_dispose(...) spSkin_dispose(__VA_ARGS__)
+#define Skin_addAttachment(...) spSkin_addAttachment(__VA_ARGS__)
+#define Skin_getAttachment(...) spSkin_getAttachment(__VA_ARGS__)
+#define Skin_getAttachmentName(...) spSkin_getAttachmentName(__VA_ARGS__)
+#define Skin_attachAll(...) spSkin_attachAll(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_SKIN_H_ */

+ 87 - 88
spine-c/include/spine/Slot.h

@@ -1,91 +1,90 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_SLOT_H_
-#define SPINE_SLOT_H_
-
-#include <spine/Bone.h>
-#include <spine/Attachment.h>
-#include <spine/SlotData.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spSlot {
-	spSlotData* const data;
-	spBone* const bone;
-	float r, g, b, a;
-	spAttachment* const attachment;
-
-	int attachmentVerticesCapacity;
-	int attachmentVerticesCount;
-	float* attachmentVertices;
-
-#ifdef __cplusplus
-	spSlot() :
-		data(0),
-		bone(0),
-		r(0), g(0), b(0), a(0),
-		attachment(0),
-		attachmentVerticesCapacity(0),
-		attachmentVerticesCount(0),
-		attachmentVertices(0) {
-	}
-#endif
-} spSlot;
-
-spSlot* spSlot_create (spSlotData* data, spBone* bone);
-void spSlot_dispose (spSlot* self);
-
-/* @param attachment May be 0 to clear the attachment for the slot. */
-void spSlot_setAttachment (spSlot* self, spAttachment* attachment);
-
-void spSlot_setAttachmentTime (spSlot* self, float time);
-float spSlot_getAttachmentTime (const spSlot* self);
-
-void spSlot_setToSetupPose (spSlot* self);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spSlot Slot;
-#define Slot_create(...) spSlot_create(__VA_ARGS__)
-#define Slot_dispose(...) spSlot_dispose(__VA_ARGS__)
-#define Slot_setAttachment(...) spSlot_setAttachment(__VA_ARGS__)
-#define Slot_setAttachmentTime(...) spSlot_setAttachmentTime(__VA_ARGS__)
-#define Slot_getAttachmentTime(...) spSlot_getAttachmentTime(__VA_ARGS__)
-#define Slot_setToSetupPose(...) spSlot_setToSetupPose(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_SLOT_H_
+#define SPINE_SLOT_H_
+
+#include <spine/Bone.h>
+#include <spine/Attachment.h>
+#include <spine/SlotData.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spSlot {
+	spSlotData* const data;
+	spBone* const bone;
+	float r, g, b, a;
+	spAttachment* const attachment;
+
+	int attachmentVerticesCapacity;
+	int attachmentVerticesCount;
+	float* attachmentVertices;
+
+#ifdef __cplusplus
+	spSlot() :
+		data(0),
+		bone(0),
+		r(0), g(0), b(0), a(0),
+		attachment(0),
+		attachmentVerticesCapacity(0),
+		attachmentVerticesCount(0),
+		attachmentVertices(0) {
+	}
+#endif
+} spSlot;
+
+spSlot* spSlot_create (spSlotData* data, spBone* bone);
+void spSlot_dispose (spSlot* self);
+
+/* @param attachment May be 0 to clear the attachment for the slot. */
+void spSlot_setAttachment (spSlot* self, spAttachment* attachment);
+
+void spSlot_setAttachmentTime (spSlot* self, float time);
+float spSlot_getAttachmentTime (const spSlot* self);
+
+void spSlot_setToSetupPose (spSlot* self);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spSlot Slot;
+#define Slot_create(...) spSlot_create(__VA_ARGS__)
+#define Slot_dispose(...) spSlot_dispose(__VA_ARGS__)
+#define Slot_setAttachment(...) spSlot_setAttachment(__VA_ARGS__)
+#define Slot_setAttachmentTime(...) spSlot_setAttachmentTime(__VA_ARGS__)
+#define Slot_getAttachmentTime(...) spSlot_getAttachmentTime(__VA_ARGS__)
+#define Slot_setToSetupPose(...) spSlot_setToSetupPose(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_SLOT_H_ */

+ 83 - 84
spine-c/include/spine/SlotData.h

@@ -1,87 +1,86 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_SLOTDATA_H_
-#define SPINE_SLOTDATA_H_
-
-#include <spine/BoneData.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
-	SP_BLEND_MODE_NORMAL, SP_BLEND_MODE_ADDITIVE, SP_BLEND_MODE_MULTIPLY, SP_BLEND_MODE_SCREEN
-} spBlendMode;
-
-typedef struct spSlotData {
-	const int index;
-	const char* const name;
-	const spBoneData* const boneData;
-	const char* attachmentName;
-	float r, g, b, a;
-	spBlendMode blendMode;
-
-#ifdef __cplusplus
-	spSlotData() :
-		index(0),
-		name(0),
-		boneData(0),
-		attachmentName(0),
-		r(0), g(0), b(0), a(0),
-		blendMode(SP_BLEND_MODE_NORMAL) {
-	}
-#endif
-} spSlotData;
-
-spSlotData* spSlotData_create (const int index, const char* name, spBoneData* boneData);
-void spSlotData_dispose (spSlotData* self);
-
-/* @param attachmentName May be 0 for no setup pose attachment. */
-void spSlotData_setAttachmentName (spSlotData* self, const char* attachmentName);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spBlendMode BlendMode;
-#define BLEND_MODE_NORMAL SP_BLEND_MODE_NORMAL
-#define BLEND_MODE_ADDITIVE SP_BLEND_MODE_ADDITIVE
-#define BLEND_MODE_MULTIPLY SP_BLEND_MODE_MULTIPLY
-#define BLEND_MODE_SCREEN SP_BLEND_MODE_SCREEN
-typedef spSlotData SlotData;
-#define SlotData_create(...) spSlotData_create(__VA_ARGS__)
-#define SlotData_dispose(...) spSlotData_dispose(__VA_ARGS__)
-#define SlotData_setAttachmentName(...) spSlotData_setAttachmentName(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_SLOTDATA_H_
+#define SPINE_SLOTDATA_H_
+
+#include <spine/BoneData.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+	SP_BLEND_MODE_NORMAL, SP_BLEND_MODE_ADDITIVE, SP_BLEND_MODE_MULTIPLY, SP_BLEND_MODE_SCREEN
+} spBlendMode;
+
+typedef struct spSlotData {
+	const int index;
+	const char* const name;
+	const spBoneData* const boneData;
+	const char* attachmentName;
+	float r, g, b, a;
+	spBlendMode blendMode;
+
+#ifdef __cplusplus
+	spSlotData() :
+		index(0),
+		name(0),
+		boneData(0),
+		attachmentName(0),
+		r(0), g(0), b(0), a(0),
+		blendMode(SP_BLEND_MODE_NORMAL) {
+	}
+#endif
+} spSlotData;
+
+spSlotData* spSlotData_create (const int index, const char* name, spBoneData* boneData);
+void spSlotData_dispose (spSlotData* self);
+
+/* @param attachmentName May be 0 for no setup pose attachment. */
+void spSlotData_setAttachmentName (spSlotData* self, const char* attachmentName);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spBlendMode BlendMode;
+#define BLEND_MODE_NORMAL SP_BLEND_MODE_NORMAL
+#define BLEND_MODE_ADDITIVE SP_BLEND_MODE_ADDITIVE
+#define BLEND_MODE_MULTIPLY SP_BLEND_MODE_MULTIPLY
+#define BLEND_MODE_SCREEN SP_BLEND_MODE_SCREEN
+typedef spSlotData SlotData;
+#define SlotData_create(...) spSlotData_create(__VA_ARGS__)
+#define SlotData_dispose(...) spSlotData_dispose(__VA_ARGS__)
+#define SlotData_setAttachmentName(...) spSlotData_setAttachmentName(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_SLOTDATA_H_ */

+ 77 - 78
spine-c/include/spine/TransformConstraint.h

@@ -1,81 +1,80 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_TRANSFORMCONSTRAINT_H_
-#define SPINE_TRANSFORMCONSTRAINT_H_
-
-#include <spine/TransformConstraintData.h>
-#include <spine/Bone.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct spSkeleton;
-
-typedef struct spTransformConstraint {
-	spTransformConstraintData* const data;
-	int bonesCount;
-	spBone** const bones;
-	spBone* target;
-	float rotateMix, translateMix, scaleMix, shearMix;
-
-#ifdef __cplusplus
-	spTransformConstraint() :
-		data(0),
-		bonesCount(0),
-		bones(0),
-		target(0),
-		rotateMix(0),
-		translateMix(0),
-		scaleMix(0),
-		shearMix(0) {
-	}
-#endif
-} spTransformConstraint;
-
-spTransformConstraint* spTransformConstraint_create (spTransformConstraintData* data, const struct spSkeleton* skeleton);
-void spTransformConstraint_dispose (spTransformConstraint* self);
-
-void spTransformConstraint_apply (spTransformConstraint* self);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spTransformConstraint TransformConstraint;
-#define TransformConstraint_create(...) spTransformConstraint_create(__VA_ARGS__)
-#define TransformConstraint_dispose(...) spTransformConstraint_dispose(__VA_ARGS__)
-#define TransformConstraint_apply(...) spTransformConstraint_apply(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_TRANSFORMCONSTRAINT_H_
+#define SPINE_TRANSFORMCONSTRAINT_H_
+
+#include <spine/TransformConstraintData.h>
+#include <spine/Bone.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct spSkeleton;
+
+typedef struct spTransformConstraint {
+	spTransformConstraintData* const data;
+	int bonesCount;
+	spBone** const bones;
+	spBone* target;
+	float rotateMix, translateMix, scaleMix, shearMix;
+
+#ifdef __cplusplus
+	spTransformConstraint() :
+		data(0),
+		bonesCount(0),
+		bones(0),
+		target(0),
+		rotateMix(0),
+		translateMix(0),
+		scaleMix(0),
+		shearMix(0) {
+	}
+#endif
+} spTransformConstraint;
+
+spTransformConstraint* spTransformConstraint_create (spTransformConstraintData* data, const struct spSkeleton* skeleton);
+void spTransformConstraint_dispose (spTransformConstraint* self);
+
+void spTransformConstraint_apply (spTransformConstraint* self);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spTransformConstraint TransformConstraint;
+#define TransformConstraint_create(...) spTransformConstraint_create(__VA_ARGS__)
+#define TransformConstraint_dispose(...) spTransformConstraint_dispose(__VA_ARGS__)
+#define TransformConstraint_apply(...) spTransformConstraint_apply(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_TRANSFORMCONSTRAINT_H_ */

+ 78 - 79
spine-c/include/spine/TransformConstraintData.h

@@ -1,82 +1,81 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_TRANSFORMCONSTRAINTDATA_H_
-#define SPINE_TRANSFORMCONSTRAINTDATA_H_
-
-#include <spine/BoneData.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spTransformConstraintData {
-	const char* const name;
-	int bonesCount;
-	spBoneData** const bones;
-	spBoneData* target;
-	float rotateMix, translateMix, scaleMix, shearMix;
-	float offsetRotation, offsetX, offsetY, offsetScaleX, offsetScaleY, offsetShearY;
-
-#ifdef __cplusplus
-	spTransformConstraintData() :
-		name(0),
-		bonesCount(0),
-		bones(0),
-		target(0),
-		rotateMix(0),
-		translateMix(0),
-		scaleMix(0),
-		shearMix(0),
-		offsetRotation(0),
-		offsetX(0),
-		offsetY(0),
-		offsetScaleX(0),
-		offsetScaleY(0),
-		offsetShearY(0) {
-	}
-#endif
-} spTransformConstraintData;
-
-spTransformConstraintData* spTransformConstraintData_create (const char* name);
-void spTransformConstraintData_dispose (spTransformConstraintData* self);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spTransformConstraintData TransformConstraintData;
-#define TransformConstraintData_create(...) spTransformConstraintData_create(__VA_ARGS__)
-#define TransformConstraintData_dispose(...) spTransformConstraintData_dispose(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_TRANSFORMCONSTRAINTDATA_H_
+#define SPINE_TRANSFORMCONSTRAINTDATA_H_
+
+#include <spine/BoneData.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spTransformConstraintData {
+	const char* const name;
+	int bonesCount;
+	spBoneData** const bones;
+	spBoneData* target;
+	float rotateMix, translateMix, scaleMix, shearMix;
+	float offsetRotation, offsetX, offsetY, offsetScaleX, offsetScaleY, offsetShearY;
+
+#ifdef __cplusplus
+	spTransformConstraintData() :
+		name(0),
+		bonesCount(0),
+		bones(0),
+		target(0),
+		rotateMix(0),
+		translateMix(0),
+		scaleMix(0),
+		shearMix(0),
+		offsetRotation(0),
+		offsetX(0),
+		offsetY(0),
+		offsetScaleX(0),
+		offsetScaleY(0),
+		offsetShearY(0) {
+	}
+#endif
+} spTransformConstraintData;
+
+spTransformConstraintData* spTransformConstraintData_create (const char* name);
+void spTransformConstraintData_dispose (spTransformConstraintData* self);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spTransformConstraintData TransformConstraintData;
+#define TransformConstraintData_create(...) spTransformConstraintData_create(__VA_ARGS__)
+#define TransformConstraintData_dispose(...) spTransformConstraintData_dispose(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_TRANSFORMCONSTRAINTDATA_H_ */

+ 64 - 65
spine-c/include/spine/VertexAttachment.h

@@ -1,68 +1,67 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_VERTEXATTACHMENT_H_
-#define SPINE_VERTEXATTACHMENT_H_
-
-#include <spine/Attachment.h>
-#include <spine/Slot.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct spVertexAttachment spVertexAttachment;
-struct spVertexAttachment {
-	spAttachment super;
-
-	int bonesCount;
-	int* bones;
-
-	int verticesCount;
-	float* vertices;
-
-	int worldVerticesLength;
-};
-
-void spVertexAttachment_computeWorldVertices (spVertexAttachment* self, spSlot* slot, float* worldVertices);
-void spVertexAttachment_computeWorldVertices1 (spVertexAttachment* self, int start, int count, spSlot* slot, float* worldVertices, int offset);
-
-#ifdef SPINE_SHORT_NAMES
-typedef spVertexAttachment VertexAttachment;
-#define VertexAttachment_computeWorldVertices(...) spVertexAttachment_computeWorldVertices(__VA_ARGS__)
-#define VertexAttachment_computeWorldVertices1(...) spVertexAttachment_computeWorldVertices1(__VA_ARGS__)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifndef SPINE_VERTEXATTACHMENT_H_
+#define SPINE_VERTEXATTACHMENT_H_
+
+#include <spine/Attachment.h>
+#include <spine/Slot.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spVertexAttachment spVertexAttachment;
+struct spVertexAttachment {
+	spAttachment super;
+
+	int bonesCount;
+	int* bones;
+
+	int verticesCount;
+	float* vertices;
+
+	int worldVerticesLength;
+};
+
+void spVertexAttachment_computeWorldVertices (spVertexAttachment* self, spSlot* slot, float* worldVertices);
+void spVertexAttachment_computeWorldVertices1 (spVertexAttachment* self, int start, int count, spSlot* slot, float* worldVertices, int offset);
+
+#ifdef SPINE_SHORT_NAMES
+typedef spVertexAttachment VertexAttachment;
+#define VertexAttachment_computeWorldVertices(...) spVertexAttachment_computeWorldVertices(__VA_ARGS__)
+#define VertexAttachment_computeWorldVertices1(...) spVertexAttachment_computeWorldVertices1(__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPINE_VERTEXATTACHMENT_H_ */

+ 55 - 56
spine-c/include/spine/spine.h

@@ -1,59 +1,58 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#ifndef SPINE_SPINE_H_
-#define SPINE_SPINE_H_
-
-#include <spine/Animation.h>
-#include <spine/AnimationState.h>
-#include <spine/AnimationStateData.h>
-#include <spine/Atlas.h>
-#include <spine/AtlasAttachmentLoader.h>
-#include <spine/Attachment.h>
-#include <spine/AttachmentLoader.h>
-#include <spine/Bone.h>
-#include <spine/BoneData.h>
-#include <spine/RegionAttachment.h>
-#include <spine/VertexAttachment.h>
-#include <spine/MeshAttachment.h>
-#include <spine/BoundingBoxAttachment.h>
-#include <spine/Skeleton.h>
-#include <spine/SkeletonBounds.h>
-#include <spine/SkeletonData.h>
-#include <spine/SkeletonBinary.h>
-#include <spine/SkeletonJson.h>
-#include <spine/Skin.h>
-#include <spine/Slot.h>
-#include <spine/SlotData.h>
-#include <spine/Event.h>
-#include <spine/EventData.h>
-
+#ifndef SPINE_SPINE_H_
+#define SPINE_SPINE_H_
+
+#include <spine/Animation.h>
+#include <spine/AnimationState.h>
+#include <spine/AnimationStateData.h>
+#include <spine/Atlas.h>
+#include <spine/AtlasAttachmentLoader.h>
+#include <spine/Attachment.h>
+#include <spine/AttachmentLoader.h>
+#include <spine/Bone.h>
+#include <spine/BoneData.h>
+#include <spine/RegionAttachment.h>
+#include <spine/VertexAttachment.h>
+#include <spine/MeshAttachment.h>
+#include <spine/BoundingBoxAttachment.h>
+#include <spine/Skeleton.h>
+#include <spine/SkeletonBounds.h>
+#include <spine/SkeletonData.h>
+#include <spine/SkeletonBinary.h>
+#include <spine/SkeletonJson.h>
+#include <spine/Skin.h>
+#include <spine/Slot.h>
+#include <spine/SlotData.h>
+#include <spine/Event.h>
+#include <spine/EventData.h>
+
 #endif /* SPINE_SPINE_H_ */

+ 1052 - 1053
spine-c/src/spine/Animation.c

@@ -1,1056 +1,1055 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#include <spine/Animation.h>
-#include <spine/IkConstraint.h>
-#include <limits.h>
-#include <spine/extension.h>
-
-spAnimation* spAnimation_create (const char* name, int timelinesCount) {
-	spAnimation* self = NEW(spAnimation);
-	MALLOC_STR(self->name, name);
-	self->timelinesCount = timelinesCount;
-	self->timelines = MALLOC(spTimeline*, timelinesCount);
-	return self;
-}
-
-void spAnimation_dispose (spAnimation* self) {
-	int i;
-	for (i = 0; i < self->timelinesCount; ++i)
-		spTimeline_dispose(self->timelines[i]);
-	FREE(self->timelines);
-	FREE(self->name);
-	FREE(self);
-}
-
-void spAnimation_apply (const spAnimation* self, spSkeleton* skeleton, float lastTime, float time, int loop, spEvent** events,
-		int* eventsCount) {
-	int i, n = self->timelinesCount;
-
-	if (loop && self->duration) {
-		time = FMOD(time, self->duration);
-		if (lastTime > 0) lastTime = FMOD(lastTime, self->duration);
-	}
-
-	for (i = 0; i < n; ++i)
-		spTimeline_apply(self->timelines[i], skeleton, lastTime, time, events, eventsCount, 1);
-}
-
-void spAnimation_mix (const spAnimation* self, spSkeleton* skeleton, float lastTime, float time, int loop, spEvent** events,
-		int* eventsCount, float alpha) {
-	int i, n = self->timelinesCount;
-
-	if (loop && self->duration) {
-		time = FMOD(time, self->duration);
-		if (lastTime > 0) lastTime = FMOD(lastTime, self->duration);
-	}
-
-	for (i = 0; i < n; ++i)
-		spTimeline_apply(self->timelines[i], skeleton, lastTime, time, events, eventsCount, alpha);
-}
-
-/**/
-
-typedef struct _spTimelineVtable {
-	void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
-			int* eventsCount, float alpha);
-	void (*dispose) (spTimeline* self);
-} _spTimelineVtable;
-
-void _spTimeline_init (spTimeline* self, spTimelineType type, /**/
-void (*dispose) (spTimeline* self), /**/
-		void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
-				int* eventsCount, float alpha)) {
-	CONST_CAST(spTimelineType, self->type) = type;
-	CONST_CAST(_spTimelineVtable*, self->vtable) = NEW(_spTimelineVtable);
-	VTABLE(spTimeline, self)->dispose = dispose;
-	VTABLE(spTimeline, self)->apply = apply;
-}
-
-void _spTimeline_deinit (spTimeline* self) {
-	FREE(self->vtable);
-}
-
-void spTimeline_dispose (spTimeline* self) {
-	VTABLE(spTimeline, self)->dispose(self);
-}
-
-void spTimeline_apply (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
-		int* eventsCount, float alpha) {
-	VTABLE(spTimeline, self)->apply(self, skeleton, lastTime, time, firedEvents, eventsCount, alpha);
-}
-
-/**/
-
-static const float CURVE_LINEAR = 0, CURVE_STEPPED = 1, CURVE_BEZIER = 2;
-static const int BEZIER_SIZE = 10 * 2 - 1;
-
-void _spCurveTimeline_init (spCurveTimeline* self, spTimelineType type, int framesCount, /**/
-void (*dispose) (spTimeline* self), /**/
-		void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
-				int* eventsCount, float alpha)) {
-	_spTimeline_init(SUPER(self), type, dispose, apply);
-	self->curves = CALLOC(float, (framesCount - 1) * BEZIER_SIZE);
-}
-
-void _spCurveTimeline_deinit (spCurveTimeline* self) {
-	_spTimeline_deinit(SUPER(self));
-	FREE(self->curves);
-}
-
-void spCurveTimeline_setLinear (spCurveTimeline* self, int frameIndex) {
-	self->curves[frameIndex * BEZIER_SIZE] = CURVE_LINEAR;
-}
-
-void spCurveTimeline_setStepped (spCurveTimeline* self, int frameIndex) {
-	self->curves[frameIndex * BEZIER_SIZE] = CURVE_STEPPED;
-}
-
-void spCurveTimeline_setCurve (spCurveTimeline* self, int frameIndex, float cx1, float cy1, float cx2, float cy2) {
-	float tmpx = (-cx1 * 2 + cx2) * 0.03f, tmpy = (-cy1 * 2 + cy2) * 0.03f;
-	float dddfx = ((cx1 - cx2) * 3 + 1) * 0.006f, dddfy = ((cy1 - cy2) * 3 + 1) * 0.006f;
-	float ddfx = tmpx * 2 + dddfx, ddfy = tmpy * 2 + dddfy;
-	float dfx = cx1 * 0.3f + tmpx + dddfx * 0.16666667f, dfy = cy1 * 0.3f + tmpy + dddfy * 0.16666667f;
-	float x = dfx, y = dfy;
-
-	int i = frameIndex * BEZIER_SIZE, n = i + BEZIER_SIZE - 1;
-	self->curves[i++] = CURVE_BEZIER;
-
-	for (; i < n; i += 2) {
-		self->curves[i] = x;
-		self->curves[i + 1] = y;
-		dfx += ddfx;
-		dfy += ddfy;
-		ddfx += dddfx;
-		ddfy += dddfy;
-		x += dfx;
-		y += dfy;
-	}
-}
-
-float spCurveTimeline_getCurvePercent (const spCurveTimeline* self, int frameIndex, float percent) {
-	float x, y;
-	int i = frameIndex * BEZIER_SIZE, start, n;
-	float type = self->curves[i];
-	percent = CLAMP(percent, 0, 1);
-	if (type == CURVE_LINEAR) return percent;
-	if (type == CURVE_STEPPED) return 0;
-	i++;
-	x = 0;
-	for (start = i, n = i + BEZIER_SIZE - 1; i < n; i += 2) {
-		x = self->curves[i];
-		if (x >= percent) {
-			float prevX, prevY;
-			if (i == start) {
-				prevX = 0;
-				prevY = 0;
-			} else {
-				prevX = self->curves[i - 2];
-				prevY = self->curves[i - 1];
-			}
-			return prevY + (self->curves[i + 1] - prevY) * (percent - prevX) / (x - prevX);
-		}
-	}
-	y = self->curves[i - 1];
-	return y + (1 - y) * (percent - x) / (1 - x); /* Last point is 1,1. */
-}
-
-/* @param target After the first and before the last entry. */
-static int binarySearch (float *values, int valuesLength, float target, int step) {
-	int low = 0, current;
-	int high = valuesLength / step - 2;
-	if (high == 0) return step;
-	current = high >> 1;
-	while (1) {
-		if (values[(current + 1) * step] <= target)
-			low = current + 1;
-		else
-			high = current;
-		if (low == high) return (low + 1) * step;
-		current = (low + high) >> 1;
-	}
-	return 0;
-}
-
-/* @param target After the first and before the last entry. */
-static int binarySearch1 (float *values, int valuesLength, float target) {
-	int low = 0, current;
-	int high = valuesLength - 2;
-	if (high == 0) return 1;
-	current = high >> 1;
-	while (1) {
-		if (values[(current + 1)] <= target)
-			low = current + 1;
-		else
-			high = current;
-		if (low == high) return low + 1;
-		current = (low + high) >> 1;
-	}
-	return 0;
-}
-
-/**/
-
-void _spBaseTimeline_dispose (spTimeline* timeline) {
-	struct spBaseTimeline* self = SUB_CAST(struct spBaseTimeline, timeline);
-	_spCurveTimeline_deinit(SUPER(self));
-	FREE(self->frames);
-	FREE(self);
-}
-
-/* Many timelines have structure identical to struct spBaseTimeline and extend spCurveTimeline. **/
-struct spBaseTimeline* _spBaseTimeline_create (int framesCount, spTimelineType type, int frameSize, /**/
-		void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
-				int* eventsCount, float alpha)) {
-	struct spBaseTimeline* self = NEW(struct spBaseTimeline);
-	_spCurveTimeline_init(SUPER(self), type, framesCount, _spBaseTimeline_dispose, apply);
-
-	CONST_CAST(int, self->framesCount) = framesCount * frameSize;
-	CONST_CAST(float*, self->frames) = CALLOC(float, self->framesCount);
-
-	return self;
-}
-
-/**/
-
-static const int ROTATE_PREV_TIME = -2, ROTATE_PREV_ROTATION = -1;
-static const int ROTATE_ROTATION = 1;
-
-void _spRotateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
-		int* eventsCount, float alpha) {
-	spBone *bone;
-	int frame;
-	float prevRotation, frameTime, percent, amount;
-
-	spRotateTimeline* self = SUB_CAST(spRotateTimeline, timeline);
-
-	if (time < self->frames[0]) return; /* Time is before first frame. */
-
-	bone = skeleton->bones[self->boneIndex];
-
-	if (time >= self->frames[self->framesCount - ROTATE_ENTRIES]) { /* Time is after last frame. */
-		amount = bone->data->rotation + self->frames[self->framesCount + ROTATE_PREV_ROTATION] - bone->rotation;
-		while (amount > 180)
-			amount -= 360;
-		while (amount < -180)
-			amount += 360;
-		bone->rotation += amount * alpha;
-		return;
-	}
-
-	/* Interpolate between the previous frame and the current frame. */
-	frame = binarySearch(self->frames, self->framesCount, time, ROTATE_ENTRIES);
-	prevRotation = self->frames[frame + ROTATE_PREV_ROTATION];
-	frameTime = self->frames[frame];
-	percent = spCurveTimeline_getCurvePercent(SUPER(self), (frame >> 1) - 1, 1 - (time - frameTime) / (self->frames[frame + ROTATE_PREV_TIME] - frameTime));
-
-	amount = self->frames[frame + ROTATE_ROTATION] - prevRotation;
-	while (amount > 180)
-		amount -= 360;
-	while (amount < -180)
-		amount += 360;
-	amount = bone->data->rotation + (prevRotation + amount * percent) - bone->rotation;
-	while (amount > 180)
-		amount -= 360;
-	while (amount < -180)
-		amount += 360;
-	bone->rotation += amount * alpha;
-
-	UNUSED(lastTime);
-	UNUSED(firedEvents);
-	UNUSED(eventsCount);
-}
-
-spRotateTimeline* spRotateTimeline_create (int framesCount) {
-	return _spBaseTimeline_create(framesCount, SP_TIMELINE_ROTATE, ROTATE_ENTRIES, _spRotateTimeline_apply);
-}
-
-void spRotateTimeline_setFrame (spRotateTimeline* self, int frameIndex, float time, float degrees) {
-	frameIndex <<= 1;
-	self->frames[frameIndex] = time;
-	self->frames[frameIndex + ROTATE_ROTATION] = degrees;
-}
-
-/**/
-
-static const int TRANSLATE_PREV_TIME = -3, TRANSLATE_PREV_X = -2, TRANSLATE_PREV_Y = -1;
-static const int TRANSLATE_X = 1, TRANSLATE_Y = 2;
-
-void _spTranslateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
-		spEvent** firedEvents, int* eventsCount, float alpha) {
-	spBone *bone;
-	int frame;
-	float prevX, prevY, frameTime, percent;
-
-	spTranslateTimeline* self = SUB_CAST(spTranslateTimeline, timeline);
-
-	if (time < self->frames[0]) return; /* Time is before first frame. */
-
-	bone = skeleton->bones[self->boneIndex];
-
-	if (time >= self->frames[self->framesCount - TRANSLATE_ENTRIES]) { /* Time is after last frame. */
-		bone->x += (bone->data->x + self->frames[self->framesCount + TRANSLATE_PREV_X] - bone->x) * alpha;
-		bone->y += (bone->data->y + self->frames[self->framesCount + TRANSLATE_PREV_Y] - bone->y) * alpha;
-		return;
-	}
-
-	/* Interpolate between the previous frame and the current frame. */
-	frame = binarySearch(self->frames, self->framesCount, time, TRANSLATE_ENTRIES);
-	prevX = self->frames[frame + TRANSLATE_PREV_X];
-	prevY = self->frames[frame + TRANSLATE_PREV_Y];
-	frameTime = self->frames[frame];
-	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + TRANSLATE_PREV_TIME] - frameTime));
-
-	bone->x += (bone->data->x + prevX + (self->frames[frame + TRANSLATE_X] - prevX) * percent - bone->x) * alpha;
-	bone->y += (bone->data->y + prevY + (self->frames[frame + TRANSLATE_Y] - prevY) * percent - bone->y) * alpha;
-
-	UNUSED(lastTime);
-	UNUSED(firedEvents);
-	UNUSED(eventsCount);
-}
-
-spTranslateTimeline* spTranslateTimeline_create (int framesCount) {
-	return _spBaseTimeline_create(framesCount, SP_TIMELINE_TRANSLATE, TRANSLATE_ENTRIES, _spTranslateTimeline_apply);
-}
-
-void spTranslateTimeline_setFrame (spTranslateTimeline* self, int frameIndex, float time, float x, float y) {
-	frameIndex *= TRANSLATE_ENTRIES;
-	self->frames[frameIndex] = time;
-	self->frames[frameIndex + TRANSLATE_X] = x;
-	self->frames[frameIndex + TRANSLATE_Y] = y;
-}
-
-/**/
-
-void _spScaleTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
-		int* eventsCount, float alpha) {
-	spBone *bone;
-	int frame;
-	float prevX, prevY, frameTime, percent;
-
-	spScaleTimeline* self = SUB_CAST(spScaleTimeline, timeline);
-
-	if (time < self->frames[0]) return; /* Time is before first frame. */
-
-	bone = skeleton->bones[self->boneIndex];
-	if (time >= self->frames[self->framesCount - TRANSLATE_ENTRIES]) { /* Time is after last frame. */
-		bone->scaleX += (bone->data->scaleX * self->frames[self->framesCount + TRANSLATE_PREV_X] - bone->scaleX) * alpha;
-		bone->scaleY += (bone->data->scaleY * self->frames[self->framesCount + TRANSLATE_PREV_Y] - bone->scaleY) * alpha;
-		return;
-	}
-
-	/* Interpolate between the previous frame and the current frame. */
-	frame = binarySearch(self->frames, self->framesCount, time, TRANSLATE_ENTRIES);
-	prevX = self->frames[frame + TRANSLATE_PREV_X];
-	prevY = self->frames[frame + TRANSLATE_PREV_Y];
-	frameTime = self->frames[frame];
-	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + TRANSLATE_PREV_TIME] - frameTime));
-
-	bone->scaleX += (bone->data->scaleX * (prevX + (self->frames[frame + TRANSLATE_X] - prevX) * percent) - bone->scaleX) * alpha;
-	bone->scaleY += (bone->data->scaleY * (prevY + (self->frames[frame + TRANSLATE_Y] - prevY) * percent) - bone->scaleY) * alpha;
-
-	UNUSED(lastTime);
-	UNUSED(firedEvents);
-	UNUSED(eventsCount);
-}
-
-spScaleTimeline* spScaleTimeline_create (int framesCount) {
-	return _spBaseTimeline_create(framesCount, SP_TIMELINE_SCALE, TRANSLATE_ENTRIES, _spScaleTimeline_apply);
-}
-
-void spScaleTimeline_setFrame (spScaleTimeline* self, int frameIndex, float time, float x, float y) {
-	spTranslateTimeline_setFrame(self, frameIndex, time, x, y);
-}
-
-/**/
-
-void _spShearTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
-							 int* eventsCount, float alpha) {
-	spBone *bone;
-	int frame;
-	float prevX, prevY, frameTime, percent;
-
-	spShearTimeline* self = SUB_CAST(spShearTimeline, timeline);
-
-	if (time < self->frames[0]) return; /* Time is before first frame. */
-
-	bone = skeleton->bones[self->boneIndex];
-	if (time >= self->frames[self->framesCount - TRANSLATE_ENTRIES]) { /* Time is after last frame. */
-		bone->shearX += (bone->data->shearX + self->frames[self->framesCount + TRANSLATE_PREV_X] - bone->shearX) * alpha;
-		bone->shearY += (bone->data->shearY + self->frames[self->framesCount + TRANSLATE_PREV_Y] - bone->shearY) * alpha;
-		return;
-	}
-
-	/* Interpolate between the previous frame and the current frame. */
-	frame = binarySearch(self->frames, self->framesCount, time, TRANSLATE_ENTRIES);
-	prevX = self->frames[frame + TRANSLATE_PREV_X];
-	prevY = self->frames[frame + TRANSLATE_PREV_Y];
-	frameTime = self->frames[frame];
-	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + TRANSLATE_PREV_TIME] - frameTime));
-
-	bone->shearX += (bone->data->shearX + prevX + (self->frames[frame + TRANSLATE_X] - prevX) * percent - bone->shearX) * alpha;
-	bone->shearY += (bone->data->shearY + prevY + (self->frames[frame + TRANSLATE_Y] - prevY) * percent - bone->shearY) * alpha;
-
-	UNUSED(lastTime);
-	UNUSED(firedEvents);
-	UNUSED(eventsCount);
-}
-
-spShearTimeline* spShearTimeline_create (int framesCount) {
-	return (spShearTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_SHEAR, 3, _spShearTimeline_apply);
-}
-
-void spShearTimeline_setFrame (spShearTimeline* self, int frameIndex, float time, float x, float y) {
-	spTranslateTimeline_setFrame(self, frameIndex, time, x, y);
-}
-
-/**/
-
-static const int COLOR_PREV_TIME = -5, COLOR_PREV_R = -4, COLOR_PREV_G = -3, COLOR_PREV_B = -2, COLOR_PREV_A = -1;
-static const int COLOR_R = 1, COLOR_G = 2, COLOR_B = 3, COLOR_A = 4;
-
-void _spColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
-		int* eventsCount, float alpha) {
-	spSlot *slot;
-	int frame;
-	float percent, frameTime;
-	float r, g, b, a;
-	spColorTimeline* self = (spColorTimeline*)timeline;
-
-	if (time < self->frames[0]) return; /* Time is before first frame. */
-
-	if (time >= self->frames[self->framesCount - 5]) { /* Time is after last frame */
-		int i = self->framesCount;
-		r = self->frames[i + COLOR_PREV_R];
-		g = self->frames[i + COLOR_PREV_G];
-		b = self->frames[i + COLOR_PREV_B];
-		a = self->frames[i + COLOR_PREV_A];
-	} else {
-		/* Interpolate between the previous frame and the current frame. */
-		frame = binarySearch(self->frames, self->framesCount, time, COLOR_ENTRIES);
-
-		r = self->frames[frame + COLOR_PREV_R];
-		g = self->frames[frame + COLOR_PREV_G];
-		b = self->frames[frame + COLOR_PREV_B];
-		a = self->frames[frame + COLOR_PREV_A];
-
-		frameTime = self->frames[frame];
-		percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / COLOR_ENTRIES - 1,
-												  1 - (time - frameTime) / (self->frames[frame + COLOR_PREV_TIME] - frameTime));
-
-		r += (self->frames[frame + COLOR_R] - r) * percent;
-		g += (self->frames[frame + COLOR_G] - g) * percent;
-		b += (self->frames[frame + COLOR_B] - b) * percent;
-		a += (self->frames[frame + COLOR_A] - a) * percent;
-	}
-	slot = skeleton->slots[self->slotIndex];
-	if (alpha < 1) {
-		slot->r += (r - slot->r) * alpha;
-		slot->g += (g - slot->g) * alpha;
-		slot->b += (b - slot->b) * alpha;
-		slot->a += (a - slot->a) * alpha;
-	} else {
-		slot->r = r;
-		slot->g = g;
-		slot->b = b;
-		slot->a = a;
-	}
-
-	UNUSED(lastTime);
-	UNUSED(firedEvents);
-	UNUSED(eventsCount);
-}
-
-spColorTimeline* spColorTimeline_create (int framesCount) {
-	return (spColorTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_COLOR, 5, _spColorTimeline_apply);
-}
-
-void spColorTimeline_setFrame (spColorTimeline* self, int frameIndex, float time, float r, float g, float b, float a) {
-	frameIndex *= COLOR_ENTRIES;
-	self->frames[frameIndex] = time;
-	self->frames[frameIndex + COLOR_R] = r;
-	self->frames[frameIndex + COLOR_G] = g;
-	self->frames[frameIndex + COLOR_B] = b;
-	self->frames[frameIndex + COLOR_A] = a;
-}
-
-/**/
-
-void _spAttachmentTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
-		spEvent** firedEvents, int* eventsCount, float alpha) {
-	const char* attachmentName;
-	spAttachmentTimeline* self = (spAttachmentTimeline*)timeline;
-	int frameIndex;
-
-	if (time < self->frames[0]) return;
-
-	if (time >= self->frames[self->framesCount - 1])
-		frameIndex = self->framesCount - 1;
-	else
-		frameIndex = binarySearch1(self->frames, self->framesCount, time) - 1;
-
-	attachmentName = self->attachmentNames[frameIndex];
-	spSlot_setAttachment(skeleton->slots[self->slotIndex],
-			attachmentName ? spSkeleton_getAttachmentForSlotIndex(skeleton, self->slotIndex, attachmentName) : 0);
-
-	UNUSED(lastTime);
-	UNUSED(firedEvents);
-	UNUSED(eventsCount);
-	UNUSED(alpha);
-}
-
-void _spAttachmentTimeline_dispose (spTimeline* timeline) {
-	spAttachmentTimeline* self = SUB_CAST(spAttachmentTimeline, timeline);
-	int i;
-
-	_spTimeline_deinit(timeline);
-
-	for (i = 0; i < self->framesCount; ++i)
-		FREE(self->attachmentNames[i]);
-	FREE(self->attachmentNames);
-	FREE(self->frames);
-	FREE(self);
-}
-
-spAttachmentTimeline* spAttachmentTimeline_create (int framesCount) {
-	spAttachmentTimeline* self = NEW(spAttachmentTimeline);
-	_spTimeline_init(SUPER(self), SP_TIMELINE_ATTACHMENT, _spAttachmentTimeline_dispose, _spAttachmentTimeline_apply);
-
-	CONST_CAST(int, self->framesCount) = framesCount;
-	CONST_CAST(float*, self->frames) = CALLOC(float, framesCount);
-	CONST_CAST(char**, self->attachmentNames) = CALLOC(char*, framesCount);
-
-	return self;
-}
-
-void spAttachmentTimeline_setFrame (spAttachmentTimeline* self, int frameIndex, float time, const char* attachmentName) {
-	self->frames[frameIndex] = time;
-
-	FREE(self->attachmentNames[frameIndex]);
-	if (attachmentName)
-		MALLOC_STR(self->attachmentNames[frameIndex], attachmentName);
-	else
-		self->attachmentNames[frameIndex] = 0;
-}
-
-/**/
-
-/** Fires events for frames > lastTime and <= time. */
-void _spEventTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
-		int* eventsCount, float alpha) {
-	spEventTimeline* self = (spEventTimeline*)timeline;
-	int frame;
-	if (!firedEvents) return;
-
-	if (lastTime > time) { /* Fire events after last time for looped animations. */
-		_spEventTimeline_apply(timeline, skeleton, lastTime, (float)INT_MAX, firedEvents, eventsCount, alpha);
-		lastTime = -1;
-	} else if (lastTime >= self->frames[self->framesCount - 1]) /* Last time is after last frame. */
-	return;
-	if (time < self->frames[0]) return; /* Time is before first frame. */
-
-	if (lastTime < self->frames[0])
-		frame = 0;
-	else {
-		float frameTime;
-		frame = binarySearch1(self->frames, self->framesCount, lastTime);
-		frameTime = self->frames[frame];
-		while (frame > 0) { /* Fire multiple events with the same frame. */
-			if (self->frames[frame - 1] != frameTime) break;
-			frame--;
-		}
-	}
-	for (; frame < self->framesCount && time >= self->frames[frame]; ++frame) {
-		firedEvents[*eventsCount] = self->events[frame];
-		(*eventsCount)++;
-	}
-}
-
-void _spEventTimeline_dispose (spTimeline* timeline) {
-	spEventTimeline* self = SUB_CAST(spEventTimeline, timeline);
-	int i;
-
-	_spTimeline_deinit(timeline);
-
-	for (i = 0; i < self->framesCount; ++i)
-		spEvent_dispose(self->events[i]);
-	FREE(self->events);
-	FREE(self->frames);
-	FREE(self);
-}
-
-spEventTimeline* spEventTimeline_create (int framesCount) {
-	spEventTimeline* self = NEW(spEventTimeline);
-	_spTimeline_init(SUPER(self), SP_TIMELINE_EVENT, _spEventTimeline_dispose, _spEventTimeline_apply);
-
-	CONST_CAST(int, self->framesCount) = framesCount;
-	CONST_CAST(float*, self->frames) = CALLOC(float, framesCount);
-	CONST_CAST(spEvent**, self->events) = CALLOC(spEvent*, framesCount);
-
-	return self;
-}
-
-void spEventTimeline_setFrame (spEventTimeline* self, int frameIndex, spEvent* event) {
-	self->frames[frameIndex] = event->time;
-
-	FREE(self->events[frameIndex]);
-	self->events[frameIndex] = event;
-}
-
-/**/
-
-void _spDrawOrderTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
-		spEvent** firedEvents, int* eventsCount, float alpha) {
-	int i;
-	int frame;
-	const int* drawOrderToSetupIndex;
-	spDrawOrderTimeline* self = (spDrawOrderTimeline*)timeline;
-
-	if (time < self->frames[0]) return; /* Time is before first frame. */
-
-	if (time >= self->frames[self->framesCount - 1]) /* Time is after last frame. */
-		frame = self->framesCount - 1;
-	else
-		frame = binarySearch1(self->frames, self->framesCount, time) - 1;
-
-	drawOrderToSetupIndex = self->drawOrders[frame];
-	if (!drawOrderToSetupIndex)
-		memcpy(skeleton->drawOrder, skeleton->slots, self->slotsCount * sizeof(spSlot*));
-	else {
-		for (i = 0; i < self->slotsCount; ++i)
-			skeleton->drawOrder[i] = skeleton->slots[drawOrderToSetupIndex[i]];
-	}
-
-	UNUSED(lastTime);
-	UNUSED(firedEvents);
-	UNUSED(eventsCount);
-	UNUSED(alpha);
-}
-
-void _spDrawOrderTimeline_dispose (spTimeline* timeline) {
-	spDrawOrderTimeline* self = SUB_CAST(spDrawOrderTimeline, timeline);
-	int i;
-
-	_spTimeline_deinit(timeline);
-
-	for (i = 0; i < self->framesCount; ++i)
-		FREE(self->drawOrders[i]);
-	FREE(self->drawOrders);
-	FREE(self->frames);
-	FREE(self);
-}
-
-spDrawOrderTimeline* spDrawOrderTimeline_create (int framesCount, int slotsCount) {
-	spDrawOrderTimeline* self = NEW(spDrawOrderTimeline);
-	_spTimeline_init(SUPER(self), SP_TIMELINE_DRAWORDER, _spDrawOrderTimeline_dispose, _spDrawOrderTimeline_apply);
-
-	CONST_CAST(int, self->framesCount) = framesCount;
-	CONST_CAST(float*, self->frames) = CALLOC(float, framesCount);
-	CONST_CAST(int**, self->drawOrders) = CALLOC(int*, framesCount);
-	CONST_CAST(int, self->slotsCount) = slotsCount;
-
-	return self;
-}
-
-void spDrawOrderTimeline_setFrame (spDrawOrderTimeline* self, int frameIndex, float time, const int* drawOrder) {
-	self->frames[frameIndex] = time;
-
-	FREE(self->drawOrders[frameIndex]);
-	if (!drawOrder)
-		self->drawOrders[frameIndex] = 0;
-	else {
-		self->drawOrders[frameIndex] = MALLOC(int, self->slotsCount);
-		memcpy(CONST_CAST(int*, self->drawOrders[frameIndex]), drawOrder, self->slotsCount * sizeof(int));
-	}
-}
-
-/**/
-
-void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
-		int* eventsCount, float alpha) {
-	int frame, i, vertexCount;
-	float percent, frameTime;
-	const float* prevVertices;
-	const float* nextVertices;
-	spDeformTimeline* self = (spDeformTimeline*)timeline;
-
-	spSlot *slot = skeleton->slots[self->slotIndex];
-
-	if (slot->attachment != self->attachment) {
-		if (!slot->attachment) return;
-		switch (slot->attachment->type) {
-		case SP_ATTACHMENT_MESH: {
-			spMeshAttachment* mesh = SUB_CAST(spMeshAttachment, slot->attachment);
-			if (!mesh->inheritDeform || mesh->parentMesh != (void*)self->attachment) return;
-			break;
-		}
-		default:
-			return;
-		}
-	}
-
-	if (time < self->frames[0]) return; /* Time is before first frame. */
-
-	vertexCount = self->frameVerticesCount;
-	if (slot->attachmentVerticesCount < vertexCount) {
-		if (slot->attachmentVerticesCapacity < vertexCount) {
-			FREE(slot->attachmentVertices);
-			slot->attachmentVertices = MALLOC(float, vertexCount);
-			slot->attachmentVerticesCapacity = vertexCount;
-		}
-	}
-	if (slot->attachmentVerticesCount != vertexCount) alpha = 1; /* Don't mix from uninitialized slot vertices. */
-	slot->attachmentVerticesCount = vertexCount;
-
-	if (time >= self->frames[self->framesCount - 1]) {
-		/* Time is after last frame. */
-		const float* lastVertices = self->frameVertices[self->framesCount - 1];
-		if (alpha < 1) {
-			for (i = 0; i < vertexCount; ++i)
-				slot->attachmentVertices[i] += (lastVertices[i] - slot->attachmentVertices[i]) * alpha;
-		} else
-			memcpy(slot->attachmentVertices, lastVertices, vertexCount * sizeof(float));
-		return;
-	}
-
-	/* Interpolate between the previous frame and the current frame. */
-	frame = binarySearch1(self->frames, self->framesCount, time);
-	frameTime = self->frames[frame];
-	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame - 1, 1 - (time - frameTime) / (self->frames[frame - 1] - frameTime));
-
-	prevVertices = self->frameVertices[frame - 1];
-	nextVertices = self->frameVertices[frame];
-
-	if (alpha < 1) {
-		for (i = 0; i < vertexCount; ++i) {
-			float prev = prevVertices[i];
-			slot->attachmentVertices[i] += (prev + (nextVertices[i] - prev) * percent - slot->attachmentVertices[i]) * alpha;
-		}
-	} else {
-		for (i = 0; i < vertexCount; ++i) {
-			float prev = prevVertices[i];
-			slot->attachmentVertices[i] = prev + (nextVertices[i] - prev) * percent;
-		}
-	}
-
-	UNUSED(lastTime);
-	UNUSED(firedEvents);
-	UNUSED(eventsCount);
-}
-
-void _spDeformTimeline_dispose (spTimeline* timeline) {
-	spDeformTimeline* self = SUB_CAST(spDeformTimeline, timeline);
-	int i;
-
-	_spCurveTimeline_deinit(SUPER(self));
-
-	for (i = 0; i < self->framesCount; ++i)
-		FREE(self->frameVertices[i]);
-	FREE(self->frameVertices);
-	FREE(self->frames);
-	FREE(self);
-}
-
-spDeformTimeline* spDeformTimeline_create (int framesCount, int frameVerticesCount) {
-	spDeformTimeline* self = NEW(spDeformTimeline);
-	_spCurveTimeline_init(SUPER(self), SP_TIMELINE_DEFORM, framesCount, _spDeformTimeline_dispose, _spDeformTimeline_apply);
-	CONST_CAST(int, self->framesCount) = framesCount;
-	CONST_CAST(float*, self->frames) = CALLOC(float, self->framesCount);
-	CONST_CAST(float**, self->frameVertices) = CALLOC(float*, framesCount);
-	CONST_CAST(int, self->frameVerticesCount) = frameVerticesCount;
-	return self;
-}
-
-void spDeformTimeline_setFrame (spDeformTimeline* self, int frameIndex, float time, float* vertices) {
-	self->frames[frameIndex] = time;
-
-	FREE(self->frameVertices[frameIndex]);
-	if (!vertices)
-		self->frameVertices[frameIndex] = 0;
-	else {
-		self->frameVertices[frameIndex] = MALLOC(float, self->frameVerticesCount);
-		memcpy(CONST_CAST(float*, self->frameVertices[frameIndex]), vertices, self->frameVerticesCount * sizeof(float));
-	}
-}
-
-
-/**/
-
-static const int IKCONSTRAINT_PREV_TIME = -3, IKCONSTRAINT_PREV_MIX = -2, IKCONSTRAINT_PREV_BEND_DIRECTION = -1;
-static const int IKCONSTRAINT_MIX = 1, IKCONSTRAINT_BEND_DIRECTION = 2;
-
-void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
-		spEvent** firedEvents, int* eventsCount, float alpha) {
-	int frame;
-	float frameTime, percent, mix;
-	spIkConstraint* constraint;
-	spIkConstraintTimeline* self = (spIkConstraintTimeline*)timeline;
-
-	if (time < self->frames[0]) return; /* Time is before first frame. */
-
-	constraint = skeleton->ikConstraints[self->ikConstraintIndex];
-
-	if (time >= self->frames[self->framesCount - IKCONSTRAINT_ENTRIES]) { /* Time is after last frame. */
-		constraint->mix += (self->frames[self->framesCount + IKCONSTRAINT_PREV_MIX] - constraint->mix) * alpha;
-		constraint->bendDirection = (int)self->frames[self->framesCount + IKCONSTRAINT_PREV_BEND_DIRECTION];
-		return;
-	}
-
-	/* Interpolate between the previous frame and the current frame. */
-	frame = binarySearch(self->frames, self->framesCount, time, IKCONSTRAINT_ENTRIES);
-	mix = self->frames[frame + IKCONSTRAINT_PREV_MIX];
-	frameTime = self->frames[frame];
-	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / IKCONSTRAINT_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + IKCONSTRAINT_PREV_TIME] - frameTime));
-
-	constraint->mix += (mix + (self->frames[frame + IKCONSTRAINT_MIX] - mix) * percent - constraint->mix) * alpha;
-	constraint->bendDirection = (int)self->frames[frame + IKCONSTRAINT_PREV_BEND_DIRECTION];
-
-	UNUSED(lastTime);
-	UNUSED(firedEvents);
-	UNUSED(eventsCount);
-}
-
-spIkConstraintTimeline* spIkConstraintTimeline_create (int framesCount) {
-	return (spIkConstraintTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_IKCONSTRAINT, IKCONSTRAINT_ENTRIES, _spIkConstraintTimeline_apply);
-}
-
-void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameIndex, float time, float mix, int bendDirection) {
-	frameIndex *= IKCONSTRAINT_ENTRIES;
-	self->frames[frameIndex] = time;
-	self->frames[frameIndex + IKCONSTRAINT_MIX] = mix;
-	self->frames[frameIndex + IKCONSTRAINT_BEND_DIRECTION] = (float)bendDirection;
-}
-
-/**/
-static const int TRANSFORMCONSTRAINT_PREV_TIME = -5;
-static const int TRANSFORMCONSTRAINT_PREV_ROTATE = -4;
-static const int TRANSFORMCONSTRAINT_PREV_TRANSLATE = -3;
-static const int TRANSFORMCONSTRAINT_PREV_SCALE = -2;
-static const int TRANSFORMCONSTRAINT_PREV_SHEAR = -1;
-static const int TRANSFORMCONSTRAINT_ROTATE = 1;
-static const int TRANSFORMCONSTRAINT_TRANSLATE = 2;
-static const int TRANSFORMCONSTRAINT_SCALE = 3;
-static const int TRANSFORMCONSTRAINT_SHEAR = 4;
-
-void _spTransformConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
-									spEvent** firedEvents, int* eventsCount, float alpha) {
-	int frame;
-	float frameTime, percent, rotate, translate, scale, shear;
-	spTransformConstraint* constraint;
-	spTransformConstraintTimeline* self = (spTransformConstraintTimeline*)timeline;
-
-	if (time < self->frames[0]) return; /* Time is before first frame. */
-
-	constraint = skeleton->transformConstraints[self->transformConstraintIndex];
-
-	if (time >= self->frames[self->framesCount - TRANSFORMCONSTRAINT_ENTRIES]) { /* Time is after last frame. */
-		int len = self->framesCount;
-		constraint->rotateMix += (self->frames[len + TRANSFORMCONSTRAINT_PREV_ROTATE] - constraint->rotateMix) * alpha;
-		constraint->translateMix += (self->frames[len + TRANSFORMCONSTRAINT_PREV_TRANSLATE] - constraint->translateMix) * alpha;
-		constraint->scaleMix += (self->frames[len + TRANSFORMCONSTRAINT_PREV_SCALE] - constraint->scaleMix) * alpha;
-		constraint->shearMix += (self->frames[len + TRANSFORMCONSTRAINT_PREV_SHEAR] - constraint->shearMix) * alpha;
-		return;
-	}
-
-	/* Interpolate between the previous frame and the current frame. */
-	frame = binarySearch(self->frames, self->framesCount, time, TRANSFORMCONSTRAINT_ENTRIES);
-	frameTime = self->frames[frame];
-	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSFORMCONSTRAINT_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + TRANSFORMCONSTRAINT_PREV_TIME] - frameTime));
-
-	rotate = self->frames[frame + TRANSFORMCONSTRAINT_PREV_ROTATE];
-	translate = self->frames[frame + TRANSFORMCONSTRAINT_PREV_TRANSLATE];
-	scale = self->frames[frame + TRANSFORMCONSTRAINT_PREV_SCALE];
-	shear = self->frames[frame + TRANSFORMCONSTRAINT_PREV_SHEAR];
-	constraint->rotateMix += (rotate + (self->frames[frame + TRANSFORMCONSTRAINT_ROTATE] - rotate) * percent - constraint->rotateMix) * alpha;
-	constraint->translateMix += (translate + (self->frames[frame + TRANSFORMCONSTRAINT_TRANSLATE] - translate) * percent - constraint->translateMix) * alpha;
-	constraint->scaleMix += (scale + (self->frames[frame + TRANSFORMCONSTRAINT_SCALE] - scale) * percent - constraint->scaleMix) * alpha;
-	constraint->shearMix += (shear + (self->frames[frame + TRANSFORMCONSTRAINT_SHEAR] - shear) * percent - constraint->shearMix) * alpha;
-
-	UNUSED(lastTime);
-	UNUSED(firedEvents);
-	UNUSED(eventsCount);
-}
-
-spTransformConstraintTimeline* spTransformConstraintTimeline_create (int framesCount) {
-	return (spTransformConstraintTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_TRANSFORMCONSTRAINT, TRANSFORMCONSTRAINT_ENTRIES, _spTransformConstraintTimeline_apply);
-}
-
-void spTransformConstraintTimeline_setFrame (spTransformConstraintTimeline* self, int frameIndex, float time, float rotateMix, float translateMix, float scaleMix, float shearMix) {
-	frameIndex *= TRANSFORMCONSTRAINT_ENTRIES;
-	self->frames[frameIndex] = time;
-	self->frames[frameIndex + TRANSFORMCONSTRAINT_ROTATE] = rotateMix;
-	self->frames[frameIndex + TRANSFORMCONSTRAINT_TRANSLATE] = translateMix;
-	self->frames[frameIndex + TRANSFORMCONSTRAINT_SCALE] = scaleMix;
-	self->frames[frameIndex + TRANSFORMCONSTRAINT_SHEAR] = shearMix;
-}
-
-/**/
-
-static const int PATHCONSTRAINTPOSITION_PREV_TIME = -2;
-static const int PATHCONSTRAINTPOSITION_PREV_VALUE = -1;
-static const int PATHCONSTRAINTPOSITION_VALUE = 1;
-
-void _spPathConstraintPositionTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
-											 spEvent** firedEvents, int* eventsCount, float alpha) {
-	int frame;
-	float frameTime, percent, position;
-	spPathConstraint* constraint;
-	spPathConstraintPositionTimeline* self = (spPathConstraintPositionTimeline*)timeline;
-
-	if (time < self->frames[0]) return; /* Time is before first frame. */
-
-	constraint = skeleton->pathConstraints[self->pathConstraintIndex];
-
-	if (time >= self->frames[self->framesCount - PATHCONSTRAINTPOSITION_ENTRIES]) { /* Time is after last frame. */
-		int len = self->framesCount;
-		constraint->position += (self->frames[len + PATHCONSTRAINTPOSITION_PREV_VALUE] - constraint->position) * alpha;
-		return;
-	}
-
-	/* Interpolate between the previous frame and the current frame. */
-	frame = binarySearch(self->frames, self->framesCount, time, PATHCONSTRAINTPOSITION_ENTRIES);
-	position = self->frames[frame + PATHCONSTRAINTPOSITION_PREV_VALUE];
-	frameTime = self->frames[frame];
-	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / PATHCONSTRAINTPOSITION_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + PATHCONSTRAINTPOSITION_PREV_TIME] - frameTime));
-
-	constraint->position += (position + (self->frames[frame + PATHCONSTRAINTPOSITION_VALUE] - position) * percent - constraint->position) * alpha;
-
-	UNUSED(lastTime);
-	UNUSED(firedEvents);
-	UNUSED(eventsCount);
-}
-
-spPathConstraintPositionTimeline* spPathConstraintPositionTimeline_create (int framesCount) {
-	return (spPathConstraintPositionTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_PATHCONSTRAINTPOSITION, PATHCONSTRAINTPOSITION_ENTRIES, _spPathConstraintPositionTimeline_apply);
-}
-
-void spPathConstraintPositionTimeline_setFrame (spPathConstraintPositionTimeline* self, int frameIndex, float time, float value) {
-	frameIndex *= PATHCONSTRAINTPOSITION_ENTRIES;
-	self->frames[frameIndex] = time;
-	self->frames[frameIndex + PATHCONSTRAINTPOSITION_VALUE] = value;
-}
-
-/**/
-static const int PATHCONSTRAINTSPACING_PREV_TIME = -2;
-static const int PATHCONSTRAINTSPACING_PREV_VALUE = -1;
-static const int PATHCONSTRAINTSPACING_VALUE = 1;
-
-void _spPathConstraintSpacingTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
-											 spEvent** firedEvents, int* eventsCount, float alpha) {
-	int frame;
-	float frameTime, percent, spacing;
-	spPathConstraint* constraint;
-	spPathConstraintSpacingTimeline* self = (spPathConstraintSpacingTimeline*)timeline;
-
-	if (time < self->frames[0]) return; /* Time is before first frame. */
-
-	constraint = skeleton->pathConstraints[self->pathConstraintIndex];
-
-	if (time >= self->frames[self->framesCount - PATHCONSTRAINTSPACING_ENTRIES]) { /* Time is after last frame. */
-		int len = self->framesCount;
-		constraint->spacing += (self->frames[len + PATHCONSTRAINTSPACING_PREV_VALUE] - constraint->spacing) * alpha;
-		return;
-	}
-
-	/* Interpolate between the previous frame and the current frame. */
-	frame = binarySearch(self->frames, self->framesCount, time, PATHCONSTRAINTSPACING_ENTRIES);
-	spacing = self->frames[frame + PATHCONSTRAINTSPACING_PREV_VALUE];
-	frameTime = self->frames[frame];
-	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / PATHCONSTRAINTSPACING_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + PATHCONSTRAINTSPACING_PREV_TIME] - frameTime));
-
-	constraint->spacing += (spacing + (self->frames[frame + PATHCONSTRAINTSPACING_VALUE] - spacing) * percent - constraint->spacing) * alpha;
-
-	UNUSED(lastTime);
-	UNUSED(firedEvents);
-	UNUSED(eventsCount);
-}
-
-spPathConstraintSpacingTimeline* spPathConstraintSpacingTimeline_create (int framesCount) {
-	return (spPathConstraintSpacingTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_PATHCONSTRAINTSPACING, PATHCONSTRAINTSPACING_ENTRIES, _spPathConstraintSpacingTimeline_apply);
-}
-
-void spPathConstraintSpacingTimeline_setFrame (spPathConstraintSpacingTimeline* self, int frameIndex, float time, float value) {
-	frameIndex *= PATHCONSTRAINTSPACING_ENTRIES;
-	self->frames[frameIndex] = time;
-	self->frames[frameIndex + PATHCONSTRAINTSPACING_VALUE] = value;
-}
-
-/**/
-
-static const int PATHCONSTRAINTMIX_PREV_TIME = -3;
-static const int PATHCONSTRAINTMIX_PREV_ROTATE = -2;
-static const int PATHCONSTRAINTMIX_PREV_TRANSLATE = -1;
-static const int PATHCONSTRAINTMIX_ROTATE = 1;
-static const int PATHCONSTRAINTMIX_TRANSLATE = 2;
-
-void _spPathConstraintMixTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
-											spEvent** firedEvents, int* eventsCount, float alpha) {
-	int frame;
-	float frameTime, percent, rotate, translate;
-	spPathConstraint* constraint;
-	spPathConstraintMixTimeline* self = (spPathConstraintMixTimeline*)timeline;
-
-	if (time < self->frames[0]) return; /* Time is before first frame. */
-
-	constraint = skeleton->pathConstraints[self->pathConstraintIndex];
-
-	if (time >= self->frames[self->framesCount - PATHCONSTRAINTMIX_ENTRIES]) { /* Time is after last frame. */
-		int len = self->framesCount;
-		constraint->rotateMix += (self->frames[len + PATHCONSTRAINTMIX_PREV_ROTATE] - constraint->rotateMix) * alpha;
-		constraint->translateMix += (self->frames[len + PATHCONSTRAINTMIX_PREV_TRANSLATE] - constraint->translateMix) * alpha;
-		return;
-	}
-
-	/* Interpolate between the previous frame and the current frame. */
-	frame = binarySearch(self->frames, self->framesCount, time, PATHCONSTRAINTMIX_ENTRIES);
-	rotate = self->frames[frame + PATHCONSTRAINTMIX_PREV_ROTATE];
-	translate = self->frames[frame + PATHCONSTRAINTMIX_PREV_TRANSLATE];
-	frameTime = self->frames[frame];
-	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / PATHCONSTRAINTMIX_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + PATHCONSTRAINTMIX_PREV_TIME] - frameTime));
-
-	constraint->rotateMix += (rotate + (self->frames[frame + PATHCONSTRAINTMIX_ROTATE] - rotate) * percent - constraint->rotateMix) * alpha;
-	constraint->translateMix += (translate + (self->frames[frame + PATHCONSTRAINTMIX_TRANSLATE] - translate) * percent - constraint->translateMix) * alpha;
-
-	UNUSED(lastTime);
-	UNUSED(firedEvents);
-	UNUSED(eventsCount);
-}
-
-spPathConstraintMixTimeline* spPathConstraintMixTimeline_create (int framesCount) {
-	return (spPathConstraintMixTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_PATHCONSTRAINTMIX, PATHCONSTRAINTMIX_ENTRIES, _spPathConstraintMixTimeline_apply);
-}
-
-void spPathConstraintMixTimeline_setFrame (spPathConstraintMixTimeline* self, int frameIndex, float time, float rotateMix, float translateMix) {
-	frameIndex *= PATHCONSTRAINTMIX_ENTRIES;
-	self->frames[frameIndex] = time;
-	self->frames[frameIndex + PATHCONSTRAINTMIX_ROTATE] = rotateMix;
-	self->frames[frameIndex + PATHCONSTRAINTMIX_TRANSLATE] = translateMix;
+#include <spine/Animation.h>
+#include <spine/IkConstraint.h>
+#include <limits.h>
+#include <spine/extension.h>
+
+spAnimation* spAnimation_create (const char* name, int timelinesCount) {
+	spAnimation* self = NEW(spAnimation);
+	MALLOC_STR(self->name, name);
+	self->timelinesCount = timelinesCount;
+	self->timelines = MALLOC(spTimeline*, timelinesCount);
+	return self;
+}
+
+void spAnimation_dispose (spAnimation* self) {
+	int i;
+	for (i = 0; i < self->timelinesCount; ++i)
+		spTimeline_dispose(self->timelines[i]);
+	FREE(self->timelines);
+	FREE(self->name);
+	FREE(self);
+}
+
+void spAnimation_apply (const spAnimation* self, spSkeleton* skeleton, float lastTime, float time, int loop, spEvent** events,
+		int* eventsCount) {
+	int i, n = self->timelinesCount;
+
+	if (loop && self->duration) {
+		time = FMOD(time, self->duration);
+		if (lastTime > 0) lastTime = FMOD(lastTime, self->duration);
+	}
+
+	for (i = 0; i < n; ++i)
+		spTimeline_apply(self->timelines[i], skeleton, lastTime, time, events, eventsCount, 1);
+}
+
+void spAnimation_mix (const spAnimation* self, spSkeleton* skeleton, float lastTime, float time, int loop, spEvent** events,
+		int* eventsCount, float alpha) {
+	int i, n = self->timelinesCount;
+
+	if (loop && self->duration) {
+		time = FMOD(time, self->duration);
+		if (lastTime > 0) lastTime = FMOD(lastTime, self->duration);
+	}
+
+	for (i = 0; i < n; ++i)
+		spTimeline_apply(self->timelines[i], skeleton, lastTime, time, events, eventsCount, alpha);
+}
+
+/**/
+
+typedef struct _spTimelineVtable {
+	void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
+			int* eventsCount, float alpha);
+	void (*dispose) (spTimeline* self);
+} _spTimelineVtable;
+
+void _spTimeline_init (spTimeline* self, spTimelineType type, /**/
+void (*dispose) (spTimeline* self), /**/
+		void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
+				int* eventsCount, float alpha)) {
+	CONST_CAST(spTimelineType, self->type) = type;
+	CONST_CAST(_spTimelineVtable*, self->vtable) = NEW(_spTimelineVtable);
+	VTABLE(spTimeline, self)->dispose = dispose;
+	VTABLE(spTimeline, self)->apply = apply;
+}
+
+void _spTimeline_deinit (spTimeline* self) {
+	FREE(self->vtable);
+}
+
+void spTimeline_dispose (spTimeline* self) {
+	VTABLE(spTimeline, self)->dispose(self);
+}
+
+void spTimeline_apply (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
+		int* eventsCount, float alpha) {
+	VTABLE(spTimeline, self)->apply(self, skeleton, lastTime, time, firedEvents, eventsCount, alpha);
+}
+
+/**/
+
+static const float CURVE_LINEAR = 0, CURVE_STEPPED = 1, CURVE_BEZIER = 2;
+static const int BEZIER_SIZE = 10 * 2 - 1;
+
+void _spCurveTimeline_init (spCurveTimeline* self, spTimelineType type, int framesCount, /**/
+void (*dispose) (spTimeline* self), /**/
+		void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
+				int* eventsCount, float alpha)) {
+	_spTimeline_init(SUPER(self), type, dispose, apply);
+	self->curves = CALLOC(float, (framesCount - 1) * BEZIER_SIZE);
+}
+
+void _spCurveTimeline_deinit (spCurveTimeline* self) {
+	_spTimeline_deinit(SUPER(self));
+	FREE(self->curves);
+}
+
+void spCurveTimeline_setLinear (spCurveTimeline* self, int frameIndex) {
+	self->curves[frameIndex * BEZIER_SIZE] = CURVE_LINEAR;
+}
+
+void spCurveTimeline_setStepped (spCurveTimeline* self, int frameIndex) {
+	self->curves[frameIndex * BEZIER_SIZE] = CURVE_STEPPED;
+}
+
+void spCurveTimeline_setCurve (spCurveTimeline* self, int frameIndex, float cx1, float cy1, float cx2, float cy2) {
+	float tmpx = (-cx1 * 2 + cx2) * 0.03f, tmpy = (-cy1 * 2 + cy2) * 0.03f;
+	float dddfx = ((cx1 - cx2) * 3 + 1) * 0.006f, dddfy = ((cy1 - cy2) * 3 + 1) * 0.006f;
+	float ddfx = tmpx * 2 + dddfx, ddfy = tmpy * 2 + dddfy;
+	float dfx = cx1 * 0.3f + tmpx + dddfx * 0.16666667f, dfy = cy1 * 0.3f + tmpy + dddfy * 0.16666667f;
+	float x = dfx, y = dfy;
+
+	int i = frameIndex * BEZIER_SIZE, n = i + BEZIER_SIZE - 1;
+	self->curves[i++] = CURVE_BEZIER;
+
+	for (; i < n; i += 2) {
+		self->curves[i] = x;
+		self->curves[i + 1] = y;
+		dfx += ddfx;
+		dfy += ddfy;
+		ddfx += dddfx;
+		ddfy += dddfy;
+		x += dfx;
+		y += dfy;
+	}
+}
+
+float spCurveTimeline_getCurvePercent (const spCurveTimeline* self, int frameIndex, float percent) {
+	float x, y;
+	int i = frameIndex * BEZIER_SIZE, start, n;
+	float type = self->curves[i];
+	percent = CLAMP(percent, 0, 1);
+	if (type == CURVE_LINEAR) return percent;
+	if (type == CURVE_STEPPED) return 0;
+	i++;
+	x = 0;
+	for (start = i, n = i + BEZIER_SIZE - 1; i < n; i += 2) {
+		x = self->curves[i];
+		if (x >= percent) {
+			float prevX, prevY;
+			if (i == start) {
+				prevX = 0;
+				prevY = 0;
+			} else {
+				prevX = self->curves[i - 2];
+				prevY = self->curves[i - 1];
+			}
+			return prevY + (self->curves[i + 1] - prevY) * (percent - prevX) / (x - prevX);
+		}
+	}
+	y = self->curves[i - 1];
+	return y + (1 - y) * (percent - x) / (1 - x); /* Last point is 1,1. */
+}
+
+/* @param target After the first and before the last entry. */
+static int binarySearch (float *values, int valuesLength, float target, int step) {
+	int low = 0, current;
+	int high = valuesLength / step - 2;
+	if (high == 0) return step;
+	current = high >> 1;
+	while (1) {
+		if (values[(current + 1) * step] <= target)
+			low = current + 1;
+		else
+			high = current;
+		if (low == high) return (low + 1) * step;
+		current = (low + high) >> 1;
+	}
+	return 0;
+}
+
+/* @param target After the first and before the last entry. */
+static int binarySearch1 (float *values, int valuesLength, float target) {
+	int low = 0, current;
+	int high = valuesLength - 2;
+	if (high == 0) return 1;
+	current = high >> 1;
+	while (1) {
+		if (values[(current + 1)] <= target)
+			low = current + 1;
+		else
+			high = current;
+		if (low == high) return low + 1;
+		current = (low + high) >> 1;
+	}
+	return 0;
+}
+
+/**/
+
+void _spBaseTimeline_dispose (spTimeline* timeline) {
+	struct spBaseTimeline* self = SUB_CAST(struct spBaseTimeline, timeline);
+	_spCurveTimeline_deinit(SUPER(self));
+	FREE(self->frames);
+	FREE(self);
+}
+
+/* Many timelines have structure identical to struct spBaseTimeline and extend spCurveTimeline. **/
+struct spBaseTimeline* _spBaseTimeline_create (int framesCount, spTimelineType type, int frameSize, /**/
+		void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
+				int* eventsCount, float alpha)) {
+	struct spBaseTimeline* self = NEW(struct spBaseTimeline);
+	_spCurveTimeline_init(SUPER(self), type, framesCount, _spBaseTimeline_dispose, apply);
+
+	CONST_CAST(int, self->framesCount) = framesCount * frameSize;
+	CONST_CAST(float*, self->frames) = CALLOC(float, self->framesCount);
+
+	return self;
+}
+
+/**/
+
+static const int ROTATE_PREV_TIME = -2, ROTATE_PREV_ROTATION = -1;
+static const int ROTATE_ROTATION = 1;
+
+void _spRotateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
+		int* eventsCount, float alpha) {
+	spBone *bone;
+	int frame;
+	float prevRotation, frameTime, percent, amount;
+
+	spRotateTimeline* self = SUB_CAST(spRotateTimeline, timeline);
+
+	if (time < self->frames[0]) return; /* Time is before first frame. */
+
+	bone = skeleton->bones[self->boneIndex];
+
+	if (time >= self->frames[self->framesCount - ROTATE_ENTRIES]) { /* Time is after last frame. */
+		amount = bone->data->rotation + self->frames[self->framesCount + ROTATE_PREV_ROTATION] - bone->rotation;
+		while (amount > 180)
+			amount -= 360;
+		while (amount < -180)
+			amount += 360;
+		bone->rotation += amount * alpha;
+		return;
+	}
+
+	/* Interpolate between the previous frame and the current frame. */
+	frame = binarySearch(self->frames, self->framesCount, time, ROTATE_ENTRIES);
+	prevRotation = self->frames[frame + ROTATE_PREV_ROTATION];
+	frameTime = self->frames[frame];
+	percent = spCurveTimeline_getCurvePercent(SUPER(self), (frame >> 1) - 1, 1 - (time - frameTime) / (self->frames[frame + ROTATE_PREV_TIME] - frameTime));
+
+	amount = self->frames[frame + ROTATE_ROTATION] - prevRotation;
+	while (amount > 180)
+		amount -= 360;
+	while (amount < -180)
+		amount += 360;
+	amount = bone->data->rotation + (prevRotation + amount * percent) - bone->rotation;
+	while (amount > 180)
+		amount -= 360;
+	while (amount < -180)
+		amount += 360;
+	bone->rotation += amount * alpha;
+
+	UNUSED(lastTime);
+	UNUSED(firedEvents);
+	UNUSED(eventsCount);
+}
+
+spRotateTimeline* spRotateTimeline_create (int framesCount) {
+	return _spBaseTimeline_create(framesCount, SP_TIMELINE_ROTATE, ROTATE_ENTRIES, _spRotateTimeline_apply);
+}
+
+void spRotateTimeline_setFrame (spRotateTimeline* self, int frameIndex, float time, float degrees) {
+	frameIndex <<= 1;
+	self->frames[frameIndex] = time;
+	self->frames[frameIndex + ROTATE_ROTATION] = degrees;
+}
+
+/**/
+
+static const int TRANSLATE_PREV_TIME = -3, TRANSLATE_PREV_X = -2, TRANSLATE_PREV_Y = -1;
+static const int TRANSLATE_X = 1, TRANSLATE_Y = 2;
+
+void _spTranslateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
+		spEvent** firedEvents, int* eventsCount, float alpha) {
+	spBone *bone;
+	int frame;
+	float prevX, prevY, frameTime, percent;
+
+	spTranslateTimeline* self = SUB_CAST(spTranslateTimeline, timeline);
+
+	if (time < self->frames[0]) return; /* Time is before first frame. */
+
+	bone = skeleton->bones[self->boneIndex];
+
+	if (time >= self->frames[self->framesCount - TRANSLATE_ENTRIES]) { /* Time is after last frame. */
+		bone->x += (bone->data->x + self->frames[self->framesCount + TRANSLATE_PREV_X] - bone->x) * alpha;
+		bone->y += (bone->data->y + self->frames[self->framesCount + TRANSLATE_PREV_Y] - bone->y) * alpha;
+		return;
+	}
+
+	/* Interpolate between the previous frame and the current frame. */
+	frame = binarySearch(self->frames, self->framesCount, time, TRANSLATE_ENTRIES);
+	prevX = self->frames[frame + TRANSLATE_PREV_X];
+	prevY = self->frames[frame + TRANSLATE_PREV_Y];
+	frameTime = self->frames[frame];
+	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + TRANSLATE_PREV_TIME] - frameTime));
+
+	bone->x += (bone->data->x + prevX + (self->frames[frame + TRANSLATE_X] - prevX) * percent - bone->x) * alpha;
+	bone->y += (bone->data->y + prevY + (self->frames[frame + TRANSLATE_Y] - prevY) * percent - bone->y) * alpha;
+
+	UNUSED(lastTime);
+	UNUSED(firedEvents);
+	UNUSED(eventsCount);
+}
+
+spTranslateTimeline* spTranslateTimeline_create (int framesCount) {
+	return _spBaseTimeline_create(framesCount, SP_TIMELINE_TRANSLATE, TRANSLATE_ENTRIES, _spTranslateTimeline_apply);
+}
+
+void spTranslateTimeline_setFrame (spTranslateTimeline* self, int frameIndex, float time, float x, float y) {
+	frameIndex *= TRANSLATE_ENTRIES;
+	self->frames[frameIndex] = time;
+	self->frames[frameIndex + TRANSLATE_X] = x;
+	self->frames[frameIndex + TRANSLATE_Y] = y;
+}
+
+/**/
+
+void _spScaleTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
+		int* eventsCount, float alpha) {
+	spBone *bone;
+	int frame;
+	float prevX, prevY, frameTime, percent;
+
+	spScaleTimeline* self = SUB_CAST(spScaleTimeline, timeline);
+
+	if (time < self->frames[0]) return; /* Time is before first frame. */
+
+	bone = skeleton->bones[self->boneIndex];
+	if (time >= self->frames[self->framesCount - TRANSLATE_ENTRIES]) { /* Time is after last frame. */
+		bone->scaleX += (bone->data->scaleX * self->frames[self->framesCount + TRANSLATE_PREV_X] - bone->scaleX) * alpha;
+		bone->scaleY += (bone->data->scaleY * self->frames[self->framesCount + TRANSLATE_PREV_Y] - bone->scaleY) * alpha;
+		return;
+	}
+
+	/* Interpolate between the previous frame and the current frame. */
+	frame = binarySearch(self->frames, self->framesCount, time, TRANSLATE_ENTRIES);
+	prevX = self->frames[frame + TRANSLATE_PREV_X];
+	prevY = self->frames[frame + TRANSLATE_PREV_Y];
+	frameTime = self->frames[frame];
+	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + TRANSLATE_PREV_TIME] - frameTime));
+
+	bone->scaleX += (bone->data->scaleX * (prevX + (self->frames[frame + TRANSLATE_X] - prevX) * percent) - bone->scaleX) * alpha;
+	bone->scaleY += (bone->data->scaleY * (prevY + (self->frames[frame + TRANSLATE_Y] - prevY) * percent) - bone->scaleY) * alpha;
+
+	UNUSED(lastTime);
+	UNUSED(firedEvents);
+	UNUSED(eventsCount);
+}
+
+spScaleTimeline* spScaleTimeline_create (int framesCount) {
+	return _spBaseTimeline_create(framesCount, SP_TIMELINE_SCALE, TRANSLATE_ENTRIES, _spScaleTimeline_apply);
+}
+
+void spScaleTimeline_setFrame (spScaleTimeline* self, int frameIndex, float time, float x, float y) {
+	spTranslateTimeline_setFrame(self, frameIndex, time, x, y);
+}
+
+/**/
+
+void _spShearTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
+							 int* eventsCount, float alpha) {
+	spBone *bone;
+	int frame;
+	float prevX, prevY, frameTime, percent;
+
+	spShearTimeline* self = SUB_CAST(spShearTimeline, timeline);
+
+	if (time < self->frames[0]) return; /* Time is before first frame. */
+
+	bone = skeleton->bones[self->boneIndex];
+	if (time >= self->frames[self->framesCount - TRANSLATE_ENTRIES]) { /* Time is after last frame. */
+		bone->shearX += (bone->data->shearX + self->frames[self->framesCount + TRANSLATE_PREV_X] - bone->shearX) * alpha;
+		bone->shearY += (bone->data->shearY + self->frames[self->framesCount + TRANSLATE_PREV_Y] - bone->shearY) * alpha;
+		return;
+	}
+
+	/* Interpolate between the previous frame and the current frame. */
+	frame = binarySearch(self->frames, self->framesCount, time, TRANSLATE_ENTRIES);
+	prevX = self->frames[frame + TRANSLATE_PREV_X];
+	prevY = self->frames[frame + TRANSLATE_PREV_Y];
+	frameTime = self->frames[frame];
+	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + TRANSLATE_PREV_TIME] - frameTime));
+
+	bone->shearX += (bone->data->shearX + prevX + (self->frames[frame + TRANSLATE_X] - prevX) * percent - bone->shearX) * alpha;
+	bone->shearY += (bone->data->shearY + prevY + (self->frames[frame + TRANSLATE_Y] - prevY) * percent - bone->shearY) * alpha;
+
+	UNUSED(lastTime);
+	UNUSED(firedEvents);
+	UNUSED(eventsCount);
+}
+
+spShearTimeline* spShearTimeline_create (int framesCount) {
+	return (spShearTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_SHEAR, 3, _spShearTimeline_apply);
+}
+
+void spShearTimeline_setFrame (spShearTimeline* self, int frameIndex, float time, float x, float y) {
+	spTranslateTimeline_setFrame(self, frameIndex, time, x, y);
+}
+
+/**/
+
+static const int COLOR_PREV_TIME = -5, COLOR_PREV_R = -4, COLOR_PREV_G = -3, COLOR_PREV_B = -2, COLOR_PREV_A = -1;
+static const int COLOR_R = 1, COLOR_G = 2, COLOR_B = 3, COLOR_A = 4;
+
+void _spColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
+		int* eventsCount, float alpha) {
+	spSlot *slot;
+	int frame;
+	float percent, frameTime;
+	float r, g, b, a;
+	spColorTimeline* self = (spColorTimeline*)timeline;
+
+	if (time < self->frames[0]) return; /* Time is before first frame. */
+
+	if (time >= self->frames[self->framesCount - 5]) { /* Time is after last frame */
+		int i = self->framesCount;
+		r = self->frames[i + COLOR_PREV_R];
+		g = self->frames[i + COLOR_PREV_G];
+		b = self->frames[i + COLOR_PREV_B];
+		a = self->frames[i + COLOR_PREV_A];
+	} else {
+		/* Interpolate between the previous frame and the current frame. */
+		frame = binarySearch(self->frames, self->framesCount, time, COLOR_ENTRIES);
+
+		r = self->frames[frame + COLOR_PREV_R];
+		g = self->frames[frame + COLOR_PREV_G];
+		b = self->frames[frame + COLOR_PREV_B];
+		a = self->frames[frame + COLOR_PREV_A];
+
+		frameTime = self->frames[frame];
+		percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / COLOR_ENTRIES - 1,
+												  1 - (time - frameTime) / (self->frames[frame + COLOR_PREV_TIME] - frameTime));
+
+		r += (self->frames[frame + COLOR_R] - r) * percent;
+		g += (self->frames[frame + COLOR_G] - g) * percent;
+		b += (self->frames[frame + COLOR_B] - b) * percent;
+		a += (self->frames[frame + COLOR_A] - a) * percent;
+	}
+	slot = skeleton->slots[self->slotIndex];
+	if (alpha < 1) {
+		slot->r += (r - slot->r) * alpha;
+		slot->g += (g - slot->g) * alpha;
+		slot->b += (b - slot->b) * alpha;
+		slot->a += (a - slot->a) * alpha;
+	} else {
+		slot->r = r;
+		slot->g = g;
+		slot->b = b;
+		slot->a = a;
+	}
+
+	UNUSED(lastTime);
+	UNUSED(firedEvents);
+	UNUSED(eventsCount);
+}
+
+spColorTimeline* spColorTimeline_create (int framesCount) {
+	return (spColorTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_COLOR, 5, _spColorTimeline_apply);
+}
+
+void spColorTimeline_setFrame (spColorTimeline* self, int frameIndex, float time, float r, float g, float b, float a) {
+	frameIndex *= COLOR_ENTRIES;
+	self->frames[frameIndex] = time;
+	self->frames[frameIndex + COLOR_R] = r;
+	self->frames[frameIndex + COLOR_G] = g;
+	self->frames[frameIndex + COLOR_B] = b;
+	self->frames[frameIndex + COLOR_A] = a;
+}
+
+/**/
+
+void _spAttachmentTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
+		spEvent** firedEvents, int* eventsCount, float alpha) {
+	const char* attachmentName;
+	spAttachmentTimeline* self = (spAttachmentTimeline*)timeline;
+	int frameIndex;
+
+	if (time < self->frames[0]) return;
+
+	if (time >= self->frames[self->framesCount - 1])
+		frameIndex = self->framesCount - 1;
+	else
+		frameIndex = binarySearch1(self->frames, self->framesCount, time) - 1;
+
+	attachmentName = self->attachmentNames[frameIndex];
+	spSlot_setAttachment(skeleton->slots[self->slotIndex],
+			attachmentName ? spSkeleton_getAttachmentForSlotIndex(skeleton, self->slotIndex, attachmentName) : 0);
+
+	UNUSED(lastTime);
+	UNUSED(firedEvents);
+	UNUSED(eventsCount);
+	UNUSED(alpha);
+}
+
+void _spAttachmentTimeline_dispose (spTimeline* timeline) {
+	spAttachmentTimeline* self = SUB_CAST(spAttachmentTimeline, timeline);
+	int i;
+
+	_spTimeline_deinit(timeline);
+
+	for (i = 0; i < self->framesCount; ++i)
+		FREE(self->attachmentNames[i]);
+	FREE(self->attachmentNames);
+	FREE(self->frames);
+	FREE(self);
+}
+
+spAttachmentTimeline* spAttachmentTimeline_create (int framesCount) {
+	spAttachmentTimeline* self = NEW(spAttachmentTimeline);
+	_spTimeline_init(SUPER(self), SP_TIMELINE_ATTACHMENT, _spAttachmentTimeline_dispose, _spAttachmentTimeline_apply);
+
+	CONST_CAST(int, self->framesCount) = framesCount;
+	CONST_CAST(float*, self->frames) = CALLOC(float, framesCount);
+	CONST_CAST(char**, self->attachmentNames) = CALLOC(char*, framesCount);
+
+	return self;
+}
+
+void spAttachmentTimeline_setFrame (spAttachmentTimeline* self, int frameIndex, float time, const char* attachmentName) {
+	self->frames[frameIndex] = time;
+
+	FREE(self->attachmentNames[frameIndex]);
+	if (attachmentName)
+		MALLOC_STR(self->attachmentNames[frameIndex], attachmentName);
+	else
+		self->attachmentNames[frameIndex] = 0;
+}
+
+/**/
+
+/** Fires events for frames > lastTime and <= time. */
+void _spEventTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
+		int* eventsCount, float alpha) {
+	spEventTimeline* self = (spEventTimeline*)timeline;
+	int frame;
+	if (!firedEvents) return;
+
+	if (lastTime > time) { /* Fire events after last time for looped animations. */
+		_spEventTimeline_apply(timeline, skeleton, lastTime, (float)INT_MAX, firedEvents, eventsCount, alpha);
+		lastTime = -1;
+	} else if (lastTime >= self->frames[self->framesCount - 1]) /* Last time is after last frame. */
+	return;
+	if (time < self->frames[0]) return; /* Time is before first frame. */
+
+	if (lastTime < self->frames[0])
+		frame = 0;
+	else {
+		float frameTime;
+		frame = binarySearch1(self->frames, self->framesCount, lastTime);
+		frameTime = self->frames[frame];
+		while (frame > 0) { /* Fire multiple events with the same frame. */
+			if (self->frames[frame - 1] != frameTime) break;
+			frame--;
+		}
+	}
+	for (; frame < self->framesCount && time >= self->frames[frame]; ++frame) {
+		firedEvents[*eventsCount] = self->events[frame];
+		(*eventsCount)++;
+	}
+}
+
+void _spEventTimeline_dispose (spTimeline* timeline) {
+	spEventTimeline* self = SUB_CAST(spEventTimeline, timeline);
+	int i;
+
+	_spTimeline_deinit(timeline);
+
+	for (i = 0; i < self->framesCount; ++i)
+		spEvent_dispose(self->events[i]);
+	FREE(self->events);
+	FREE(self->frames);
+	FREE(self);
+}
+
+spEventTimeline* spEventTimeline_create (int framesCount) {
+	spEventTimeline* self = NEW(spEventTimeline);
+	_spTimeline_init(SUPER(self), SP_TIMELINE_EVENT, _spEventTimeline_dispose, _spEventTimeline_apply);
+
+	CONST_CAST(int, self->framesCount) = framesCount;
+	CONST_CAST(float*, self->frames) = CALLOC(float, framesCount);
+	CONST_CAST(spEvent**, self->events) = CALLOC(spEvent*, framesCount);
+
+	return self;
+}
+
+void spEventTimeline_setFrame (spEventTimeline* self, int frameIndex, spEvent* event) {
+	self->frames[frameIndex] = event->time;
+
+	FREE(self->events[frameIndex]);
+	self->events[frameIndex] = event;
+}
+
+/**/
+
+void _spDrawOrderTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
+		spEvent** firedEvents, int* eventsCount, float alpha) {
+	int i;
+	int frame;
+	const int* drawOrderToSetupIndex;
+	spDrawOrderTimeline* self = (spDrawOrderTimeline*)timeline;
+
+	if (time < self->frames[0]) return; /* Time is before first frame. */
+
+	if (time >= self->frames[self->framesCount - 1]) /* Time is after last frame. */
+		frame = self->framesCount - 1;
+	else
+		frame = binarySearch1(self->frames, self->framesCount, time) - 1;
+
+	drawOrderToSetupIndex = self->drawOrders[frame];
+	if (!drawOrderToSetupIndex)
+		memcpy(skeleton->drawOrder, skeleton->slots, self->slotsCount * sizeof(spSlot*));
+	else {
+		for (i = 0; i < self->slotsCount; ++i)
+			skeleton->drawOrder[i] = skeleton->slots[drawOrderToSetupIndex[i]];
+	}
+
+	UNUSED(lastTime);
+	UNUSED(firedEvents);
+	UNUSED(eventsCount);
+	UNUSED(alpha);
+}
+
+void _spDrawOrderTimeline_dispose (spTimeline* timeline) {
+	spDrawOrderTimeline* self = SUB_CAST(spDrawOrderTimeline, timeline);
+	int i;
+
+	_spTimeline_deinit(timeline);
+
+	for (i = 0; i < self->framesCount; ++i)
+		FREE(self->drawOrders[i]);
+	FREE(self->drawOrders);
+	FREE(self->frames);
+	FREE(self);
+}
+
+spDrawOrderTimeline* spDrawOrderTimeline_create (int framesCount, int slotsCount) {
+	spDrawOrderTimeline* self = NEW(spDrawOrderTimeline);
+	_spTimeline_init(SUPER(self), SP_TIMELINE_DRAWORDER, _spDrawOrderTimeline_dispose, _spDrawOrderTimeline_apply);
+
+	CONST_CAST(int, self->framesCount) = framesCount;
+	CONST_CAST(float*, self->frames) = CALLOC(float, framesCount);
+	CONST_CAST(int**, self->drawOrders) = CALLOC(int*, framesCount);
+	CONST_CAST(int, self->slotsCount) = slotsCount;
+
+	return self;
+}
+
+void spDrawOrderTimeline_setFrame (spDrawOrderTimeline* self, int frameIndex, float time, const int* drawOrder) {
+	self->frames[frameIndex] = time;
+
+	FREE(self->drawOrders[frameIndex]);
+	if (!drawOrder)
+		self->drawOrders[frameIndex] = 0;
+	else {
+		self->drawOrders[frameIndex] = MALLOC(int, self->slotsCount);
+		memcpy(CONST_CAST(int*, self->drawOrders[frameIndex]), drawOrder, self->slotsCount * sizeof(int));
+	}
+}
+
+/**/
+
+void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
+		int* eventsCount, float alpha) {
+	int frame, i, vertexCount;
+	float percent, frameTime;
+	const float* prevVertices;
+	const float* nextVertices;
+	spDeformTimeline* self = (spDeformTimeline*)timeline;
+
+	spSlot *slot = skeleton->slots[self->slotIndex];
+
+	if (slot->attachment != self->attachment) {
+		if (!slot->attachment) return;
+		switch (slot->attachment->type) {
+		case SP_ATTACHMENT_MESH: {
+			spMeshAttachment* mesh = SUB_CAST(spMeshAttachment, slot->attachment);
+			if (!mesh->inheritDeform || mesh->parentMesh != (void*)self->attachment) return;
+			break;
+		}
+		default:
+			return;
+		}
+	}
+
+	if (time < self->frames[0]) return; /* Time is before first frame. */
+
+	vertexCount = self->frameVerticesCount;
+	if (slot->attachmentVerticesCount < vertexCount) {
+		if (slot->attachmentVerticesCapacity < vertexCount) {
+			FREE(slot->attachmentVertices);
+			slot->attachmentVertices = MALLOC(float, vertexCount);
+			slot->attachmentVerticesCapacity = vertexCount;
+		}
+	}
+	if (slot->attachmentVerticesCount != vertexCount) alpha = 1; /* Don't mix from uninitialized slot vertices. */
+	slot->attachmentVerticesCount = vertexCount;
+
+	if (time >= self->frames[self->framesCount - 1]) {
+		/* Time is after last frame. */
+		const float* lastVertices = self->frameVertices[self->framesCount - 1];
+		if (alpha < 1) {
+			for (i = 0; i < vertexCount; ++i)
+				slot->attachmentVertices[i] += (lastVertices[i] - slot->attachmentVertices[i]) * alpha;
+		} else
+			memcpy(slot->attachmentVertices, lastVertices, vertexCount * sizeof(float));
+		return;
+	}
+
+	/* Interpolate between the previous frame and the current frame. */
+	frame = binarySearch1(self->frames, self->framesCount, time);
+	frameTime = self->frames[frame];
+	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame - 1, 1 - (time - frameTime) / (self->frames[frame - 1] - frameTime));
+
+	prevVertices = self->frameVertices[frame - 1];
+	nextVertices = self->frameVertices[frame];
+
+	if (alpha < 1) {
+		for (i = 0; i < vertexCount; ++i) {
+			float prev = prevVertices[i];
+			slot->attachmentVertices[i] += (prev + (nextVertices[i] - prev) * percent - slot->attachmentVertices[i]) * alpha;
+		}
+	} else {
+		for (i = 0; i < vertexCount; ++i) {
+			float prev = prevVertices[i];
+			slot->attachmentVertices[i] = prev + (nextVertices[i] - prev) * percent;
+		}
+	}
+
+	UNUSED(lastTime);
+	UNUSED(firedEvents);
+	UNUSED(eventsCount);
+}
+
+void _spDeformTimeline_dispose (spTimeline* timeline) {
+	spDeformTimeline* self = SUB_CAST(spDeformTimeline, timeline);
+	int i;
+
+	_spCurveTimeline_deinit(SUPER(self));
+
+	for (i = 0; i < self->framesCount; ++i)
+		FREE(self->frameVertices[i]);
+	FREE(self->frameVertices);
+	FREE(self->frames);
+	FREE(self);
+}
+
+spDeformTimeline* spDeformTimeline_create (int framesCount, int frameVerticesCount) {
+	spDeformTimeline* self = NEW(spDeformTimeline);
+	_spCurveTimeline_init(SUPER(self), SP_TIMELINE_DEFORM, framesCount, _spDeformTimeline_dispose, _spDeformTimeline_apply);
+	CONST_CAST(int, self->framesCount) = framesCount;
+	CONST_CAST(float*, self->frames) = CALLOC(float, self->framesCount);
+	CONST_CAST(float**, self->frameVertices) = CALLOC(float*, framesCount);
+	CONST_CAST(int, self->frameVerticesCount) = frameVerticesCount;
+	return self;
+}
+
+void spDeformTimeline_setFrame (spDeformTimeline* self, int frameIndex, float time, float* vertices) {
+	self->frames[frameIndex] = time;
+
+	FREE(self->frameVertices[frameIndex]);
+	if (!vertices)
+		self->frameVertices[frameIndex] = 0;
+	else {
+		self->frameVertices[frameIndex] = MALLOC(float, self->frameVerticesCount);
+		memcpy(CONST_CAST(float*, self->frameVertices[frameIndex]), vertices, self->frameVerticesCount * sizeof(float));
+	}
+}
+
+
+/**/
+
+static const int IKCONSTRAINT_PREV_TIME = -3, IKCONSTRAINT_PREV_MIX = -2, IKCONSTRAINT_PREV_BEND_DIRECTION = -1;
+static const int IKCONSTRAINT_MIX = 1, IKCONSTRAINT_BEND_DIRECTION = 2;
+
+void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
+		spEvent** firedEvents, int* eventsCount, float alpha) {
+	int frame;
+	float frameTime, percent, mix;
+	spIkConstraint* constraint;
+	spIkConstraintTimeline* self = (spIkConstraintTimeline*)timeline;
+
+	if (time < self->frames[0]) return; /* Time is before first frame. */
+
+	constraint = skeleton->ikConstraints[self->ikConstraintIndex];
+
+	if (time >= self->frames[self->framesCount - IKCONSTRAINT_ENTRIES]) { /* Time is after last frame. */
+		constraint->mix += (self->frames[self->framesCount + IKCONSTRAINT_PREV_MIX] - constraint->mix) * alpha;
+		constraint->bendDirection = (int)self->frames[self->framesCount + IKCONSTRAINT_PREV_BEND_DIRECTION];
+		return;
+	}
+
+	/* Interpolate between the previous frame and the current frame. */
+	frame = binarySearch(self->frames, self->framesCount, time, IKCONSTRAINT_ENTRIES);
+	mix = self->frames[frame + IKCONSTRAINT_PREV_MIX];
+	frameTime = self->frames[frame];
+	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / IKCONSTRAINT_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + IKCONSTRAINT_PREV_TIME] - frameTime));
+
+	constraint->mix += (mix + (self->frames[frame + IKCONSTRAINT_MIX] - mix) * percent - constraint->mix) * alpha;
+	constraint->bendDirection = (int)self->frames[frame + IKCONSTRAINT_PREV_BEND_DIRECTION];
+
+	UNUSED(lastTime);
+	UNUSED(firedEvents);
+	UNUSED(eventsCount);
+}
+
+spIkConstraintTimeline* spIkConstraintTimeline_create (int framesCount) {
+	return (spIkConstraintTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_IKCONSTRAINT, IKCONSTRAINT_ENTRIES, _spIkConstraintTimeline_apply);
+}
+
+void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameIndex, float time, float mix, int bendDirection) {
+	frameIndex *= IKCONSTRAINT_ENTRIES;
+	self->frames[frameIndex] = time;
+	self->frames[frameIndex + IKCONSTRAINT_MIX] = mix;
+	self->frames[frameIndex + IKCONSTRAINT_BEND_DIRECTION] = (float)bendDirection;
+}
+
+/**/
+static const int TRANSFORMCONSTRAINT_PREV_TIME = -5;
+static const int TRANSFORMCONSTRAINT_PREV_ROTATE = -4;
+static const int TRANSFORMCONSTRAINT_PREV_TRANSLATE = -3;
+static const int TRANSFORMCONSTRAINT_PREV_SCALE = -2;
+static const int TRANSFORMCONSTRAINT_PREV_SHEAR = -1;
+static const int TRANSFORMCONSTRAINT_ROTATE = 1;
+static const int TRANSFORMCONSTRAINT_TRANSLATE = 2;
+static const int TRANSFORMCONSTRAINT_SCALE = 3;
+static const int TRANSFORMCONSTRAINT_SHEAR = 4;
+
+void _spTransformConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
+									spEvent** firedEvents, int* eventsCount, float alpha) {
+	int frame;
+	float frameTime, percent, rotate, translate, scale, shear;
+	spTransformConstraint* constraint;
+	spTransformConstraintTimeline* self = (spTransformConstraintTimeline*)timeline;
+
+	if (time < self->frames[0]) return; /* Time is before first frame. */
+
+	constraint = skeleton->transformConstraints[self->transformConstraintIndex];
+
+	if (time >= self->frames[self->framesCount - TRANSFORMCONSTRAINT_ENTRIES]) { /* Time is after last frame. */
+		int len = self->framesCount;
+		constraint->rotateMix += (self->frames[len + TRANSFORMCONSTRAINT_PREV_ROTATE] - constraint->rotateMix) * alpha;
+		constraint->translateMix += (self->frames[len + TRANSFORMCONSTRAINT_PREV_TRANSLATE] - constraint->translateMix) * alpha;
+		constraint->scaleMix += (self->frames[len + TRANSFORMCONSTRAINT_PREV_SCALE] - constraint->scaleMix) * alpha;
+		constraint->shearMix += (self->frames[len + TRANSFORMCONSTRAINT_PREV_SHEAR] - constraint->shearMix) * alpha;
+		return;
+	}
+
+	/* Interpolate between the previous frame and the current frame. */
+	frame = binarySearch(self->frames, self->framesCount, time, TRANSFORMCONSTRAINT_ENTRIES);
+	frameTime = self->frames[frame];
+	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSFORMCONSTRAINT_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + TRANSFORMCONSTRAINT_PREV_TIME] - frameTime));
+
+	rotate = self->frames[frame + TRANSFORMCONSTRAINT_PREV_ROTATE];
+	translate = self->frames[frame + TRANSFORMCONSTRAINT_PREV_TRANSLATE];
+	scale = self->frames[frame + TRANSFORMCONSTRAINT_PREV_SCALE];
+	shear = self->frames[frame + TRANSFORMCONSTRAINT_PREV_SHEAR];
+	constraint->rotateMix += (rotate + (self->frames[frame + TRANSFORMCONSTRAINT_ROTATE] - rotate) * percent - constraint->rotateMix) * alpha;
+	constraint->translateMix += (translate + (self->frames[frame + TRANSFORMCONSTRAINT_TRANSLATE] - translate) * percent - constraint->translateMix) * alpha;
+	constraint->scaleMix += (scale + (self->frames[frame + TRANSFORMCONSTRAINT_SCALE] - scale) * percent - constraint->scaleMix) * alpha;
+	constraint->shearMix += (shear + (self->frames[frame + TRANSFORMCONSTRAINT_SHEAR] - shear) * percent - constraint->shearMix) * alpha;
+
+	UNUSED(lastTime);
+	UNUSED(firedEvents);
+	UNUSED(eventsCount);
+}
+
+spTransformConstraintTimeline* spTransformConstraintTimeline_create (int framesCount) {
+	return (spTransformConstraintTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_TRANSFORMCONSTRAINT, TRANSFORMCONSTRAINT_ENTRIES, _spTransformConstraintTimeline_apply);
+}
+
+void spTransformConstraintTimeline_setFrame (spTransformConstraintTimeline* self, int frameIndex, float time, float rotateMix, float translateMix, float scaleMix, float shearMix) {
+	frameIndex *= TRANSFORMCONSTRAINT_ENTRIES;
+	self->frames[frameIndex] = time;
+	self->frames[frameIndex + TRANSFORMCONSTRAINT_ROTATE] = rotateMix;
+	self->frames[frameIndex + TRANSFORMCONSTRAINT_TRANSLATE] = translateMix;
+	self->frames[frameIndex + TRANSFORMCONSTRAINT_SCALE] = scaleMix;
+	self->frames[frameIndex + TRANSFORMCONSTRAINT_SHEAR] = shearMix;
+}
+
+/**/
+
+static const int PATHCONSTRAINTPOSITION_PREV_TIME = -2;
+static const int PATHCONSTRAINTPOSITION_PREV_VALUE = -1;
+static const int PATHCONSTRAINTPOSITION_VALUE = 1;
+
+void _spPathConstraintPositionTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
+											 spEvent** firedEvents, int* eventsCount, float alpha) {
+	int frame;
+	float frameTime, percent, position;
+	spPathConstraint* constraint;
+	spPathConstraintPositionTimeline* self = (spPathConstraintPositionTimeline*)timeline;
+
+	if (time < self->frames[0]) return; /* Time is before first frame. */
+
+	constraint = skeleton->pathConstraints[self->pathConstraintIndex];
+
+	if (time >= self->frames[self->framesCount - PATHCONSTRAINTPOSITION_ENTRIES]) { /* Time is after last frame. */
+		int len = self->framesCount;
+		constraint->position += (self->frames[len + PATHCONSTRAINTPOSITION_PREV_VALUE] - constraint->position) * alpha;
+		return;
+	}
+
+	/* Interpolate between the previous frame and the current frame. */
+	frame = binarySearch(self->frames, self->framesCount, time, PATHCONSTRAINTPOSITION_ENTRIES);
+	position = self->frames[frame + PATHCONSTRAINTPOSITION_PREV_VALUE];
+	frameTime = self->frames[frame];
+	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / PATHCONSTRAINTPOSITION_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + PATHCONSTRAINTPOSITION_PREV_TIME] - frameTime));
+
+	constraint->position += (position + (self->frames[frame + PATHCONSTRAINTPOSITION_VALUE] - position) * percent - constraint->position) * alpha;
+
+	UNUSED(lastTime);
+	UNUSED(firedEvents);
+	UNUSED(eventsCount);
+}
+
+spPathConstraintPositionTimeline* spPathConstraintPositionTimeline_create (int framesCount) {
+	return (spPathConstraintPositionTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_PATHCONSTRAINTPOSITION, PATHCONSTRAINTPOSITION_ENTRIES, _spPathConstraintPositionTimeline_apply);
+}
+
+void spPathConstraintPositionTimeline_setFrame (spPathConstraintPositionTimeline* self, int frameIndex, float time, float value) {
+	frameIndex *= PATHCONSTRAINTPOSITION_ENTRIES;
+	self->frames[frameIndex] = time;
+	self->frames[frameIndex + PATHCONSTRAINTPOSITION_VALUE] = value;
+}
+
+/**/
+static const int PATHCONSTRAINTSPACING_PREV_TIME = -2;
+static const int PATHCONSTRAINTSPACING_PREV_VALUE = -1;
+static const int PATHCONSTRAINTSPACING_VALUE = 1;
+
+void _spPathConstraintSpacingTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
+											 spEvent** firedEvents, int* eventsCount, float alpha) {
+	int frame;
+	float frameTime, percent, spacing;
+	spPathConstraint* constraint;
+	spPathConstraintSpacingTimeline* self = (spPathConstraintSpacingTimeline*)timeline;
+
+	if (time < self->frames[0]) return; /* Time is before first frame. */
+
+	constraint = skeleton->pathConstraints[self->pathConstraintIndex];
+
+	if (time >= self->frames[self->framesCount - PATHCONSTRAINTSPACING_ENTRIES]) { /* Time is after last frame. */
+		int len = self->framesCount;
+		constraint->spacing += (self->frames[len + PATHCONSTRAINTSPACING_PREV_VALUE] - constraint->spacing) * alpha;
+		return;
+	}
+
+	/* Interpolate between the previous frame and the current frame. */
+	frame = binarySearch(self->frames, self->framesCount, time, PATHCONSTRAINTSPACING_ENTRIES);
+	spacing = self->frames[frame + PATHCONSTRAINTSPACING_PREV_VALUE];
+	frameTime = self->frames[frame];
+	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / PATHCONSTRAINTSPACING_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + PATHCONSTRAINTSPACING_PREV_TIME] - frameTime));
+
+	constraint->spacing += (spacing + (self->frames[frame + PATHCONSTRAINTSPACING_VALUE] - spacing) * percent - constraint->spacing) * alpha;
+
+	UNUSED(lastTime);
+	UNUSED(firedEvents);
+	UNUSED(eventsCount);
+}
+
+spPathConstraintSpacingTimeline* spPathConstraintSpacingTimeline_create (int framesCount) {
+	return (spPathConstraintSpacingTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_PATHCONSTRAINTSPACING, PATHCONSTRAINTSPACING_ENTRIES, _spPathConstraintSpacingTimeline_apply);
+}
+
+void spPathConstraintSpacingTimeline_setFrame (spPathConstraintSpacingTimeline* self, int frameIndex, float time, float value) {
+	frameIndex *= PATHCONSTRAINTSPACING_ENTRIES;
+	self->frames[frameIndex] = time;
+	self->frames[frameIndex + PATHCONSTRAINTSPACING_VALUE] = value;
+}
+
+/**/
+
+static const int PATHCONSTRAINTMIX_PREV_TIME = -3;
+static const int PATHCONSTRAINTMIX_PREV_ROTATE = -2;
+static const int PATHCONSTRAINTMIX_PREV_TRANSLATE = -1;
+static const int PATHCONSTRAINTMIX_ROTATE = 1;
+static const int PATHCONSTRAINTMIX_TRANSLATE = 2;
+
+void _spPathConstraintMixTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
+											spEvent** firedEvents, int* eventsCount, float alpha) {
+	int frame;
+	float frameTime, percent, rotate, translate;
+	spPathConstraint* constraint;
+	spPathConstraintMixTimeline* self = (spPathConstraintMixTimeline*)timeline;
+
+	if (time < self->frames[0]) return; /* Time is before first frame. */
+
+	constraint = skeleton->pathConstraints[self->pathConstraintIndex];
+
+	if (time >= self->frames[self->framesCount - PATHCONSTRAINTMIX_ENTRIES]) { /* Time is after last frame. */
+		int len = self->framesCount;
+		constraint->rotateMix += (self->frames[len + PATHCONSTRAINTMIX_PREV_ROTATE] - constraint->rotateMix) * alpha;
+		constraint->translateMix += (self->frames[len + PATHCONSTRAINTMIX_PREV_TRANSLATE] - constraint->translateMix) * alpha;
+		return;
+	}
+
+	/* Interpolate between the previous frame and the current frame. */
+	frame = binarySearch(self->frames, self->framesCount, time, PATHCONSTRAINTMIX_ENTRIES);
+	rotate = self->frames[frame + PATHCONSTRAINTMIX_PREV_ROTATE];
+	translate = self->frames[frame + PATHCONSTRAINTMIX_PREV_TRANSLATE];
+	frameTime = self->frames[frame];
+	percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / PATHCONSTRAINTMIX_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + PATHCONSTRAINTMIX_PREV_TIME] - frameTime));
+
+	constraint->rotateMix += (rotate + (self->frames[frame + PATHCONSTRAINTMIX_ROTATE] - rotate) * percent - constraint->rotateMix) * alpha;
+	constraint->translateMix += (translate + (self->frames[frame + PATHCONSTRAINTMIX_TRANSLATE] - translate) * percent - constraint->translateMix) * alpha;
+
+	UNUSED(lastTime);
+	UNUSED(firedEvents);
+	UNUSED(eventsCount);
+}
+
+spPathConstraintMixTimeline* spPathConstraintMixTimeline_create (int framesCount) {
+	return (spPathConstraintMixTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_PATHCONSTRAINTMIX, PATHCONSTRAINTMIX_ENTRIES, _spPathConstraintMixTimeline_apply);
+}
+
+void spPathConstraintMixTimeline_setFrame (spPathConstraintMixTimeline* self, int frameIndex, float time, float rotateMix, float translateMix) {
+	frameIndex *= PATHCONSTRAINTMIX_ENTRIES;
+	self->frames[frameIndex] = time;
+	self->frames[frameIndex + PATHCONSTRAINTMIX_ROTATE] = rotateMix;
+	self->frames[frameIndex + PATHCONSTRAINTMIX_TRANSLATE] = translateMix;
 }

+ 319 - 320
spine-c/src/spine/AnimationState.c

@@ -1,323 +1,322 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#include <spine/AnimationState.h>
-#include <spine/extension.h>
-#include <string.h>
-
-spTrackEntry* _spTrackEntry_create (spAnimationState* state) {
-	spTrackEntry* self = NEW(spTrackEntry);
-	CONST_CAST(spAnimationState*, self->state) = state;
-	self->timeScale = 1;
-	self->lastTime = -1;
-	self->mix = 1;
-	return self;
-}
-
-void _spTrackEntry_dispose (spTrackEntry* self) {
-	if (self->previous) SUB_CAST(_spAnimationState, self->state)->disposeTrackEntry(self->previous);
-	FREE(self);
-}
-
-/**/
-
-spTrackEntry* _spAnimationState_createTrackEntry (spAnimationState* self) {
-	return _spTrackEntry_create(self);
-}
-
-void _spAnimationState_disposeTrackEntry (spTrackEntry* entry) {
-	_spTrackEntry_dispose(entry);
-}
-
-spAnimationState* spAnimationState_create (spAnimationStateData* data) {
-	_spAnimationState* internal = NEW(_spAnimationState);
-	spAnimationState* self = SUPER(internal);
-	internal->events = MALLOC(spEvent*, 64);
-	self->timeScale = 1;
-	CONST_CAST(spAnimationStateData*, self->data) = data;
-	internal->createTrackEntry = _spAnimationState_createTrackEntry;
-	internal->disposeTrackEntry = _spAnimationState_disposeTrackEntry;
-	return self;
-}
-
-void _spAnimationState_disposeAllEntries (spAnimationState* self, spTrackEntry* entry) {
-	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
-	while (entry) {
-		spTrackEntry* next = entry->next;
-		internal->disposeTrackEntry(entry);
-		entry = next;
-	}
-}
-
-void spAnimationState_dispose (spAnimationState* self) {
-	int i;
-	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
-	FREE(internal->events);
-	for (i = 0; i < self->tracksCount; ++i)
-		_spAnimationState_disposeAllEntries(self, self->tracks[i]);
-	FREE(self->tracks);
-	FREE(self);
-}
-
-void _spAnimationState_setCurrent (spAnimationState* self, int index, spTrackEntry* entry);
-
-void spAnimationState_update (spAnimationState* self, float delta) {
-	int i;
-	float previousDelta;
-	delta *= self->timeScale;
-	for (i = 0; i < self->tracksCount; ++i) {
-		spTrackEntry* current = self->tracks[i];
-		if (!current) continue;
-
-		current->time += delta * current->timeScale;
-		if (current->previous) {
-			previousDelta = delta * current->previous->timeScale;
-			current->previous->time += previousDelta;
-			current->mixTime += previousDelta;
-		}
-
-		if (current->next) {
-			current->next->time = current->lastTime - current->next->delay;
-			if (current->next->time >= 0) _spAnimationState_setCurrent(self, i, current->next);
-		} else {
-			/* End non-looping animation when it reaches its end time and there is no next entry. */
-			if (!current->loop && current->lastTime >= current->endTime) spAnimationState_clearTrack(self, i);
-		}
-	}
-}
-
-void spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
-	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
-
-	int i, ii;
-	int eventsCount;
-	int entryChanged;
-	float time;
-	spTrackEntry* previous;
-	for (i = 0; i < self->tracksCount; ++i) {
-		spTrackEntry* current = self->tracks[i];
-		if (!current) continue;
-
-		eventsCount = 0;
-
-		time = current->time;
-		if (!current->loop && time > current->endTime) time = current->endTime;
-
-		previous = current->previous;
-		if (!previous) {
-			if (current->mix == 1) {
-				spAnimation_apply(current->animation, skeleton, current->lastTime, time,
-					current->loop, internal->events, &eventsCount);
-			} else {
-				spAnimation_mix(current->animation, skeleton, current->lastTime, time,
-					current->loop, internal->events, &eventsCount, current->mix);
-			}
-		} else {
-			float alpha = current->mixTime / current->mixDuration * current->mix;
-
-			float previousTime = previous->time;
-			if (!previous->loop && previousTime > previous->endTime) previousTime = previous->endTime;
-			spAnimation_apply(previous->animation, skeleton, previousTime, previousTime, previous->loop, 0, 0);
-
-			if (alpha >= 1) {
-				alpha = 1;
-				internal->disposeTrackEntry(current->previous);
-				current->previous = 0;
-			}
-			spAnimation_mix(current->animation, skeleton, current->lastTime, time,
-				current->loop, internal->events, &eventsCount, alpha);
-		}
-
-		entryChanged = 0;
-		for (ii = 0; ii < eventsCount; ++ii) {
-			spEvent* event = internal->events[ii];
-			if (current->listener) {
-				current->listener(self, i, SP_ANIMATION_EVENT, event, 0);
-				if (self->tracks[i] != current) {
-					entryChanged = 1;
-					break;
-				}
-			}
-			if (self->listener) {
-				self->listener(self, i, SP_ANIMATION_EVENT, event, 0);
-				if (self->tracks[i] != current) {
-					entryChanged = 1;
-					break;
-				}
-			}
-		}
-		if (entryChanged) continue;
-
-		/* Check if completed the animation or a loop iteration. */
-		if (current->loop ? (FMOD(current->lastTime, current->endTime) > FMOD(time, current->endTime))
-				: (current->lastTime < current->endTime && time >= current->endTime)) {
-			int count = (int)(time / current->endTime);
-			if (current->listener) {
-				current->listener(self, i, SP_ANIMATION_COMPLETE, 0, count);
-				if (self->tracks[i] != current) continue;
-			}
-			if (self->listener) {
-				self->listener(self, i, SP_ANIMATION_COMPLETE, 0, count);
-				if (self->tracks[i] != current) continue;
-			}
-		}
-
-		current->lastTime = current->time;
-	}
-}
-
-void spAnimationState_clearTracks (spAnimationState* self) {
-	int i;
-	for (i = 0; i < self->tracksCount; ++i)
-		spAnimationState_clearTrack(self, i);
-	self->tracksCount = 0;
-}
-
-void spAnimationState_clearTrack (spAnimationState* self, int trackIndex) {
-	spTrackEntry* current;
-	if (trackIndex >= self->tracksCount) return;
-	current = self->tracks[trackIndex];
-	if (!current) return;
-
-	if (current->listener) current->listener(self, trackIndex, SP_ANIMATION_END, 0, 0);
-	if (self->listener) self->listener(self, trackIndex, SP_ANIMATION_END, 0, 0);
-
-	self->tracks[trackIndex] = 0;
-
-	_spAnimationState_disposeAllEntries(self, current);
-}
-
-spTrackEntry* _spAnimationState_expandToIndex (spAnimationState* self, int index) {
-	spTrackEntry** newTracks;
-	if (index < self->tracksCount) return self->tracks[index];
-	newTracks = CALLOC(spTrackEntry*, index + 1);
-	memcpy(newTracks, self->tracks, self->tracksCount * sizeof(spTrackEntry*));
-	FREE(self->tracks);
-	self->tracks = newTracks;
-	self->tracksCount = index + 1;
-	return 0;
-}
-
-void _spAnimationState_setCurrent (spAnimationState* self, int index, spTrackEntry* entry) {
-	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
-
-	spTrackEntry* current = _spAnimationState_expandToIndex(self, index);
-	if (current) {
-		spTrackEntry* previous = current->previous;
-		current->previous = 0;
-
-		if (current->listener) current->listener(self, index, SP_ANIMATION_END, 0, 0);
-		if (self->listener) self->listener(self, index, SP_ANIMATION_END, 0, 0);
-
-		entry->mixDuration = spAnimationStateData_getMix(self->data, current->animation, entry->animation);
-		if (entry->mixDuration > 0) {
-			entry->mixTime = 0;
-			/* If a mix is in progress, mix from the closest animation. */
-			if (previous && current->mixTime / current->mixDuration < 0.5f) {
-				entry->previous = previous;
-				previous = current;
-			} else
-				entry->previous = current;
-		} else
-			internal->disposeTrackEntry(current);
-
-		if (previous) internal->disposeTrackEntry(previous);
-	}
-
-	self->tracks[index] = entry;
-
-	if (entry->listener) {
-		entry->listener(self, index, SP_ANIMATION_START, 0, 0);
-		if (self->tracks[index] != entry) return;
-	}
-	if (self->listener) self->listener(self, index, SP_ANIMATION_START, 0, 0);
-}
-
-spTrackEntry* spAnimationState_setAnimationByName (spAnimationState* self, int trackIndex, const char* animationName,
-		int/*bool*/loop) {
-	spAnimation* animation = spSkeletonData_findAnimation(self->data->skeletonData, animationName);
-	return spAnimationState_setAnimation(self, trackIndex, animation, loop);
-}
-
-spTrackEntry* spAnimationState_setAnimation (spAnimationState* self, int trackIndex, spAnimation* animation, int/*bool*/loop) {
-	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
-
-	spTrackEntry* entry;
-	spTrackEntry* current = _spAnimationState_expandToIndex(self, trackIndex);
-	if (current) _spAnimationState_disposeAllEntries(self, current->next);
-
-	entry = internal->createTrackEntry(self);
-	entry->animation = animation;
-	entry->loop = loop;
-	entry->endTime = animation->duration;
-	_spAnimationState_setCurrent(self, trackIndex, entry);
-	return entry;
-}
-
-spTrackEntry* spAnimationState_addAnimationByName (spAnimationState* self, int trackIndex, const char* animationName,
-		int/*bool*/loop, float delay) {
-	spAnimation* animation = spSkeletonData_findAnimation(self->data->skeletonData, animationName);
-	return spAnimationState_addAnimation(self, trackIndex, animation, loop, delay);
-}
-
-spTrackEntry* spAnimationState_addAnimation (spAnimationState* self, int trackIndex, spAnimation* animation, int/*bool*/loop,
-		float delay) {
-	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
-	spTrackEntry* last;
-
-	spTrackEntry* entry = internal->createTrackEntry(self);
-	entry->animation = animation;
-	entry->loop = loop;
-	entry->endTime = animation->duration;
-
-	last = _spAnimationState_expandToIndex(self, trackIndex);
-	if (last) {
-		while (last->next)
-			last = last->next;
-		last->next = entry;
-	} else
-		self->tracks[trackIndex] = entry;
-
-	if (delay <= 0) {
-		if (last)
-			delay += last->endTime - spAnimationStateData_getMix(self->data, last->animation, animation);
-		else
-			delay = 0;
-	}
-	entry->delay = delay;
-
-	return entry;
-}
-
-spTrackEntry* spAnimationState_getCurrent (spAnimationState* self, int trackIndex) {
-	if (trackIndex >= self->tracksCount) return 0;
-	return self->tracks[trackIndex];
+#include <spine/AnimationState.h>
+#include <spine/extension.h>
+#include <string.h>
+
+spTrackEntry* _spTrackEntry_create (spAnimationState* state) {
+	spTrackEntry* self = NEW(spTrackEntry);
+	CONST_CAST(spAnimationState*, self->state) = state;
+	self->timeScale = 1;
+	self->lastTime = -1;
+	self->mix = 1;
+	return self;
+}
+
+void _spTrackEntry_dispose (spTrackEntry* self) {
+	if (self->previous) SUB_CAST(_spAnimationState, self->state)->disposeTrackEntry(self->previous);
+	FREE(self);
+}
+
+/**/
+
+spTrackEntry* _spAnimationState_createTrackEntry (spAnimationState* self) {
+	return _spTrackEntry_create(self);
+}
+
+void _spAnimationState_disposeTrackEntry (spTrackEntry* entry) {
+	_spTrackEntry_dispose(entry);
+}
+
+spAnimationState* spAnimationState_create (spAnimationStateData* data) {
+	_spAnimationState* internal = NEW(_spAnimationState);
+	spAnimationState* self = SUPER(internal);
+	internal->events = MALLOC(spEvent*, 64);
+	self->timeScale = 1;
+	CONST_CAST(spAnimationStateData*, self->data) = data;
+	internal->createTrackEntry = _spAnimationState_createTrackEntry;
+	internal->disposeTrackEntry = _spAnimationState_disposeTrackEntry;
+	return self;
+}
+
+void _spAnimationState_disposeAllEntries (spAnimationState* self, spTrackEntry* entry) {
+	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
+	while (entry) {
+		spTrackEntry* next = entry->next;
+		internal->disposeTrackEntry(entry);
+		entry = next;
+	}
+}
+
+void spAnimationState_dispose (spAnimationState* self) {
+	int i;
+	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
+	FREE(internal->events);
+	for (i = 0; i < self->tracksCount; ++i)
+		_spAnimationState_disposeAllEntries(self, self->tracks[i]);
+	FREE(self->tracks);
+	FREE(self);
+}
+
+void _spAnimationState_setCurrent (spAnimationState* self, int index, spTrackEntry* entry);
+
+void spAnimationState_update (spAnimationState* self, float delta) {
+	int i;
+	float previousDelta;
+	delta *= self->timeScale;
+	for (i = 0; i < self->tracksCount; ++i) {
+		spTrackEntry* current = self->tracks[i];
+		if (!current) continue;
+
+		current->time += delta * current->timeScale;
+		if (current->previous) {
+			previousDelta = delta * current->previous->timeScale;
+			current->previous->time += previousDelta;
+			current->mixTime += previousDelta;
+		}
+
+		if (current->next) {
+			current->next->time = current->lastTime - current->next->delay;
+			if (current->next->time >= 0) _spAnimationState_setCurrent(self, i, current->next);
+		} else {
+			/* End non-looping animation when it reaches its end time and there is no next entry. */
+			if (!current->loop && current->lastTime >= current->endTime) spAnimationState_clearTrack(self, i);
+		}
+	}
+}
+
+void spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
+	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
+
+	int i, ii;
+	int eventsCount;
+	int entryChanged;
+	float time;
+	spTrackEntry* previous;
+	for (i = 0; i < self->tracksCount; ++i) {
+		spTrackEntry* current = self->tracks[i];
+		if (!current) continue;
+
+		eventsCount = 0;
+
+		time = current->time;
+		if (!current->loop && time > current->endTime) time = current->endTime;
+
+		previous = current->previous;
+		if (!previous) {
+			if (current->mix == 1) {
+				spAnimation_apply(current->animation, skeleton, current->lastTime, time,
+					current->loop, internal->events, &eventsCount);
+			} else {
+				spAnimation_mix(current->animation, skeleton, current->lastTime, time,
+					current->loop, internal->events, &eventsCount, current->mix);
+			}
+		} else {
+			float alpha = current->mixTime / current->mixDuration * current->mix;
+
+			float previousTime = previous->time;
+			if (!previous->loop && previousTime > previous->endTime) previousTime = previous->endTime;
+			spAnimation_apply(previous->animation, skeleton, previousTime, previousTime, previous->loop, 0, 0);
+
+			if (alpha >= 1) {
+				alpha = 1;
+				internal->disposeTrackEntry(current->previous);
+				current->previous = 0;
+			}
+			spAnimation_mix(current->animation, skeleton, current->lastTime, time,
+				current->loop, internal->events, &eventsCount, alpha);
+		}
+
+		entryChanged = 0;
+		for (ii = 0; ii < eventsCount; ++ii) {
+			spEvent* event = internal->events[ii];
+			if (current->listener) {
+				current->listener(self, i, SP_ANIMATION_EVENT, event, 0);
+				if (self->tracks[i] != current) {
+					entryChanged = 1;
+					break;
+				}
+			}
+			if (self->listener) {
+				self->listener(self, i, SP_ANIMATION_EVENT, event, 0);
+				if (self->tracks[i] != current) {
+					entryChanged = 1;
+					break;
+				}
+			}
+		}
+		if (entryChanged) continue;
+
+		/* Check if completed the animation or a loop iteration. */
+		if (current->loop ? (FMOD(current->lastTime, current->endTime) > FMOD(time, current->endTime))
+				: (current->lastTime < current->endTime && time >= current->endTime)) {
+			int count = (int)(time / current->endTime);
+			if (current->listener) {
+				current->listener(self, i, SP_ANIMATION_COMPLETE, 0, count);
+				if (self->tracks[i] != current) continue;
+			}
+			if (self->listener) {
+				self->listener(self, i, SP_ANIMATION_COMPLETE, 0, count);
+				if (self->tracks[i] != current) continue;
+			}
+		}
+
+		current->lastTime = current->time;
+	}
+}
+
+void spAnimationState_clearTracks (spAnimationState* self) {
+	int i;
+	for (i = 0; i < self->tracksCount; ++i)
+		spAnimationState_clearTrack(self, i);
+	self->tracksCount = 0;
+}
+
+void spAnimationState_clearTrack (spAnimationState* self, int trackIndex) {
+	spTrackEntry* current;
+	if (trackIndex >= self->tracksCount) return;
+	current = self->tracks[trackIndex];
+	if (!current) return;
+
+	if (current->listener) current->listener(self, trackIndex, SP_ANIMATION_END, 0, 0);
+	if (self->listener) self->listener(self, trackIndex, SP_ANIMATION_END, 0, 0);
+
+	self->tracks[trackIndex] = 0;
+
+	_spAnimationState_disposeAllEntries(self, current);
+}
+
+spTrackEntry* _spAnimationState_expandToIndex (spAnimationState* self, int index) {
+	spTrackEntry** newTracks;
+	if (index < self->tracksCount) return self->tracks[index];
+	newTracks = CALLOC(spTrackEntry*, index + 1);
+	memcpy(newTracks, self->tracks, self->tracksCount * sizeof(spTrackEntry*));
+	FREE(self->tracks);
+	self->tracks = newTracks;
+	self->tracksCount = index + 1;
+	return 0;
+}
+
+void _spAnimationState_setCurrent (spAnimationState* self, int index, spTrackEntry* entry) {
+	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
+
+	spTrackEntry* current = _spAnimationState_expandToIndex(self, index);
+	if (current) {
+		spTrackEntry* previous = current->previous;
+		current->previous = 0;
+
+		if (current->listener) current->listener(self, index, SP_ANIMATION_END, 0, 0);
+		if (self->listener) self->listener(self, index, SP_ANIMATION_END, 0, 0);
+
+		entry->mixDuration = spAnimationStateData_getMix(self->data, current->animation, entry->animation);
+		if (entry->mixDuration > 0) {
+			entry->mixTime = 0;
+			/* If a mix is in progress, mix from the closest animation. */
+			if (previous && current->mixTime / current->mixDuration < 0.5f) {
+				entry->previous = previous;
+				previous = current;
+			} else
+				entry->previous = current;
+		} else
+			internal->disposeTrackEntry(current);
+
+		if (previous) internal->disposeTrackEntry(previous);
+	}
+
+	self->tracks[index] = entry;
+
+	if (entry->listener) {
+		entry->listener(self, index, SP_ANIMATION_START, 0, 0);
+		if (self->tracks[index] != entry) return;
+	}
+	if (self->listener) self->listener(self, index, SP_ANIMATION_START, 0, 0);
+}
+
+spTrackEntry* spAnimationState_setAnimationByName (spAnimationState* self, int trackIndex, const char* animationName,
+		int/*bool*/loop) {
+	spAnimation* animation = spSkeletonData_findAnimation(self->data->skeletonData, animationName);
+	return spAnimationState_setAnimation(self, trackIndex, animation, loop);
+}
+
+spTrackEntry* spAnimationState_setAnimation (spAnimationState* self, int trackIndex, spAnimation* animation, int/*bool*/loop) {
+	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
+
+	spTrackEntry* entry;
+	spTrackEntry* current = _spAnimationState_expandToIndex(self, trackIndex);
+	if (current) _spAnimationState_disposeAllEntries(self, current->next);
+
+	entry = internal->createTrackEntry(self);
+	entry->animation = animation;
+	entry->loop = loop;
+	entry->endTime = animation->duration;
+	_spAnimationState_setCurrent(self, trackIndex, entry);
+	return entry;
+}
+
+spTrackEntry* spAnimationState_addAnimationByName (spAnimationState* self, int trackIndex, const char* animationName,
+		int/*bool*/loop, float delay) {
+	spAnimation* animation = spSkeletonData_findAnimation(self->data->skeletonData, animationName);
+	return spAnimationState_addAnimation(self, trackIndex, animation, loop, delay);
+}
+
+spTrackEntry* spAnimationState_addAnimation (spAnimationState* self, int trackIndex, spAnimation* animation, int/*bool*/loop,
+		float delay) {
+	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
+	spTrackEntry* last;
+
+	spTrackEntry* entry = internal->createTrackEntry(self);
+	entry->animation = animation;
+	entry->loop = loop;
+	entry->endTime = animation->duration;
+
+	last = _spAnimationState_expandToIndex(self, trackIndex);
+	if (last) {
+		while (last->next)
+			last = last->next;
+		last->next = entry;
+	} else
+		self->tracks[trackIndex] = entry;
+
+	if (delay <= 0) {
+		if (last)
+			delay += last->endTime - spAnimationStateData_getMix(self->data, last->animation, animation);
+		else
+			delay = 0;
+	}
+	entry->delay = delay;
+
+	return entry;
+}
+
+spTrackEntry* spAnimationState_getCurrent (spAnimationState* self, int trackIndex) {
+	if (trackIndex >= self->tracksCount) return 0;
+	return self->tracks[trackIndex];
 }

+ 148 - 149
spine-c/src/spine/AnimationStateData.c

@@ -1,152 +1,151 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#include <spine/AnimationStateData.h>
-#include <spine/extension.h>
-
-typedef struct _ToEntry _ToEntry;
-struct _ToEntry {
-	spAnimation* animation;
-	float duration;
-	_ToEntry* next;
-};
-
-_ToEntry* _ToEntry_create (spAnimation* to, float duration) {
-	_ToEntry* self = NEW(_ToEntry);
-	self->animation = to;
-	self->duration = duration;
-	return self;
-}
-
-void _ToEntry_dispose (_ToEntry* self) {
-	FREE(self);
-}
-
-/**/
-
-typedef struct _FromEntry _FromEntry;
-struct _FromEntry {
-	spAnimation* animation;
-	_ToEntry* toEntries;
-	_FromEntry* next;
-};
-
-_FromEntry* _FromEntry_create (spAnimation* from) {
-	_FromEntry* self = NEW(_FromEntry);
-	self->animation = from;
-	return self;
-}
-
-void _FromEntry_dispose (_FromEntry* self) {
-	FREE(self);
-}
-
-/**/
-
-spAnimationStateData* spAnimationStateData_create (spSkeletonData* skeletonData) {
-	spAnimationStateData* self = NEW(spAnimationStateData);
-	CONST_CAST(spSkeletonData*, self->skeletonData) = skeletonData;
-	return self;
-}
-
-void spAnimationStateData_dispose (spAnimationStateData* self) {
-	_ToEntry* toEntry;
-	_ToEntry* nextToEntry;
-	_FromEntry* nextFromEntry;
-
-	_FromEntry* fromEntry = (_FromEntry*)self->entries;
-	while (fromEntry) {
-		toEntry = fromEntry->toEntries;
-		while (toEntry) {
-			nextToEntry = toEntry->next;
-			_ToEntry_dispose(toEntry);
-			toEntry = nextToEntry;
-		}
-		nextFromEntry = fromEntry->next;
-		_FromEntry_dispose(fromEntry);
-		fromEntry = nextFromEntry;
-	}
-
-	FREE(self);
-}
-
-void spAnimationStateData_setMixByName (spAnimationStateData* self, const char* fromName, const char* toName, float duration) {
-	spAnimation* to;
-	spAnimation* from = spSkeletonData_findAnimation(self->skeletonData, fromName);
-	if (!from) return;
-	to = spSkeletonData_findAnimation(self->skeletonData, toName);
-	if (!to) return;
-	spAnimationStateData_setMix(self, from, to, duration);
-}
-
-void spAnimationStateData_setMix (spAnimationStateData* self, spAnimation* from, spAnimation* to, float duration) {
-	/* Find existing FromEntry. */
-	_ToEntry* toEntry;
-	_FromEntry* fromEntry = (_FromEntry*)self->entries;
-	while (fromEntry) {
-		if (fromEntry->animation == from) {
-			/* Find existing ToEntry. */
-			toEntry = fromEntry->toEntries;
-			while (toEntry) {
-				if (toEntry->animation == to) {
-					toEntry->duration = duration;
-					return;
-				}
-				toEntry = toEntry->next;
-			}
-			break; /* Add new ToEntry to the existing FromEntry. */
-		}
-		fromEntry = fromEntry->next;
-	}
-	if (!fromEntry) {
-		fromEntry = _FromEntry_create(from);
-		fromEntry->next = (_FromEntry*)self->entries;
-		CONST_CAST(_FromEntry*, self->entries) = fromEntry;
-	}
-	toEntry = _ToEntry_create(to, duration);
-	toEntry->next = fromEntry->toEntries;
-	fromEntry->toEntries = toEntry;
-}
-
-float spAnimationStateData_getMix (spAnimationStateData* self, spAnimation* from, spAnimation* to) {
-	_FromEntry* fromEntry = (_FromEntry*)self->entries;
-	while (fromEntry) {
-		if (fromEntry->animation == from) {
-			_ToEntry* toEntry = fromEntry->toEntries;
-			while (toEntry) {
-				if (toEntry->animation == to) return toEntry->duration;
-				toEntry = toEntry->next;
-			}
-		}
-		fromEntry = fromEntry->next;
-	}
-	return self->defaultMix;
+#include <spine/AnimationStateData.h>
+#include <spine/extension.h>
+
+typedef struct _ToEntry _ToEntry;
+struct _ToEntry {
+	spAnimation* animation;
+	float duration;
+	_ToEntry* next;
+};
+
+_ToEntry* _ToEntry_create (spAnimation* to, float duration) {
+	_ToEntry* self = NEW(_ToEntry);
+	self->animation = to;
+	self->duration = duration;
+	return self;
+}
+
+void _ToEntry_dispose (_ToEntry* self) {
+	FREE(self);
+}
+
+/**/
+
+typedef struct _FromEntry _FromEntry;
+struct _FromEntry {
+	spAnimation* animation;
+	_ToEntry* toEntries;
+	_FromEntry* next;
+};
+
+_FromEntry* _FromEntry_create (spAnimation* from) {
+	_FromEntry* self = NEW(_FromEntry);
+	self->animation = from;
+	return self;
+}
+
+void _FromEntry_dispose (_FromEntry* self) {
+	FREE(self);
+}
+
+/**/
+
+spAnimationStateData* spAnimationStateData_create (spSkeletonData* skeletonData) {
+	spAnimationStateData* self = NEW(spAnimationStateData);
+	CONST_CAST(spSkeletonData*, self->skeletonData) = skeletonData;
+	return self;
+}
+
+void spAnimationStateData_dispose (spAnimationStateData* self) {
+	_ToEntry* toEntry;
+	_ToEntry* nextToEntry;
+	_FromEntry* nextFromEntry;
+
+	_FromEntry* fromEntry = (_FromEntry*)self->entries;
+	while (fromEntry) {
+		toEntry = fromEntry->toEntries;
+		while (toEntry) {
+			nextToEntry = toEntry->next;
+			_ToEntry_dispose(toEntry);
+			toEntry = nextToEntry;
+		}
+		nextFromEntry = fromEntry->next;
+		_FromEntry_dispose(fromEntry);
+		fromEntry = nextFromEntry;
+	}
+
+	FREE(self);
+}
+
+void spAnimationStateData_setMixByName (spAnimationStateData* self, const char* fromName, const char* toName, float duration) {
+	spAnimation* to;
+	spAnimation* from = spSkeletonData_findAnimation(self->skeletonData, fromName);
+	if (!from) return;
+	to = spSkeletonData_findAnimation(self->skeletonData, toName);
+	if (!to) return;
+	spAnimationStateData_setMix(self, from, to, duration);
+}
+
+void spAnimationStateData_setMix (spAnimationStateData* self, spAnimation* from, spAnimation* to, float duration) {
+	/* Find existing FromEntry. */
+	_ToEntry* toEntry;
+	_FromEntry* fromEntry = (_FromEntry*)self->entries;
+	while (fromEntry) {
+		if (fromEntry->animation == from) {
+			/* Find existing ToEntry. */
+			toEntry = fromEntry->toEntries;
+			while (toEntry) {
+				if (toEntry->animation == to) {
+					toEntry->duration = duration;
+					return;
+				}
+				toEntry = toEntry->next;
+			}
+			break; /* Add new ToEntry to the existing FromEntry. */
+		}
+		fromEntry = fromEntry->next;
+	}
+	if (!fromEntry) {
+		fromEntry = _FromEntry_create(from);
+		fromEntry->next = (_FromEntry*)self->entries;
+		CONST_CAST(_FromEntry*, self->entries) = fromEntry;
+	}
+	toEntry = _ToEntry_create(to, duration);
+	toEntry->next = fromEntry->toEntries;
+	fromEntry->toEntries = toEntry;
+}
+
+float spAnimationStateData_getMix (spAnimationStateData* self, spAnimation* from, spAnimation* to) {
+	_FromEntry* fromEntry = (_FromEntry*)self->entries;
+	while (fromEntry) {
+		if (fromEntry->animation == from) {
+			_ToEntry* toEntry = fromEntry->toEntries;
+			while (toEntry) {
+				if (toEntry->animation == to) return toEntry->duration;
+				toEntry = toEntry->next;
+			}
+		}
+		fromEntry = fromEntry->next;
+	}
+	return self->defaultMix;
 }

+ 350 - 351
spine-c/src/spine/Atlas.c

@@ -1,354 +1,353 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- * 
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- * 
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
- * translate, adapt or otherwise create derivative works, improvements of the
- * Software or develop new applications using the Software or (b) remove,
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- * 
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#include <spine/Atlas.h>
-#include <ctype.h>
-#include <spine/extension.h>
-
-spAtlasPage* spAtlasPage_create (spAtlas* atlas, const char* name) {
-	spAtlasPage* self = NEW(spAtlasPage);
-	CONST_CAST(spAtlas*, self->atlas) = atlas;
-	MALLOC_STR(self->name, name);
-	return self;
-}
-
-void spAtlasPage_dispose (spAtlasPage* self) {
-	_spAtlasPage_disposeTexture(self);
-	FREE(self->name);
-	FREE(self);
-}
-
-/**/
-
-spAtlasRegion* spAtlasRegion_create () {
-	return NEW(spAtlasRegion);
-}
-
-void spAtlasRegion_dispose (spAtlasRegion* self) {
-	FREE(self->name);
-	FREE(self->splits);
-	FREE(self->pads);
-	FREE(self);
-}
-
-/**/
-
-typedef struct {
-	const char* begin;
-	const char* end;
-} Str;
-
-static void trim (Str* str) {
-	while (isspace(*str->begin) && str->begin < str->end)
-		(str->begin)++;
-	if (str->begin == str->end) return;
-	str->end--;
-	while (isspace(*str->end) && str->end >= str->begin)
-		str->end--;
-	str->end++;
-}
-
-/* Tokenize string without modification. Returns 0 on failure. */
-static int readLine (const char** begin, const char* end, Str* str) {
-	if (*begin == end) return 0;
-	str->begin = *begin;
-
-	/* Find next delimiter. */
-	while (*begin != end && **begin != '\n')
-		(*begin)++;
-
-	str->end = *begin;
-	trim(str);
-
-	if (*begin != end) (*begin)++;
-	return 1;
-}
-
-/* Moves str->begin past the first occurence of c. Returns 0 on failure. */
-static int beginPast (Str* str, char c) {
-	const char* begin = str->begin;
-	while (1) {
-		char lastSkippedChar = *begin;
-		if (begin == str->end) return 0;
-		begin++;
-		if (lastSkippedChar == c) break;
-	}
-	str->begin = begin;
-	return 1;
-}
-
-/* Returns 0 on failure. */
-static int readValue (const char** begin, const char* end, Str* str) {
-	readLine(begin, end, str);
-	if (!beginPast(str, ':')) return 0;
-	trim(str);
-	return 1;
-}
-
-/* Returns the number of tuple values read (1, 2, 4, or 0 for failure). */
-static int readTuple (const char** begin, const char* end, Str tuple[]) {
-	int i;
-	Str str = {NULL, NULL};
-	readLine(begin, end, &str);
-	if (!beginPast(&str, ':')) return 0;
-
-	for (i = 0; i < 3; ++i) {
-		tuple[i].begin = str.begin;
-		if (!beginPast(&str, ',')) break;
-		tuple[i].end = str.begin - 2;
-		trim(&tuple[i]);
-	}
-	tuple[i].begin = str.begin;
-	tuple[i].end = str.end;
-	trim(&tuple[i]);
-	return i + 1;
-}
-
-static char* mallocString (Str* str) {
-	int length = (int)(str->end - str->begin);
-	char* string = MALLOC(char, length + 1);
-	memcpy(string, str->begin, length);
-	string[length] = '\0';
-	return string;
-}
-
-static int indexOf (const char** array, int count, Str* str) {
-	int length = (int)(str->end - str->begin);
-	int i;
-	for (i = count - 1; i >= 0; i--)
-		if (strncmp(array[i], str->begin, length) == 0) return i;
-	return 0;
-}
-
-static int equals (Str* str, const char* other) {
-	return strncmp(other, str->begin, str->end - str->begin) == 0;
-}
-
-static int toInt (Str* str) {
-	return (int)strtol(str->begin, (char**)&str->end, 10);
-}
-
-static spAtlas* abortAtlas (spAtlas* self) {
-	spAtlas_dispose(self);
-	return 0;
-}
-
-static const char* formatNames[] = {"", "Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888", "RGBA8888"};
-static const char* textureFilterNames[] = {"", "Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest",
-		"MipMapNearestLinear", "MipMapLinearLinear"};
-
-spAtlas* spAtlas_create (const char* begin, int length, const char* dir, void* rendererObject) {
-	spAtlas* self;
-
-	int count;
-	const char* end = begin + length;
-	int dirLength = (int)strlen(dir);
-	int needsSlash = dirLength > 0 && dir[dirLength - 1] != '/' && dir[dirLength - 1] != '\\';
-
-	spAtlasPage *page = 0;
-	spAtlasPage *lastPage = 0;
-	spAtlasRegion *lastRegion = 0;
-	Str str;
-	Str tuple[4];
-
-	self = NEW(spAtlas);
-	self->rendererObject = rendererObject;
-
-	while (readLine(&begin, end, &str)) {
-		if (str.end - str.begin == 0) {
-			page = 0;
-		} else if (!page) {
-			char* name = mallocString(&str);
-			char* path = MALLOC(char, dirLength + needsSlash + strlen(name) + 1);
-			memcpy(path, dir, dirLength);
-			if (needsSlash) path[dirLength] = '/';
-			strcpy(path + dirLength + needsSlash, name);
-
-			page = spAtlasPage_create(self, name);
-			FREE(name);
-			if (lastPage)
-				lastPage->next = page;
-			else
-				self->pages = page;
-			lastPage = page;
-
-			switch (readTuple(&begin, end, tuple)) {
-			case 0:
-				return abortAtlas(self);
-			case 2:  /* size is only optional for an atlas packed with an old TexturePacker. */
-				page->width = toInt(tuple);
-				page->height = toInt(tuple + 1);
-				if (!readTuple(&begin, end, tuple)) return abortAtlas(self);
-			}
-			page->format = (spAtlasFormat)indexOf(formatNames, 8, tuple);
-
-			if (!readTuple(&begin, end, tuple)) return abortAtlas(self);
-			page->minFilter = (spAtlasFilter)indexOf(textureFilterNames, 8, tuple);
-			page->magFilter = (spAtlasFilter)indexOf(textureFilterNames, 8, tuple + 1);
-
-			if (!readValue(&begin, end, &str)) return abortAtlas(self);
-
-			page->uWrap = SP_ATLAS_CLAMPTOEDGE;
-			page->vWrap = SP_ATLAS_CLAMPTOEDGE;
-			if (!equals(&str, "none")) {
-				if (str.end - str.begin == 1) {
-					if (*str.begin == 'x')
-						page->uWrap = SP_ATLAS_REPEAT;
-					else if (*str.begin == 'y')
-						page->vWrap = SP_ATLAS_REPEAT;
-				} else if (equals(&str, "xy")) {
-					page->uWrap = SP_ATLAS_REPEAT;
-					page->vWrap = SP_ATLAS_REPEAT;
-				}
-			}
-
-			_spAtlasPage_createTexture(page, path);
-			FREE(path);
-		} else {
-			spAtlasRegion *region = spAtlasRegion_create();
-			if (lastRegion)
-				lastRegion->next = region;
-			else
-				self->regions = region;
-			lastRegion = region;
-
-			region->page = page;
-			region->name = mallocString(&str);
-
-			if (!readValue(&begin, end, &str)) return abortAtlas(self);
-			region->rotate = equals(&str, "true");
-
-			if (readTuple(&begin, end, tuple) != 2) return abortAtlas(self);
-			region->x = toInt(tuple);
-			region->y = toInt(tuple + 1);
-
-			if (readTuple(&begin, end, tuple) != 2) return abortAtlas(self);
-			region->width = toInt(tuple);
-			region->height = toInt(tuple + 1);
-
-			region->u = region->x / (float)page->width;
-			region->v = region->y / (float)page->height;
-			if (region->rotate) {
-				region->u2 = (region->x + region->height) / (float)page->width;
-				region->v2 = (region->y + region->width) / (float)page->height;
-			} else {
-				region->u2 = (region->x + region->width) / (float)page->width;
-				region->v2 = (region->y + region->height) / (float)page->height;
-			}
-
-			if (!(count = readTuple(&begin, end, tuple))) return abortAtlas(self);
-			if (count == 4) { /* split is optional */
-				region->splits = MALLOC(int, 4);
-				region->splits[0] = toInt(tuple);
-				region->splits[1] = toInt(tuple + 1);
-				region->splits[2] = toInt(tuple + 2);
-				region->splits[3] = toInt(tuple + 3);
-
-				if (!(count = readTuple(&begin, end, tuple))) return abortAtlas(self);
-				if (count == 4) { /* pad is optional, but only present with splits */
-					region->pads = MALLOC(int, 4);
-					region->pads[0] = toInt(tuple);
-					region->pads[1] = toInt(tuple + 1);
-					region->pads[2] = toInt(tuple + 2);
-					region->pads[3] = toInt(tuple + 3);
-
-					if (!readTuple(&begin, end, tuple)) return abortAtlas(self);
-				}
-			}
-
-			region->originalWidth = toInt(tuple);
-			region->originalHeight = toInt(tuple + 1);
-
-			readTuple(&begin, end, tuple);
-			region->offsetX = toInt(tuple);
-			region->offsetY = toInt(tuple + 1);
-
-			if (!readValue(&begin, end, &str)) return abortAtlas(self);
-			region->index = toInt(&str);
-		}
-	}
-
-	return self;
-}
-
-spAtlas* spAtlas_createFromFile (const char* path, void* rendererObject) {
-	int dirLength;
-	char *dir;
-	int length;
-	const char* data;
-
-	spAtlas* atlas = 0;
-
-	/* Get directory from atlas path. */
-	const char* lastForwardSlash = strrchr(path, '/');
-	const char* lastBackwardSlash = strrchr(path, '\\');
-	const char* lastSlash = lastForwardSlash > lastBackwardSlash ? lastForwardSlash : lastBackwardSlash;
-	if (lastSlash == path) lastSlash++; /* Never drop starting slash. */
-	dirLength = (int)(lastSlash ? lastSlash - path : 0);
-	dir = MALLOC(char, dirLength + 1);
-	memcpy(dir, path, dirLength);
-	dir[dirLength] = '\0';
-
-	data = _spUtil_readFile(path, &length);
-	if (data) atlas = spAtlas_create(data, length, dir, rendererObject);
-
-	FREE(data);
-	FREE(dir);
-	return atlas;
-}
-
-void spAtlas_dispose (spAtlas* self) {
-	spAtlasRegion* region, *nextRegion;
-	spAtlasPage* page = self->pages;
-	while (page) {
-		spAtlasPage* nextPage = page->next;
-		spAtlasPage_dispose(page);
-		page = nextPage;
-	}
-
-	region = self->regions;
-	while (region) {
-		nextRegion = region->next;
-		spAtlasRegion_dispose(region);
-		region = nextRegion;
-	}
-
-	FREE(self);
-}
-
-spAtlasRegion* spAtlas_findRegion (const spAtlas* self, const char* name) {
-	spAtlasRegion* region = self->regions;
-	while (region) {
-		if (strcmp(region->name, name) == 0) return region;
-		region = region->next;
-	}
-	return 0;
+#include <spine/Atlas.h>
+#include <ctype.h>
+#include <spine/extension.h>
+
+spAtlasPage* spAtlasPage_create (spAtlas* atlas, const char* name) {
+	spAtlasPage* self = NEW(spAtlasPage);
+	CONST_CAST(spAtlas*, self->atlas) = atlas;
+	MALLOC_STR(self->name, name);
+	return self;
+}
+
+void spAtlasPage_dispose (spAtlasPage* self) {
+	_spAtlasPage_disposeTexture(self);
+	FREE(self->name);
+	FREE(self);
+}
+
+/**/
+
+spAtlasRegion* spAtlasRegion_create () {
+	return NEW(spAtlasRegion);
+}
+
+void spAtlasRegion_dispose (spAtlasRegion* self) {
+	FREE(self->name);
+	FREE(self->splits);
+	FREE(self->pads);
+	FREE(self);
+}
+
+/**/
+
+typedef struct {
+	const char* begin;
+	const char* end;
+} Str;
+
+static void trim (Str* str) {
+	while (isspace(*str->begin) && str->begin < str->end)
+		(str->begin)++;
+	if (str->begin == str->end) return;
+	str->end--;
+	while (isspace(*str->end) && str->end >= str->begin)
+		str->end--;
+	str->end++;
+}
+
+/* Tokenize string without modification. Returns 0 on failure. */
+static int readLine (const char** begin, const char* end, Str* str) {
+	if (*begin == end) return 0;
+	str->begin = *begin;
+
+	/* Find next delimiter. */
+	while (*begin != end && **begin != '\n')
+		(*begin)++;
+
+	str->end = *begin;
+	trim(str);
+
+	if (*begin != end) (*begin)++;
+	return 1;
+}
+
+/* Moves str->begin past the first occurence of c. Returns 0 on failure. */
+static int beginPast (Str* str, char c) {
+	const char* begin = str->begin;
+	while (1) {
+		char lastSkippedChar = *begin;
+		if (begin == str->end) return 0;
+		begin++;
+		if (lastSkippedChar == c) break;
+	}
+	str->begin = begin;
+	return 1;
+}
+
+/* Returns 0 on failure. */
+static int readValue (const char** begin, const char* end, Str* str) {
+	readLine(begin, end, str);
+	if (!beginPast(str, ':')) return 0;
+	trim(str);
+	return 1;
+}
+
+/* Returns the number of tuple values read (1, 2, 4, or 0 for failure). */
+static int readTuple (const char** begin, const char* end, Str tuple[]) {
+	int i;
+	Str str = {NULL, NULL};
+	readLine(begin, end, &str);
+	if (!beginPast(&str, ':')) return 0;
+
+	for (i = 0; i < 3; ++i) {
+		tuple[i].begin = str.begin;
+		if (!beginPast(&str, ',')) break;
+		tuple[i].end = str.begin - 2;
+		trim(&tuple[i]);
+	}
+	tuple[i].begin = str.begin;
+	tuple[i].end = str.end;
+	trim(&tuple[i]);
+	return i + 1;
+}
+
+static char* mallocString (Str* str) {
+	int length = (int)(str->end - str->begin);
+	char* string = MALLOC(char, length + 1);
+	memcpy(string, str->begin, length);
+	string[length] = '\0';
+	return string;
+}
+
+static int indexOf (const char** array, int count, Str* str) {
+	int length = (int)(str->end - str->begin);
+	int i;
+	for (i = count - 1; i >= 0; i--)
+		if (strncmp(array[i], str->begin, length) == 0) return i;
+	return 0;
+}
+
+static int equals (Str* str, const char* other) {
+	return strncmp(other, str->begin, str->end - str->begin) == 0;
+}
+
+static int toInt (Str* str) {
+	return (int)strtol(str->begin, (char**)&str->end, 10);
+}
+
+static spAtlas* abortAtlas (spAtlas* self) {
+	spAtlas_dispose(self);
+	return 0;
+}
+
+static const char* formatNames[] = {"", "Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888", "RGBA8888"};
+static const char* textureFilterNames[] = {"", "Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest",
+		"MipMapNearestLinear", "MipMapLinearLinear"};
+
+spAtlas* spAtlas_create (const char* begin, int length, const char* dir, void* rendererObject) {
+	spAtlas* self;
+
+	int count;
+	const char* end = begin + length;
+	int dirLength = (int)strlen(dir);
+	int needsSlash = dirLength > 0 && dir[dirLength - 1] != '/' && dir[dirLength - 1] != '\\';
+
+	spAtlasPage *page = 0;
+	spAtlasPage *lastPage = 0;
+	spAtlasRegion *lastRegion = 0;
+	Str str;
+	Str tuple[4];
+
+	self = NEW(spAtlas);
+	self->rendererObject = rendererObject;
+
+	while (readLine(&begin, end, &str)) {
+		if (str.end - str.begin == 0) {
+			page = 0;
+		} else if (!page) {
+			char* name = mallocString(&str);
+			char* path = MALLOC(char, dirLength + needsSlash + strlen(name) + 1);
+			memcpy(path, dir, dirLength);
+			if (needsSlash) path[dirLength] = '/';
+			strcpy(path + dirLength + needsSlash, name);
+
+			page = spAtlasPage_create(self, name);
+			FREE(name);
+			if (lastPage)
+				lastPage->next = page;
+			else
+				self->pages = page;
+			lastPage = page;
+
+			switch (readTuple(&begin, end, tuple)) {
+			case 0:
+				return abortAtlas(self);
+			case 2:  /* size is only optional for an atlas packed with an old TexturePacker. */
+				page->width = toInt(tuple);
+				page->height = toInt(tuple + 1);
+				if (!readTuple(&begin, end, tuple)) return abortAtlas(self);
+			}
+			page->format = (spAtlasFormat)indexOf(formatNames, 8, tuple);
+
+			if (!readTuple(&begin, end, tuple)) return abortAtlas(self);
+			page->minFilter = (spAtlasFilter)indexOf(textureFilterNames, 8, tuple);
+			page->magFilter = (spAtlasFilter)indexOf(textureFilterNames, 8, tuple + 1);
+
+			if (!readValue(&begin, end, &str)) return abortAtlas(self);
+
+			page->uWrap = SP_ATLAS_CLAMPTOEDGE;
+			page->vWrap = SP_ATLAS_CLAMPTOEDGE;
+			if (!equals(&str, "none")) {
+				if (str.end - str.begin == 1) {
+					if (*str.begin == 'x')
+						page->uWrap = SP_ATLAS_REPEAT;
+					else if (*str.begin == 'y')
+						page->vWrap = SP_ATLAS_REPEAT;
+				} else if (equals(&str, "xy")) {
+					page->uWrap = SP_ATLAS_REPEAT;
+					page->vWrap = SP_ATLAS_REPEAT;
+				}
+			}
+
+			_spAtlasPage_createTexture(page, path);
+			FREE(path);
+		} else {
+			spAtlasRegion *region = spAtlasRegion_create();
+			if (lastRegion)
+				lastRegion->next = region;
+			else
+				self->regions = region;
+			lastRegion = region;
+
+			region->page = page;
+			region->name = mallocString(&str);
+
+			if (!readValue(&begin, end, &str)) return abortAtlas(self);
+			region->rotate = equals(&str, "true");
+
+			if (readTuple(&begin, end, tuple) != 2) return abortAtlas(self);
+			region->x = toInt(tuple);
+			region->y = toInt(tuple + 1);
+
+			if (readTuple(&begin, end, tuple) != 2) return abortAtlas(self);
+			region->width = toInt(tuple);
+			region->height = toInt(tuple + 1);
+
+			region->u = region->x / (float)page->width;
+			region->v = region->y / (float)page->height;
+			if (region->rotate) {
+				region->u2 = (region->x + region->height) / (float)page->width;
+				region->v2 = (region->y + region->width) / (float)page->height;
+			} else {
+				region->u2 = (region->x + region->width) / (float)page->width;
+				region->v2 = (region->y + region->height) / (float)page->height;
+			}
+
+			if (!(count = readTuple(&begin, end, tuple))) return abortAtlas(self);
+			if (count == 4) { /* split is optional */
+				region->splits = MALLOC(int, 4);
+				region->splits[0] = toInt(tuple);
+				region->splits[1] = toInt(tuple + 1);
+				region->splits[2] = toInt(tuple + 2);
+				region->splits[3] = toInt(tuple + 3);
+
+				if (!(count = readTuple(&begin, end, tuple))) return abortAtlas(self);
+				if (count == 4) { /* pad is optional, but only present with splits */
+					region->pads = MALLOC(int, 4);
+					region->pads[0] = toInt(tuple);
+					region->pads[1] = toInt(tuple + 1);
+					region->pads[2] = toInt(tuple + 2);
+					region->pads[3] = toInt(tuple + 3);
+
+					if (!readTuple(&begin, end, tuple)) return abortAtlas(self);
+				}
+			}
+
+			region->originalWidth = toInt(tuple);
+			region->originalHeight = toInt(tuple + 1);
+
+			readTuple(&begin, end, tuple);
+			region->offsetX = toInt(tuple);
+			region->offsetY = toInt(tuple + 1);
+
+			if (!readValue(&begin, end, &str)) return abortAtlas(self);
+			region->index = toInt(&str);
+		}
+	}
+
+	return self;
+}
+
+spAtlas* spAtlas_createFromFile (const char* path, void* rendererObject) {
+	int dirLength;
+	char *dir;
+	int length;
+	const char* data;
+
+	spAtlas* atlas = 0;
+
+	/* Get directory from atlas path. */
+	const char* lastForwardSlash = strrchr(path, '/');
+	const char* lastBackwardSlash = strrchr(path, '\\');
+	const char* lastSlash = lastForwardSlash > lastBackwardSlash ? lastForwardSlash : lastBackwardSlash;
+	if (lastSlash == path) lastSlash++; /* Never drop starting slash. */
+	dirLength = (int)(lastSlash ? lastSlash - path : 0);
+	dir = MALLOC(char, dirLength + 1);
+	memcpy(dir, path, dirLength);
+	dir[dirLength] = '\0';
+
+	data = _spUtil_readFile(path, &length);
+	if (data) atlas = spAtlas_create(data, length, dir, rendererObject);
+
+	FREE(data);
+	FREE(dir);
+	return atlas;
+}
+
+void spAtlas_dispose (spAtlas* self) {
+	spAtlasRegion* region, *nextRegion;
+	spAtlasPage* page = self->pages;
+	while (page) {
+		spAtlasPage* nextPage = page->next;
+		spAtlasPage_dispose(page);
+		page = nextPage;
+	}
+
+	region = self->regions;
+	while (region) {
+		nextRegion = region->next;
+		spAtlasRegion_dispose(region);
+		region = nextRegion;
+	}
+
+	FREE(self);
+}
+
+spAtlasRegion* spAtlas_findRegion (const spAtlas* self, const char* name) {
+	spAtlasRegion* region = self->regions;
+	while (region) {
+		if (strcmp(region->name, name) == 0) return region;
+		region = region->next;
+	}
+	return 0;
 }

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно