Browse Source

[c] More 4.2 porting, remove incorrect/unnecessary const qualifiers

Mario Zechner 1 year ago
parent
commit
430758eb9b
30 changed files with 679 additions and 133 deletions
  1. 4 4
      spine-c/spine-c/include/spine/Animation.h
  2. 2 2
      spine-c/spine-c/include/spine/Atlas.h
  3. 1 1
      spine-c/spine-c/include/spine/Attachment.h
  4. 2 2
      spine-c/spine-c/include/spine/AttachmentLoader.h
  5. 1 1
      spine-c/spine-c/include/spine/BoneData.h
  6. 1 13
      spine-c/spine-c/include/spine/Event.h
  7. 3 3
      spine-c/spine-c/include/spine/EventData.h
  8. 1 1
      spine-c/spine-c/include/spine/IkConstraintData.h
  9. 1 1
      spine-c/spine-c/include/spine/MeshAttachment.h
  10. 1 1
      spine-c/spine-c/include/spine/PathConstraintData.h
  11. 97 0
      spine-c/spine-c/include/spine/PhysicsConstraint.h
  12. 58 0
      spine-c/spine-c/include/spine/PhysicsConstraintData.h
  13. 1 1
      spine-c/spine-c/include/spine/RegionAttachment.h
  14. 7 0
      spine-c/spine-c/include/spine/Skeleton.h
  15. 1 1
      spine-c/spine-c/include/spine/SkeletonBinary.h
  16. 9 2
      spine-c/spine-c/include/spine/SkeletonData.h
  17. 1 1
      spine-c/spine-c/include/spine/SkeletonJson.h
  18. 3 2
      spine-c/spine-c/include/spine/Skin.h
  19. 4 3
      spine-c/spine-c/include/spine/SlotData.h
  20. 1 1
      spine-c/spine-c/include/spine/TransformConstraintData.h
  21. 4 0
      spine-c/spine-c/include/spine/extension.h
  22. 1 1
      spine-c/spine-c/src/spine/Animation.c
  23. 97 82
      spine-c/spine-c/src/spine/Bone.c
  24. 278 0
      spine-c/spine-c/src/spine/PhysicsConstraint.c
  25. 64 0
      spine-c/spine-c/src/spine/PhysicsConstraintData.c
  26. 15 2
      spine-c/spine-c/src/spine/Skeleton.c
  27. 6 6
      spine-c/spine-c/src/spine/SkeletonBinary.c
  28. 11 0
      spine-c/spine-c/src/spine/SkeletonData.c
  29. 3 2
      spine-c/spine-c/src/spine/Skin.c
  30. 1 0
      spine-c/spine-c/src/spine/SlotData.c

+ 4 - 4
spine-c/spine-c/include/spine/Animation.h

@@ -51,7 +51,7 @@ _SP_ARRAY_DECLARE_TYPE(spPropertyIdArray, spPropertyId)
 _SP_ARRAY_DECLARE_TYPE(spTimelineArray, spTimeline*)
 
 typedef struct spAnimation {
-	const char *name;
+	char *name;
 	float duration;
 
 	spTimelineArray *timelines;
@@ -375,7 +375,7 @@ spRGB2Timeline_setFrame(spRGB2Timeline *self, int frameIndex, float time, float
 typedef struct spAttachmentTimeline {
 	spTimeline super;
 	int slotIndex;
-	const char **attachmentNames;
+	char **attachmentNames;
 } spAttachmentTimeline;
 
 SP_API spAttachmentTimeline *spAttachmentTimeline_create(int framesCount, int SlotIndex);
@@ -389,7 +389,7 @@ spAttachmentTimeline_setFrame(spAttachmentTimeline *self, int frameIndex, float
 typedef struct spDeformTimeline {
 	spCurveTimeline super;
 	int frameVerticesCount;
-	const float **frameVertices;
+	float **frameVertices;
 	int slotIndex;
 	spAttachment *attachment;
 } spDeformTimeline;
@@ -429,7 +429,7 @@ SP_API void spEventTimeline_setFrame(spEventTimeline *self, int frameIndex, spEv
 
 typedef struct spDrawOrderTimeline {
 	spTimeline super;
-	const int **drawOrders;
+	int **drawOrders;
 	int slotsCount;
 } spDrawOrderTimeline;
 

+ 2 - 2
spine-c/spine-c/include/spine/Atlas.h

@@ -70,8 +70,8 @@ typedef enum {
 
 typedef struct spAtlasPage spAtlasPage;
 struct spAtlasPage {
-	const spAtlas *atlas;
-	const char *name;
+	spAtlas *atlas;
+	char *name;
 	spAtlasFormat format;
 	spAtlasFilter minFilter, magFilter;
 	spAtlasWrap uWrap, vWrap;

+ 1 - 1
spine-c/spine-c/include/spine/Attachment.h

@@ -49,7 +49,7 @@ typedef enum {
 } spAttachmentType;
 
 typedef struct spAttachment {
-	const char *name;
+	char *name;
 	spAttachmentType type;
 	const void *vtable;
 	int refCount;

+ 2 - 2
spine-c/spine-c/include/spine/AttachmentLoader.h

@@ -40,8 +40,8 @@ extern "C" {
 #endif
 
 typedef struct spAttachmentLoader {
-	const char *error1;
-	const char *error2;
+	char *error1;
+	char *error2;
 
 	const void *vtable;
 } spAttachmentLoader;

+ 1 - 1
spine-c/spine-c/include/spine/BoneData.h

@@ -48,7 +48,7 @@ typedef enum {
 typedef struct spBoneData spBoneData;
 struct spBoneData {
 	int index;
-	const char *name;
+	char *name;
 	spBoneData *parent;
 	float length;
 	float x, y, rotation, scaleX, scaleY, shearX, shearY;

+ 1 - 13
spine-c/spine-c/include/spine/Event.h

@@ -42,21 +42,9 @@ typedef struct spEvent {
 	float time;
 	int intValue;
 	float floatValue;
-	const char *stringValue;
+	char *stringValue;
 	float volume;
 	float balance;
-
-#ifdef __cplusplus
-	spEvent() :
-		data(0),
-		time(0),
-		intValue(0),
-		floatValue(0),
-		stringValue(0),
-		volume(0),
-		balance(0) {
-	}
-#endif
 } spEvent;
 
 SP_API spEvent *spEvent_create(float time, spEventData *data);

+ 3 - 3
spine-c/spine-c/include/spine/EventData.h

@@ -37,11 +37,11 @@ extern "C" {
 #endif
 
 typedef struct spEventData {
-	const char *name;
+	char *name;
 	int intValue;
 	float floatValue;
-	const char *stringValue;
-	const char *audioPath;
+	char *stringValue;
+	char *audioPath;
 	float volume;
 	float balance;
 } spEventData;

+ 1 - 1
spine-c/spine-c/include/spine/IkConstraintData.h

@@ -38,7 +38,7 @@ extern "C" {
 #endif
 
 typedef struct spIkConstraintData {
-	const char *name;
+	char *name;
 	int order;
 	int /*boolean*/ skinRequired;
 	int bonesCount;

+ 1 - 1
spine-c/spine-c/include/spine/MeshAttachment.h

@@ -49,7 +49,7 @@ struct spMeshAttachment {
 	spTextureRegion *region;
 	spSequence *sequence;
 
-	const char *path;
+	char *path;
 
 	float *regionUVs;
 	float *uvs;

+ 1 - 1
spine-c/spine-c/include/spine/PathConstraintData.h

@@ -51,7 +51,7 @@ typedef enum {
 } spRotateMode;
 
 typedef struct spPathConstraintData {
-	const char *name;
+	char *name;
 	int order;
 	int/*bool*/ skinRequired;
 	int bonesCount;

+ 97 - 0
spine-c/spine-c/include/spine/PhysicsConstraint.h

@@ -0,0 +1,97 @@
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated July 28, 2023. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2023, Esoteric Software LLC
+ *
+ * Integration of the Spine Runtimes into software or otherwise creating
+ * derivative works of the Spine Runtimes is permitted under the terms and
+ * conditions of Section 2 of the Spine Editor License Agreement:
+ * http://esotericsoftware.com/spine-editor-license
+ *
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software or
+ * otherwise create derivative works of the Spine Runtimes (collectively,
+ * "Products"), provided that each user of the Products must obtain their own
+ * Spine Editor license and redistribution of the Products in any form must
+ * include this license and copyright notice.
+ *
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE
+ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef SPINE_PHYSICSCONSTRAINT_H_
+#define SPINE_PHYSICSCONSTRAINT_H_
+
+#include <spine/dll.h>
+#include <spine/PhysicsConstraintData.h>
+#include <spine/Bone.h>
+#include <spine/Physics.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spPhysicsConstraint {
+    spPhysicsConstraintData *data;
+    spBone* bone;
+
+    float inertia;
+    float strength;
+    float damping;
+    float massInverse;
+    float wind;
+    float gravity;
+    float mix;
+
+    int/*bool*/ reset;
+    float ux;
+    float uy;
+    float cx;
+    float cy;
+    float tx;
+    float ty;
+    float xOffset;
+    float xVelocity;
+    float yOffset;
+    float yVelocity;
+    float rotateOffset;
+    float rotateVelocity;
+    float scaleOffset;
+    float scaleVelocity;
+
+    int/*bool*/ active;
+
+    struct spSkeleton *skeleton;
+    float remaining;
+    float lastTime;
+
+} spPhysicsConstraint;
+
+SP_API spPhysicsConstraint *
+spPhysicsConstraint_create(spPhysicsConstraintData *data, struct spSkeleton *skeleton);
+
+SP_API void spPhysicsConstraint_dispose(spPhysicsConstraint *self);
+
+SP_API void spPhysicsConstraint_reset(spPhysicsConstraint *self);
+
+SP_API void spPhysicsConstraint_setToSetupPose(spPhysicsConstraint *self);
+
+SP_API void spPhysicsConstraint_update(spPhysicsConstraint *self, spPhysics physics);
+
+SP_API void spPhysicsConstraint_rotate(spPhysicsConstraint *self, float x, float y, float degrees);
+
+SP_API void spPhysicsConstraint_translate(spPhysicsConstraint *self, float x, float y);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SPINE_PHYSICSCONSTRAINT_H_ */

+ 58 - 0
spine-c/spine-c/include/spine/PhysicsConstraintData.h

@@ -0,0 +1,58 @@
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated July 28, 2023. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2023, Esoteric Software LLC
+ *
+ * Integration of the Spine Runtimes into software or otherwise creating
+ * derivative works of the Spine Runtimes is permitted under the terms and
+ * conditions of Section 2 of the Spine Editor License Agreement:
+ * http://esotericsoftware.com/spine-editor-license
+ *
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software or
+ * otherwise create derivative works of the Spine Runtimes (collectively,
+ * "Products"), provided that each user of the Products must obtain their own
+ * Spine Editor license and redistribution of the Products in any form must
+ * include this license and copyright notice.
+ *
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE
+ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef SPINE_PHYSICSCONSTRAINTDATA_H_
+#define SPINE_PHYSICSCONSTRAINTDATA_H_
+
+#include <spine/dll.h>
+#include <spine/BoneData.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct spPhysicsConstraintData {
+	char *name;
+	int order;
+	int/*bool*/ skinRequired;
+    spBoneData *bone;
+    float x, y, rotate, scaleX, shearX, limit;
+    float step, inertia, strength, damping, massInverse, wind, gravity, mix;
+    int/*bool*/ inertiaGlobal, strengthGlobal, dampingGlobal, massGlobal, windGlobal, gravityGlobal, mixGlobal;
+} spPhysicsConstraintData;
+
+SP_API spPhysicsConstraintData *spPhysicsConstraintData_create(const char *name);
+
+SP_API void spPhysicsConstraintData_dispose(spPhysicsConstraintData *self);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SPINE_PHYSICSCONSTRAINTDATA_H_ */

+ 1 - 1
spine-c/spine-c/include/spine/RegionAttachment.h

@@ -42,7 +42,7 @@ extern "C" {
 
 typedef struct spRegionAttachment {
 	spAttachment super;
-	const char *path;
+	char *path;
 	float x, y, scaleX, scaleY, rotation, width, height;
 	spColor color;
 

+ 7 - 0
spine-c/spine-c/include/spine/Skeleton.h

@@ -37,6 +37,7 @@
 #include <spine/IkConstraint.h>
 #include <spine/TransformConstraint.h>
 #include <spine/PathConstraint.h>
+#include <spine/PhysicsConstraint.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -62,6 +63,9 @@ typedef struct spSkeleton {
 	int pathConstraintsCount;
 	spPathConstraint **pathConstraints;
 
+    int physicsConstraintsCount;
+    spPhysicsConstraint **physicsConstraints;
+
 	spSkin *skin;
 	spColor color;
 	float scaleX, scaleY;
@@ -123,6 +127,9 @@ SP_API spTransformConstraint *spSkeleton_findTransformConstraint(const spSkeleto
 /* Returns 0 if the path constraint was not found. */
 SP_API spPathConstraint *spSkeleton_findPathConstraint(const spSkeleton *self, const char *constraintName);
 
+/* Returns 0 if the physics constraint was not found. */
+SP_API spPhysicsConstraint *spSkeleton_findPhysicsConstraint(const spSkeleton *self, const char *constraintName);
+
 #ifdef __cplusplus
 }
 #endif

+ 1 - 1
spine-c/spine-c/include/spine/SkeletonBinary.h

@@ -45,7 +45,7 @@ struct spAtlasAttachmentLoader;
 typedef struct spSkeletonBinary {
 	float scale;
 	spAttachmentLoader *attachmentLoader;
-	const char *error;
+	char *error;
 } spSkeletonBinary;
 
 SP_API spSkeletonBinary *spSkeletonBinary_createWithLoader(spAttachmentLoader *attachmentLoader);

+ 9 - 2
spine-c/spine-c/include/spine/SkeletonData.h

@@ -39,15 +39,17 @@
 #include <spine/IkConstraintData.h>
 #include <spine/TransformConstraintData.h>
 #include <spine/PathConstraintData.h>
+#include <spine/PhysicsConstraintData.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 typedef struct spSkeletonData {
-	const char *version;
-	const char *hash;
+	char *version;
+	char *hash;
 	float x, y, width, height;
+    float referenceScale;
 	float fps;
 	const char *imagesPath;
 	const char *audioPath;
@@ -79,6 +81,9 @@ typedef struct spSkeletonData {
 
 	int pathConstraintsCount;
 	spPathConstraintData **pathConstraints;
+
+    int physicsConstraintsCount;
+    spPhysicsConstraintData **physicsConstraints;
 } spSkeletonData;
 
 SP_API spSkeletonData *spSkeletonData_create(void);
@@ -102,6 +107,8 @@ spSkeletonData_findTransformConstraint(const spSkeletonData *self, const char *c
 
 SP_API spPathConstraintData *spSkeletonData_findPathConstraint(const spSkeletonData *self, const char *constraintName);
 
+SP_API spPhysicsConstraintData *spSkeletonData_findPhysicsConstraint(const spSkeletonData *self, const char *constraintName);
+
 #ifdef __cplusplus
 }
 #endif

+ 1 - 1
spine-c/spine-c/include/spine/SkeletonJson.h

@@ -46,7 +46,7 @@ struct spAtlasAttachmentLoader;
 typedef struct spSkeletonJson {
 	float scale;
 	spAttachmentLoader *attachmentLoader;
-	const char *error;
+	char *error;
 } spSkeletonJson;
 
 SP_API spSkeletonJson *spSkeletonJson_createWithLoader(spAttachmentLoader *attachmentLoader);

+ 3 - 2
spine-c/spine-c/include/spine/Skin.h

@@ -55,12 +55,13 @@ _SP_ARRAY_DECLARE_TYPE(spTransformConstraintDataArray, spTransformConstraintData
 _SP_ARRAY_DECLARE_TYPE(spPathConstraintDataArray, spPathConstraintData*)
 
 typedef struct spSkin {
-	const char *name;
+	char *name;
 
 	spBoneDataArray *bones;
 	spIkConstraintDataArray *ikConstraints;
 	spTransformConstraintDataArray *transformConstraints;
 	spPathConstraintDataArray *pathConstraints;
+    spColor color;
 } spSkin;
 
 /* Private structs, needed by Skeleton */
@@ -68,7 +69,7 @@ typedef struct _Entry _Entry;
 typedef struct _Entry spSkinEntry;
 struct _Entry {
 	int slotIndex;
-	const char *name;
+	char *name;
 	spAttachment *attachment;
 	_Entry *next;
 };

+ 4 - 3
spine-c/spine-c/include/spine/SlotData.h

@@ -44,12 +44,13 @@ typedef enum {
 
 typedef struct spSlotData {
 	int index;
-	const char *name;
-	const spBoneData *boneData;
-	const char *attachmentName;
+	char *name;
+	spBoneData *boneData;
+	char *attachmentName;
 	spColor color;
 	spColor *darkColor;
 	spBlendMode blendMode;
+    int/*bool*/ visible;
 } spSlotData;
 
 SP_API spSlotData *spSlotData_create(const int index, const char *name, spBoneData *boneData);

+ 1 - 1
spine-c/spine-c/include/spine/TransformConstraintData.h

@@ -38,7 +38,7 @@ extern "C" {
 #endif
 
 typedef struct spTransformConstraintData {
-	const char *name;
+	char *name;
 	int order;
 	int/*bool*/ skinRequired;
 	int bonesCount;

+ 4 - 0
spine-c/spine-c/include/spine/extension.h

@@ -92,11 +92,13 @@
 
 #define PI 3.1415926535897932385f
 #define PI2 (PI * 2)
+#define INV_PI2 (1 / PI2)
 #define DEG_RAD (PI / 180)
 #define RAD_DEG (180 / PI)
 
 #define ABS(A) ((A) < 0? -(A): (A))
 #define SIGNUM(A) ((A) < 0? -1.0f: (A) > 0 ? 1.0f : 0.0f)
+#define CEIL(a) ((float)ceil(a))
 
 #ifdef __STDC_VERSION__
 #define FMOD(A,B) fmodf(A, B)
@@ -128,6 +130,8 @@
 #define MAX(x, y) ((x) > (y) ? (x) : (y))
 #endif
 
+#define ATAN2DEG(A, B)  ((float)ATAN2(A, B) * RAD_DEG)
+
 #define UNUSED(x) (void)(x)
 
 #include <stdlib.h>

+ 1 - 1
spine-c/spine-c/src/spine/Animation.c

@@ -1765,7 +1765,7 @@ void _spDeformTimeline_apply(
 	const float *nextVertices;
 	float *frames;
 	int framesCount;
-	const float **frameVertices;
+	float **frameVertices;
 	float *deformArray;
 	spDeformTimeline *self = (spDeformTimeline *) timeline;
 

+ 97 - 82
spine-c/spine-c/src/spine/Bone.c

@@ -70,11 +70,8 @@ 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 cosine, sine;
     float pa, pb, pc, pd;
 	spBone *parent = self->parent;
-	float sx = self->skeleton->scaleX;
-	float sy = self->skeleton->scaleY * (spBone_isYDown() ? -1 : 1);
 
 	self->ax = x;
 	self->ay = y;
@@ -85,13 +82,14 @@ void spBone_updateWorldTransformWith(spBone *self, float x, float y, float rotat
 	self->ashearY = shearY;
 
 	if (!parent) { /* Root bone. */
-		float rotationY = rotation + 90 + shearY;
-		self->a = COS_DEG(rotation + shearX) * scaleX * sx;
-		self->b = COS_DEG(rotationY) * scaleY * sx;
-		self->c = SIN_DEG(rotation + shearX) * scaleX * sy;
-		self->d = SIN_DEG(rotationY) * scaleY * sy;
-		self->worldX = x * sx + self->skeleton->x;
-		self->worldY = y * sy + self->skeleton->y;
+        float sx = self->skeleton->scaleX;
+        float sy = self->skeleton->scaleY;
+        float rx = (rotation + shearX) * DEG_RAD;
+        float ry = (rotation + 90 + shearY) * DEG_RAD;
+        self->a = COS(rx) * scaleX * sx;
+        self->b = COS(ry) * scaleY * sx;
+        self->c = SIN(rx) * scaleX * sy;
+        self->d = SIN(ry) * scaleY * sy;
 		return;
 	}
 
@@ -103,13 +101,14 @@ void spBone_updateWorldTransformWith(spBone *self, float x, float y, float rotat
 	self->worldX = pa * x + pb * y + parent->worldX;
 	self->worldY = pc * x + pd * y + parent->worldY;
 
-	switch (self->data->inherit) {
+	switch (self->inherit) {
 		case SP_INHERIT_NORMAL: {
-			float rotationY = rotation + 90 + shearY;
-			float la = COS_DEG(rotation + shearX) * scaleX;
-			float lb = COS_DEG(rotationY) * scaleY;
-			float lc = SIN_DEG(rotation + shearX) * scaleX;
-			float ld = SIN_DEG(rotationY) * scaleY;
+            float rx = (rotation + shearX) * DEG_RAD;
+            float ry = (rotation + 90 + shearY) * DEG_RAD;
+            float la = COS(rx) * scaleX;
+            float lb = COS(ry) * scaleY;
+            float lc = SIN(rx) * scaleX;
+            float ld = SIN(ry) * scaleY;
 			self->a = pa * la + pb * lc;
 			self->b = pa * lb + pb * ld;
 			self->c = pc * la + pd * lc;
@@ -117,34 +116,35 @@ void spBone_updateWorldTransformWith(spBone *self, float x, float y, float rotat
 			return;
 		}
 		case SP_INHERIT_ONLYTRANSLATION: {
-			float rotationY = rotation + 90 + shearY;
-			self->a = COS_DEG(rotation + shearX) * scaleX;
-			self->b = COS_DEG(rotationY) * scaleY;
-			self->c = SIN_DEG(rotation + shearX) * scaleX;
-			self->d = SIN_DEG(rotationY) * scaleY;
+            float rx = (rotation + shearX) * DEG_RAD;
+            float ry = (rotation + 90 + shearY) * DEG_RAD;
+            self->a = COS(rx) * scaleX;
+            self->b = COS(ry) * scaleY;
+            self->c = SIN(rx) * scaleX;
+            self->d = SIN(ry) * scaleY;
 			break;
 		}
 		case SP_INHERIT_NOROTATIONORREFLECTION: {
 			float s = pa * pa + pc * pc;
-			float prx, rx, ry, la, lb, lc, ld;
+			float prx;
 			if (s > 0.0001f) {
 				s = ABS(pa * pd - pb * pc) / s;
 				pa /= self->skeleton->scaleX;
 				pc /= self->skeleton->scaleY;
 				pb = pc * s;
 				pd = pa * s;
-				prx = ATAN2(pc, pa) * RAD_DEG;
+				prx = ATAN2DEG(pc, pa);
 			} else {
 				pa = 0;
 				pc = 0;
-				prx = 90 - ATAN2(pd, pb) * RAD_DEG;
+				prx = 90 - ATAN2DEG(pd, pb);
 			}
-			rx = rotation + shearX - prx;
-			ry = rotation + shearY - prx + 90;
-			la = COS_DEG(rx) * scaleX;
-			lb = COS_DEG(ry) * scaleY;
-			lc = SIN_DEG(rx) * scaleX;
-			ld = SIN_DEG(ry) * scaleY;
+            float rx = (rotation + shearX - prx) *DEG_RAD;
+            float ry = (rotation + shearY - prx + 90) *DEG_RAD;
+            float la = COS(rx) * scaleX;
+            float lb = COS(ry) * scaleY;
+            float lc = SIN(rx) * scaleX;
+            float ld = SIN(ry) * scaleY;
 			self->a = pa * la - pb * lc;
 			self->b = pa * lb - pb * ld;
 			self->c = pc * la + pd * lc;
@@ -153,26 +153,23 @@ void spBone_updateWorldTransformWith(spBone *self, float x, float y, float rotat
 		}
 		case SP_INHERIT_NOSCALE:
 		case SP_INHERIT_NOSCALEORREFLECTION: {
-			float za, zc, s;
-			float r, zb, zd, la, lb, lc, ld;
-			cosine = COS_DEG(rotation);
-			sine = SIN_DEG(rotation);
-			za = (pa * cosine + pb * sine) / sx;
-			zc = (pc * cosine + pd * sine) / sy;
-			s = SQRT(za * za + zc * zc);
-			if (s > 0.00001f) s = 1 / s;
-			za *= s;
-			zc *= s;
-			s = SQRT(za * za + zc * zc);
-			if (self->data->inherit == SP_INHERIT_NOSCALE && (pa * pd - pb * pc < 0) != (sx < 0 != sy < 0))
+            rotation *= DEG_RAD;
+            float cosine = COS(rotation);
+            float sine = SIN(rotation);
+            float za = (pa * cosine + pb * sine) / self->skeleton->scaleX;
+            float zc = (pc * cosine + pd * sine) / self->skeleton->scaleY;
+            float s = SQRT(za * za + zc * zc);
+			if (self->data->inherit == SP_INHERIT_NOSCALE && (pa * pd - pb * pc < 0) != (self->skeleton->scaleX < 0 != self->skeleton->scaleY < 0))
 				s = -s;
-			r = PI / 2 + ATAN2(zc, za);
-			zb = COS(r) * s;
-			zd = SIN(r) * s;
-			la = COS_DEG(shearX) * scaleX;
-			lb = COS_DEG(90 + shearY) * scaleY;
-			lc = SIN_DEG(shearX) * scaleX;
-			ld = SIN_DEG(90 + shearY) * scaleY;
+            rotation = PI / 2 + ATAN2(zc, za);
+            float zb = COS(rotation) * s;
+            float zd = SIN(rotation) * s;
+            shearX *= DEG_RAD;
+            shearY = (90 + shearY) * DEG_RAD;
+            float la = COS(shearX) * scaleX;
+            float lb = COS(shearY) * scaleY;
+            float lc = SIN(shearX) * scaleX;
+            float ld = SIN(shearY) * scaleY;
 			self->a = za * la + zb * lc;
 			self->b = za * lb + zb * ld;
 			self->c = zc * la + zd * lc;
@@ -180,10 +177,10 @@ void spBone_updateWorldTransformWith(spBone *self, float x, float y, float rotat
 		}
 	}
 
-	self->a *= sx;
-	self->b *= sx;
-	self->c *= sy;
-	self->d *= sy;
+	self->a *= self->skeleton->scaleX;
+	self->b *= self->skeleton->scaleX;
+	self->c *= self->skeleton->scaleY;
+	self->d *= self->skeleton->scaleY;
 }
 
 void spBone_setToSetupPose(spBone *self) {
@@ -194,14 +191,15 @@ void spBone_setToSetupPose(spBone *self) {
 	self->scaleY = self->data->scaleY;
 	self->shearX = self->data->shearX;
 	self->shearY = self->data->shearY;
+    self->inherit = self->data->inherit;
 }
 
 float spBone_getWorldRotationX(spBone *self) {
-	return ATAN2(self->c, self->a) * RAD_DEG;
+	return ATAN2DEG(self->c, self->a);
 }
 
 float spBone_getWorldRotationY(spBone *self) {
-	return ATAN2(self->d, self->b) * RAD_DEG;
+	return ATAN2DEG(self->d, self->b);
 }
 
 float spBone_getWorldScaleX(spBone *self) {
@@ -222,18 +220,18 @@ void spBone_updateAppliedTransform(spBone *self) {
 	float ia, ib, ic, id;
 	float dx, dy;
 	float ra, rb, rc, rd;
-	float s, r, sa, sc;
+	float s, sa, sc;
 	float cosine, sine;
 
 	spBone *parent = self->parent;
 	if (!parent) {
 		self->ax = self->worldX - self->skeleton->x;
 		self->ay = self->worldY - self->skeleton->y;
-		self->arotation = ATAN2(self->c, self->a) * RAD_DEG;
+		self->arotation = ATAN2DEG(self->c, self->a);
 		self->ascaleX = SQRT(self->a * self->a + self->c * self->c);
 		self->ascaleY = SQRT(self->b * self->b + self->d * self->d);
 		self->ashearX = 0;
-		self->ashearY = ATAN2(self->a * self->b + self->c * self->d, self->a * self->d - self->b * self->c) * RAD_DEG;
+		self->ashearY = ATAN2DEG(self->a * self->b + self->c * self->d, self->a * self->d - self->b * self->c);
 		return;
 	}
 
@@ -244,13 +242,13 @@ void spBone_updateAppliedTransform(spBone *self) {
 	self->ax = (dx * ia - dy * ib);
 	self->ay = (dy * id - dx * ic);
 
-	if (self->data->inherit == SP_INHERIT_ONLYTRANSLATION) {
+	if (self->inherit == SP_INHERIT_ONLYTRANSLATION) {
 		ra = self->a;
 		rb = self->b;
 		rc = self->c;
 		rd = self->d;
 	} else {
-		switch (self->data->inherit) {
+		switch (self->inherit) {
 			case SP_INHERIT_NOROTATIONORREFLECTION: {
 				s = ABS(pa * pd - pb * pc) / (pa * pa + pc * pc);
 				sa = pa / self->skeleton->scaleX;
@@ -264,15 +262,16 @@ void spBone_updateAppliedTransform(spBone *self) {
 			}
 			case SP_INHERIT_NOSCALE:
 			case SP_INHERIT_NOSCALEORREFLECTION: {
-				cosine = COS_DEG(self->rotation), sine = SIN_DEG(self->rotation);
+                float r = self->rotation * DEG_RAD;
+				cosine = COS(r), sine = SIN(r);
 				pa = (pa * cosine + pb * sine) / self->skeleton->scaleX;
 				pc = (pc * cosine + pd * sine) / self->skeleton->scaleY;
 				s = SQRT(pa * pa + pc * pc);
-				if (s > 0.00001f) s = 1 / s;
+				if (s > 0.00001) s = 1 / s;
 				pa *= s;
 				pc *= s;
 				s = SQRT(pa * pa + pc * pc);
-				if (self->data->inherit == SP_INHERIT_NOSCALE &&
+				if (self->inherit == SP_INHERIT_NOSCALE &&
 					pid < 0 != (self->skeleton->scaleX < 0 != self->skeleton->scaleY < 0))
 					s = -s;
 				r = PI / 2 + ATAN2(pc, pa);
@@ -300,13 +299,13 @@ void spBone_updateAppliedTransform(spBone *self) {
 	if (self->ascaleX > 0.0001f) {
 		float det = ra * rd - rb * rc;
 		self->ascaleY = det / self->ascaleX;
-		self->ashearY = -ATAN2(ra * rb + rc * rd, det) * RAD_DEG;
-		self->arotation = ATAN2(rc, ra) * RAD_DEG;
+		self->ashearY = -ATAN2DEG(ra * rb + rc * rd, det);
+		self->arotation = ATAN2DEG(rc, ra);
 	} else {
 		self->ascaleX = 0;
 		self->ascaleY = SQRT(rb * rb + rd * rd);
 		self->ashearY = 0;
-		self->arotation = 90 - ATAN2(rd, rb) * RAD_DEG;
+		self->arotation = 90 - ATAN2DEG(rd, rb);
 	}
 }
 
@@ -317,33 +316,49 @@ void spBone_worldToLocal(spBone *self, float worldX, float worldY, float *localX
 	*localY = (y * self->a * invDet - x * self->c * invDet);
 }
 
+void spBone_worldToParent(spBone *self, float worldX, float worldY, float *localX, float *localY) {
+    if (self->parent == NULL) {
+        *localX = worldX;
+        *localY = worldY;
+    } else {
+        spBone_worldToLocal(self->parent, worldX, worldY, localX, localY);
+    }
+}
+
 void spBone_localToWorld(spBone *self, float localX, float localY, float *worldX, float *worldY) {
 	float x = localX, y = localY;
 	*worldX = x * self->a + y * self->b + self->worldX;
 	*worldY = x * self->c + y * self->d + self->worldY;
 }
 
+void spBone_parentToWorld(spBone *self, float localX, float localY, float *worldX, float *worldY) {
+    if (self->parent != NULL) {
+        *worldX = localX;
+        *worldY = localY;
+    } else {
+        spBone_localToWorld(self->parent, localX, localY, worldX, worldY);
+    }
+}
+
 float spBone_worldToLocalRotation(spBone *self, float worldRotation) {
-	float sine, cosine;
-	sine = SIN_DEG(worldRotation);
-	cosine = COS_DEG(worldRotation);
-	return ATAN2(self->a * sine - self->c * cosine, self->d * cosine - self->b * sine) * RAD_DEG + self->rotation -
-		   self->shearX;
+    worldRotation *= DEG_RAD;
+    float sine = SIN(worldRotation), cosine = COS(worldRotation);
+    return ATAN2DEG(self->a * sine - self->c * cosine, self->d * cosine - self->b * sine) + self->rotation - self->shearX;
 }
 
 float spBone_localToWorldRotation(spBone *self, float localRotation) {
-	float sine, cosine;
-	localRotation -= self->rotation - self->shearX;
-	sine = SIN_DEG(localRotation);
-	cosine = COS_DEG(localRotation);
-	return ATAN2(cosine * self->c + sine * self->d, cosine * self->a + sine * self->b) * RAD_DEG;
+    localRotation = (localRotation - self->rotation - self->shearX) * DEG_RAD;
+    float sine = SIN(localRotation), cosine = COS(localRotation);
+    return ATAN2DEG(cosine * self->c + sine * self->d, cosine * self->a + sine * self->b);
+
 }
 
 void spBone_rotateWorld(spBone *self, float degrees) {
-	float a = self->a, b = self->b, c = self->c, d = self->d;
-	float cosine = COS_DEG(degrees), sine = SIN_DEG(degrees);
-	self->a = cosine * a - sine * c;
-	self->b = cosine * b - sine * d;
-	self->c = sine * a + cosine * c;
-	self->d = sine * b + cosine * d;
+    degrees *= DEG_RAD;
+    float sine = SIN(degrees), cosine = COS(degrees);
+    float ra = self->a, rb = self->b;
+    self->a = cosine * ra - sine * self->c;
+    self->b = cosine * rb - sine * self->d;
+    self->c = sine * ra + cosine * self->c;
+    self->d = sine * rb + cosine * self->d;
 }

+ 278 - 0
spine-c/spine-c/src/spine/PhysicsConstraint.c

@@ -0,0 +1,278 @@
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated July 28, 2023. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2023, Esoteric Software LLC
+ *
+ * Integration of the Spine Runtimes into software or otherwise creating
+ * derivative works of the Spine Runtimes is permitted under the terms and
+ * conditions of Section 2 of the Spine Editor License Agreement:
+ * http://esotericsoftware.com/spine-editor-license
+ *
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software or
+ * otherwise create derivative works of the Spine Runtimes (collectively,
+ * "Products"), provided that each user of the Products must obtain their own
+ * Spine Editor license and redistribution of the Products in any form must
+ * include this license and copyright notice.
+ *
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE
+ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#include <spine/Skeleton.h>
+#include <spine/PhysicsConstraint.h>
+#include <spine/extension.h>
+
+spPhysicsConstraint *spPhysicsConstraint_create(spPhysicsConstraintData *data, spSkeleton *skeleton) {
+    spPhysicsConstraint *self = NEW(spPhysicsConstraint);
+	self->data = data;
+    self->skeleton = skeleton;
+    self->bone = skeleton->bones[data->bone->index];
+    self->inertia = data->inertia;
+    self->strength = data->strength;
+    self->damping = data->damping;
+    self->massInverse = data->massInverse;
+    self->wind = data->wind;
+    self->gravity = data->gravity;
+    self->mix = data->mix;
+
+    self->reset = -1;
+    self->ux = 0;
+    self->uy = 0;
+    self->cx = 0;
+    self->tx = 0;
+    self->ty = 0;
+    self->xOffset = 0;
+    self->xVelocity = 0;
+    self->yOffset = 0;
+    self->yVelocity = 0;
+    self->rotateOffset = 0;
+    self->rotateVelocity = 0;
+    self->scaleOffset = 0;
+    self->scaleVelocity = 0;
+    self->active = 0;
+    self->remaining = 0;
+    self->lastTime = 0;
+	return self;
+}
+
+void spPhysicsConstraint_dispose(spPhysicsConstraint *self) {
+	FREE(self);
+}
+
+void spPhysicsConstraint_reset(spPhysicsConstraint *self) {
+    self->remaining = 0;
+    self->lastTime = self->skeleton->time;
+    self->reset = -1;
+    self->xOffset = 0;
+    self->xVelocity = 0;
+    self->yOffset = 0;
+    self->yVelocity = 0;
+    self->rotateOffset = 0;
+    self->rotateVelocity = 0;
+    self->scaleOffset = 0;
+    self->scaleVelocity = 0;
+}
+
+void spPhysicsConstraint_setToSetupPose(spPhysicsConstraint *self) {
+    self->inertia = self->data->inertia;
+    self->strength = self->data->strength;
+    self->damping = self->data->damping;
+    self->massInverse = self->data->massInverse;
+    self->wind = self->data->wind;
+    self->gravity = self->data->gravity;
+    self->mix = self->data->mix;
+}
+
+void spPhysicsConstraint_update(spPhysicsConstraint *self, spPhysics physics) {
+    float mix = self->mix;
+    if (mix == 0) return;
+
+    int x = self->data->x > 0;
+    int y = self->data->y > 0;
+    int rotateOrShearX = self->data->rotate > 0 || self->data->shearX > 0;
+    int scaleX = self->data->scaleX > 0;
+
+    spBone *bone = self->bone;
+    float l = bone->data->length;
+
+    switch (physics) {
+        case SP_PHYSICS_NONE:
+            return;
+        case SP_PHYSICS_RESET:
+            spPhysicsConstraint_reset(self);
+            // Fall through.
+        case SP_PHYSICS_UPDATE: {
+            float delta = MAX(self->skeleton->time - self->lastTime, 0.0f);
+            self->remaining += delta;
+            self->lastTime = self->skeleton->time;
+
+            float bx = bone->worldX, by = bone->worldY;
+            if (self->reset) {
+                self->reset = 0;
+                self->ux = bx;
+                self->uy = by;
+            } else {
+                float a = self->remaining, i = self->inertia, q = self->data->limit * delta, t = self->data->step, f = self->skeleton->data->referenceScale, d = -1;
+                if (x || y) {
+                    if (x) {
+                        float u = (self->ux - bx) * i;
+                        self->xOffset += u > q ? q : u < -q ? -q
+                                                       : u;
+                        self->ux = bx;
+                    }
+                    if (y) {
+                        float u = (self->uy - by) * i;
+                        self->yOffset += u > q ? q : u < -q ? -q
+                                                       : u;
+                        self->uy = by;
+                    }
+                    if (a >= t) {
+                        d = POW(self->damping, 60 * t);
+                        float m = self->massInverse * t, e = self->strength, w = self->wind * f, g = self->gravity * f * (spBone_isYDown() ? -1 : 1);
+                        do {
+                            if (x) {
+                                self->xVelocity += (w - self->xOffset * e) * m;
+                                self->xOffset += self->xVelocity * t;
+                                self->xVelocity *= d;
+                            }
+                            if (y) {
+                                self->yVelocity -= (g + self->yOffset * e) * m;
+                                self->yOffset += self->yVelocity * t;
+                                self->yVelocity *= d;
+                            }
+                            a -= t;
+                        } while (a >= t);
+                    }
+                    if (x) bone->worldX += self->xOffset * mix * self->data->x;
+                    if (y) bone->worldY += self->yOffset * mix * self->data->y;
+                }
+
+                if (rotateOrShearX || scaleX) {
+                    float ca = ATAN2(bone->c, bone->a), c, s, mr = 0;
+                    float dx = self->cx - bone->worldX, dy = self->cy - bone->worldY;
+                    if (dx > q)
+                        dx = q;
+                    else if (dx < -q)//
+                        dx = -q;
+                    if (dy > q)
+                        dy = q;
+                    else if (dy < -q)//
+                        dy = -q;
+                    if (rotateOrShearX) {
+                        mr = (self->data->rotate + self->data->shearX) * mix;
+                        float r = ATAN2(dy + self->ty, dx + self->tx) - ca - self->rotateOffset * mr;
+                        self->rotateOffset += (r - CEIL(r * INV_PI2 - 0.5f) * PI2) * i;
+                        r = self->rotateOffset * mr + ca;
+                        c = COS(r);
+                        s = SIN(r);
+                        if (scaleX) {
+                            r = l * spBone_getWorldScaleX(bone);
+                            if (r > 0) self->scaleOffset += (dx * c + dy * s) * i / r;
+                        }
+                    } else {
+                        c = COS(ca);
+                        s = SIN(ca);
+                        float r = l * spBone_getWorldScaleX(bone);
+                        if (r > 0) self->scaleOffset += (dx * c + dy * s) * i / r;
+                    }
+                    a = self->remaining;
+                    if (a >= t) {
+                        if (d == -1) d = POW(self->damping, 60 * t);
+                        float m = self->massInverse * t, e = self->strength, w = self->wind, g = self->gravity, h = l / f;
+                        while (-1) {
+                            a -= t;
+                            if (scaleX) {
+                                self->scaleVelocity += (w * c - g * s - self->scaleOffset * e) * m;
+                                self->scaleOffset += self->scaleVelocity * t;
+                                self->scaleVelocity *= d;
+                            }
+                            if (rotateOrShearX) {
+                                self->rotateVelocity -= ((w * s + g * c) * h + self->rotateOffset * e) * m;
+                                self->rotateOffset += self->rotateVelocity * t;
+                                self->rotateVelocity *= d;
+                                if (a < t) break;
+                                float r = self->rotateOffset * mr + ca;
+                                c = COS(r);
+                                s = SIN(r);
+                            } else if (a < t)//
+                                break;
+                        }
+                    }
+                }
+                self->remaining = a;
+            }
+
+            self->cx = bone->worldX;
+            self->cy = bone->worldY;
+            break;
+        }
+        case SP_PHYSICS_POSE: {
+            if (x) bone->worldX += self->xOffset * mix * self->data->x;
+            if (y) bone->worldY += self->yOffset * mix * self->data->y;
+            break;
+        }
+    }
+
+    if (rotateOrShearX) {
+        float o = self->rotateOffset * mix, s = 0, c = 0, a = 0;
+        if (self->data->shearX > 0) {
+            float r = 0;
+            if (self->data->rotate > 0) {
+                r = o * self->data->rotate;
+                s = SIN(r);
+                c = COS(r);
+                a = bone->b;
+                bone->b = c * a - s * bone->d;
+                bone->d = s * a + c * bone->d;
+            }
+            r += o * self->data->shearX;
+            s = SIN(r);
+            c = COS(r);
+            a = bone->a;
+            bone->a = c * a - s * bone->c;
+            bone->c = s * a + c * bone->c;
+        } else {
+            o *= self->data->rotate;
+            s = SIN(o);
+            c = COS(o);
+            a = bone->a;
+            bone->a = c * a - s * bone->c;
+            bone->c = s * a + c * bone->c;
+            a = bone->b;
+            bone->b = c * a - s * bone->d;
+            bone->d = s * a + c * bone->d;
+        }
+    }
+    if (scaleX) {
+        float s = 1 + self->scaleOffset * mix * self->data->scaleX;
+        bone->a *= s;
+        bone->c *= s;
+    }
+    if (physics != SP_PHYSICS_POSE) {
+        self->tx = l * bone->a;
+        self->ty = l * bone->c;
+    }
+    spBone_updateAppliedTransform(bone);
+}
+
+void spPhysicsConstraint_rotate(spPhysicsConstraint *self, float x, float y, float degrees) {
+    float r = degrees * DEG_RAD, cosine = COS(r), sine = SIN(r);
+    float dx = self->cx - x, dy = self->cy - y;
+    spPhysicsConstraint_translate(self, dx * cosine - dy * sine - dx, dx * sine + dy * cosine - dy);
+}
+
+void spPhysicsConstraint_translate(spPhysicsConstraint *self, float x, float y) {
+    self->ux -= x;
+    self->uy -= y;
+    self->cx -= x;
+    self->cy -= y;
+}

+ 64 - 0
spine-c/spine-c/src/spine/PhysicsConstraintData.c

@@ -0,0 +1,64 @@
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated July 28, 2023. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2023, Esoteric Software LLC
+ *
+ * Integration of the Spine Runtimes into software or otherwise creating
+ * derivative works of the Spine Runtimes is permitted under the terms and
+ * conditions of Section 2 of the Spine Editor License Agreement:
+ * http://esotericsoftware.com/spine-editor-license
+ *
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software or
+ * otherwise create derivative works of the Spine Runtimes (collectively,
+ * "Products"), provided that each user of the Products must obtain their own
+ * Spine Editor license and redistribution of the Products in any form must
+ * include this license and copyright notice.
+ *
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE
+ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#include <spine/PhysicsConstraintData.h>
+#include <spine/extension.h>
+
+spPhysicsConstraintData *spPhysicsConstraintData_create(const char *name) {
+    spPhysicsConstraintData *self = NEW(spPhysicsConstraintData);
+	MALLOC_STR(self->name, name);
+    self->bone = NULL;
+    self->x = 0;
+    self->y = 0;
+    self->rotate = 0;
+    self->scaleX = 0;
+    self->shearX = 0;
+    self->limit = 0;
+    self->step = 0;
+    self->inertia = 0;
+    self->strength = 0;
+    self->damping = 0;
+    self->massInverse = 0;
+    self->wind = 0;
+    self->gravity = 0;
+    self->mix = 0;
+    self->inertiaGlobal = 0;
+    self->strengthGlobal = 0;
+    self->dampingGlobal = 0;
+    self->massGlobal = 0;
+    self->windGlobal = 0;
+    self->gravityGlobal = 0;
+    self->mixGlobal = 0;
+	return self;
+}
+
+void spPhysicsConstraintData_dispose(spPhysicsConstraintData *self) {
+	FREE(self->name);
+	FREE(self);
+}

+ 15 - 2
spine-c/spine-c/src/spine/Skeleton.c

@@ -36,7 +36,8 @@ typedef enum {
 	SP_UPDATE_BONE,
 	SP_UPDATE_IK_CONSTRAINT,
 	SP_UPDATE_PATH_CONSTRAINT,
-	SP_UPDATE_TRANSFORM_CONSTRAINT
+	SP_UPDATE_TRANSFORM_CONSTRAINT,
+	SP_UPDATE_PHYSICS_CONSTRAINT
 } _spUpdateType;
 
 typedef struct {
@@ -431,6 +432,8 @@ void spSkeleton_updateWorldTransform(const spSkeleton *self, spPhysics physics)
 			case SP_UPDATE_PATH_CONSTRAINT:
 				spPathConstraint_update((spPathConstraint *) update->object);
 				break;
+			case SP_UPDATE_PHYSICS_CONSTRAINT:
+				spPhysicsConstraint_update((spPhysicsConstraint *) update->object, physics);
 		}
 	}
 }
@@ -439,7 +442,7 @@ void spSkeleton_update(spSkeleton *self, float delta) {
     self->time += delta;
 }
 
-void spSkeleton_updateWorldTransformWith(const spSkeleton *self, const spBone *parent) {
+void spSkeleton_updateWorldTransformWith(const spSkeleton *self, const spBone *parent, spPhysics physics) {
 	/* Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection. */
 	int i;
 	float rotationY, la, lb, lc, ld;
@@ -475,6 +478,8 @@ void spSkeleton_updateWorldTransformWith(const spSkeleton *self, const spBone *p
 			case SP_UPDATE_PATH_CONSTRAINT:
 				spPathConstraint_update((spPathConstraint *) update->object);
 				break;
+			case SP_UPDATE_PHYSICS_CONSTRAINT:
+				spPhysicsConstraint_update((spPhysicsConstraint *) update->object, physics);
 		}
 	}
 }
@@ -632,3 +637,11 @@ spPathConstraint *spSkeleton_findPathConstraint(const spSkeleton *self, const ch
 		if (strcmp(self->pathConstraints[i]->data->name, constraintName) == 0) return self->pathConstraints[i];
 	return 0;
 }
+
+
+spPhysicsConstraint *spSkeleton_findPhysicsConstraint(const spSkeleton *self, const char *constraintName) {
+	int i;
+	for (i = 0; i < self->physicsConstraintsCount; ++i)
+		if (strcmp(self->physicsConstraints[i]->data->name, constraintName) == 0) return self->physicsConstraints[i];
+	return 0;
+}

+ 6 - 6
spine-c/spine-c/src/spine/SkeletonBinary.c

@@ -1005,13 +1005,13 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
 
 	switch (type) {
 		case SP_ATTACHMENT_REGION: {
-			const char *path = readStringRef(input, skeletonData);
+			char *path = readStringRef(input, skeletonData);
 			float rotation, x, y, scaleX, scaleY, width, height;
 			spColor color;
 			spSequence *sequence;
 			if (!path) MALLOC_STR(path, name);
 			else {
-				const char *tmp = 0;
+				char *tmp = 0;
 				MALLOC_STR(tmp, path);
 				path = tmp;
 			}
@@ -1067,7 +1067,7 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
 		}
 		case SP_ATTACHMENT_MESH: {
 			int vertexCount;
-			const char *path = readStringRef(input, skeletonData);
+			char *path = readStringRef(input, skeletonData);
 			spColor color;
 			float *regionUVs;
 			unsigned short *triangles;
@@ -1085,7 +1085,7 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
 			float height = 0;
 			if (!path) MALLOC_STR(path, name);
 			else {
-				const char *tmp = 0;
+				char *tmp = 0;
 				MALLOC_STR(tmp, path);
 				path = tmp;
 			}
@@ -1137,10 +1137,10 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
 			const char *parent;
 			int inheritTimeline;
 			spSequence *sequence;
-			const char *path = readStringRef(input, skeletonData);
+			char *path = readStringRef(input, skeletonData);
 			if (!path) MALLOC_STR(path, name);
 			else {
-				const char *tmp = 0;
+				char *tmp = 0;
 				MALLOC_STR(tmp, path);
 				path = tmp;
 			}

+ 11 - 0
spine-c/spine-c/src/spine/SkeletonData.c

@@ -74,6 +74,10 @@ void spSkeletonData_dispose(spSkeletonData *self) {
 		spPathConstraintData_dispose(self->pathConstraints[i]);
 	FREE(self->pathConstraints);
 
+    for (i = 0; i < self->physicsConstraintsCount; i++)
+        spPhysicsConstraintData_dispose(self->physicsConstraints[i]);
+    FREE(self->physicsConstraints);
+
 	FREE(self->hash);
 	FREE(self->version);
 	FREE(self->imagesPath);
@@ -138,3 +142,10 @@ spPathConstraintData *spSkeletonData_findPathConstraint(const spSkeletonData *se
 		if (strcmp(self->pathConstraints[i]->name, constraintName) == 0) return self->pathConstraints[i];
 	return 0;
 }
+
+spPhysicsConstraintData *spSkeletonData_findPhysicsConstraint(const spSkeletonData *self, const char *constraintName) {
+    int i;
+    for (i = 0; i < self->physicsConstraintsCount; ++i)
+        if (strcmp(self->physicsConstraints[i]->name, constraintName) == 0) return self->physicsConstraints[i];
+    return 0;
+}

+ 3 - 2
spine-c/spine-c/src/spine/Skin.c

@@ -42,7 +42,7 @@ _SP_ARRAY_IMPLEMENT_TYPE(spPathConstraintDataArray, spPathConstraintData *)
 _Entry *_Entry_create(int slotIndex, const char *name, spAttachment *attachment) {
 	_Entry *self = NEW(_Entry);
 	self->slotIndex = slotIndex;
-	MALLOC_STR(self->name, name);
+	MALLOC_STR(self->name, (char *)name);
 	self->attachment = attachment;
 	return self;
 }
@@ -67,11 +67,12 @@ static void _SkinHashTableEntry_dispose(_SkinHashTableEntry *self) {
 
 spSkin *spSkin_create(const char *name) {
 	spSkin *self = SUPER(NEW(_spSkin));
-	MALLOC_STR(self->name, name);
+	MALLOC_STR(self->name, (char*)name);
 	self->bones = spBoneDataArray_create(4);
 	self->ikConstraints = spIkConstraintDataArray_create(4);
 	self->transformConstraints = spTransformConstraintDataArray_create(4);
 	self->pathConstraints = spPathConstraintDataArray_create(4);
+    spColor_setFromFloats(&self->color, 0.99607843f, 0.61960787f, 0.30980393f, 1);
 	return self;
 }
 

+ 1 - 0
spine-c/spine-c/src/spine/SlotData.c

@@ -36,6 +36,7 @@ spSlotData *spSlotData_create(const int index, const char *name, spBoneData *bon
 	MALLOC_STR(self->name, name);
 	self->boneData = boneData;
 	spColor_setFromFloats(&self->color, 1, 1, 1, 1);
+    self->visible = -1;
 	return self;
 }