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

[c] Fix sequences for meshes, sanitizer warnings

Mario Zechner 3 жил өмнө
parent
commit
a725dcd292

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

@@ -58,7 +58,7 @@ SP_API spSequence *spSequence_copy(spSequence *self);
 
 SP_API void spSequence_apply(spSequence *self, spSlot *slot, spAttachment *attachment);
 
-SP_API void spSequence_getPath(const char* basePath, int index, char *path);
+SP_API void spSequence_getPath(spSequence *self, const char *basePath, int index, char *path);
 
 #define SP_SEQUENCE_MODE_HOLD 0
 #define SP_SEQUENCE_MODE_ONCE 1

+ 2 - 6
spine-c/spine-c/src/spine/Animation.c

@@ -2083,12 +2083,8 @@ void _spSequenceTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float
 }
 
 void _spSequenceTimeline_dispose(spTimeline *timeline) {
-	spEventTimeline *self = SUB_CAST(spEventTimeline, timeline);
-	int i;
-
-	for (i = 0; i < self->super.frames->size; ++i)
-		spEvent_dispose(self->events[i]);
-	FREE(self->events);
+	/* NO-OP */
+	UNUSED(timeline);
 }
 
 spSequenceTimeline *spSequenceTimeline_create(int framesCount, int slotIndex, spAttachment *attachment) {

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

@@ -36,7 +36,7 @@ static int /*bool*/ loadSequence(spAtlas *atlas, const char *basePath, spSequenc
 	char *path = CALLOC(char, strlen(basePath) + sequence->digits + 1);
 	int i;
 	for (i = 0; i < regions->size; i++) {
-		spSequence_getPath(basePath, i, path);
+		spSequence_getPath(sequence, basePath, i, path);
 		regions->items[i] = SUPER(spAtlas_findRegion(atlas, path));
 		if (!regions->items[i]) {
 			FREE(path);

+ 28 - 2
spine-c/spine-c/src/spine/Sequence.c

@@ -29,6 +29,7 @@
 
 #include <spine/Sequence.h>
 #include <spine/extension.h>
+#include <stdio.h>
 
 _SP_ARRAY_IMPLEMENT_TYPE(spTextureRegionArray, spTextureRegion *)
 
@@ -84,6 +85,31 @@ void spSequence_apply(spSequence *self, spSlot *slot, spAttachment *attachment)
 	}
 }
 
-void spSequence_getPath(const char *basePath, int index, char *path) {
-	fix me
+static int num_digits(int value) {
+	int count = value < 0 ? 1 : 0;
+	do {
+		value /= 10;
+		++count;
+	} while (value != 0);
+	return count;
+}
+
+static char *string_append(char *str, const char *b) {
+	int lenB = strlen(b);
+	memcpy(str, b, lenB + 1);
+	return str + lenB;
+}
+
+static char *string_append_int(char *str, int value) {
+	char intStr[20];;
+	sprintf(intStr, "%i", value);
+	return string_append(str, intStr);
+}
+
+void spSequence_getPath(spSequence *self, const char *basePath, int index, char *path) {
+	int i;
+	path = string_append(path, basePath);
+	for (i = self->digits - num_digits(self->start + index); i > 0; i--)
+		path = string_append(path, "0");
+	path = string_append_int(path, self->start + index);
 }

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

@@ -101,19 +101,19 @@ static int readBoolean(_dataInput *input) {
 }
 
 static int readInt(_dataInput *input) {
-	int result = readByte(input);
+	uint32_t result = readByte(input);
 	result <<= 8;
 	result |= readByte(input);
 	result <<= 8;
 	result |= readByte(input);
 	result <<= 8;
 	result |= readByte(input);
-	return result;
+	return (int)result;
 }
 
 static int readVarint(_dataInput *input, int /*bool*/ optimizePositive) {
 	unsigned char b = readByte(input);
-	int value = b & 0x7F;
+	uint32_t value = b & 0x7F;
 	if (b & 0x80) {
 		b = readByte(input);
 		value |= (b & 0x7F) << 7;
@@ -123,12 +123,12 @@ static int readVarint(_dataInput *input, int /*bool*/ optimizePositive) {
 			if (b & 0x80) {
 				b = readByte(input);
 				value |= (b & 0x7F) << 21;
-				if (b & 0x80) value |= (readByte(input) & 0x7F) << 28;
+				if (b & 0x80) value |= (uint32_t)(readByte(input) & 0x7F) << 28;
 			}
 		}
 	}
 	if (!optimizePositive) value = (((unsigned int) value >> 1) ^ -(value & 1));
-	return value;
+	return (int)value;
 }
 
 float readFloat(_dataInput *input) {
@@ -1117,7 +1117,7 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
 				mesh->width = width;
 				mesh->height = height;
 				mesh->sequence = sequence;
-				if (sequence) spMeshAttachment_updateRegion(mesh);
+				if (sequence == NULL) spMeshAttachment_updateRegion(mesh);
 				spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
 				return attachment;
 			}

+ 2 - 1
spine-c/spine-c/src/spine/SkeletonJson.c

@@ -801,6 +801,7 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
 							if (!strcmp(modeString, "loopReverse")) mode = SP_SEQUENCE_MODE_LOOPREVERSE;
 							if (!strcmp(modeString, "pingpongReverse")) mode = SP_SEQUENCE_MODE_PINGPONGREVERSE;
 							spSequenceTimeline_setFrame(timeline, frame, time, mode, index, delay);
+							lastDelay = delay;
 						}
 						spTimelineArray_add(timelines, SUPER(timeline));
 					}
@@ -1366,7 +1367,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
 						return NULL;
 					}
 
-					sequence = readSequence(attachmentMap);
+					sequence = readSequence(Json_getItem(attachmentMap, "sequence"));
 					attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, attachmentName,
 																	 path, sequence);
 					if (!attachment) {

+ 40 - 2
spine-sfml/c/example/main.cpp

@@ -95,15 +95,17 @@ void testcase(void func(spSkeletonData *skeletonData, spAtlas *atlas),
 			  float scale) {
 	spAtlas *atlas = spAtlas_createFromFile(atlasName, 0);
 
-	spSkeletonData *skeletonData = readSkeletonJsonData(jsonName, atlas, scale);
+	spSkeletonData *skeletonData = readSkeletonBinaryData(binaryName, atlas, scale);
 	func(skeletonData, atlas);
 	spSkeletonData_dispose(skeletonData);
 
-	skeletonData = readSkeletonBinaryData(binaryName, atlas, scale);
+	skeletonData = readSkeletonJsonData(jsonName, atlas, scale);
 	func(skeletonData, atlas);
 	spSkeletonData_dispose(skeletonData);
 
 	spAtlas_dispose(atlas);
+
+	UNUSED(jsonName);
 }
 
 void spineboy(spSkeletonData *skeletonData, spAtlas *atlas) {
@@ -444,6 +446,40 @@ void coin(spSkeletonData *skeletonData, spAtlas *atlas) {
 	}
 }
 
+void dragon(spSkeletonData *skeletonData, spAtlas *atlas) {
+	UNUSED(atlas);
+
+
+	SkeletonDrawable *drawable = new SkeletonDrawable(skeletonData);
+	drawable->timeScale = 1;
+	drawable->setUsePremultipliedAlpha(true);
+
+	spSkeleton *skeleton = drawable->skeleton;
+	skeleton->x = 320;
+	skeleton->y = 320;
+	spSkeleton_updateWorldTransform(skeleton);
+	spAnimationState_setAnimationByName(drawable->state, 0, "flying", true);
+
+	sf::RenderWindow window(sf::VideoMode(640, 640), "Spine SFML - dragon");
+	window.setFramerateLimit(60);
+	sf::Event event;
+	sf::Clock deltaClock;
+
+	while (window.isOpen()) {
+		while (window.pollEvent(event))
+			if (event.type == sf::Event::Closed) window.close();
+
+		float delta = deltaClock.getElapsedTime().asSeconds();
+		deltaClock.restart();
+
+		drawable->update(delta);
+
+		window.clear();
+		window.draw(*drawable);
+		window.display();
+	}
+}
+
 void owl(spSkeletonData *skeletonData, spAtlas *atlas) {
 	UNUSED(atlas);
 	SkeletonDrawable *drawable = new SkeletonDrawable(skeletonData);
@@ -492,6 +528,7 @@ void owl(spSkeletonData *skeletonData, spAtlas *atlas) {
 		float delta = deltaClock.getElapsedTime().asSeconds();
 		deltaClock.restart();
 
+		spSkeleton_setToSetupPose(drawable->skeleton);
 		drawable->update(delta);
 
 		window.clear();
@@ -623,6 +660,7 @@ void testMixAndMatch(spSkeletonData *skeletonData, spAtlas *atlas) {
 }
 
 int main() {
+	testcase(dragon, "data/dragon-ess.json", "data/dragon-ess.skel", "data/dragon-pma.atlas", 0.6f);
 	testcase(ikDemo, "data/spineboy-pro.json", "data/spineboy-pro.skel", "data/spineboy-pma.atlas", 0.6f);
 	testcase(spineboy, "data/spineboy-pro.json", "data/spineboy-pro.skel", "data/spineboy-pma.atlas", 0.6f);
 	testcase(coin, "data/coin-pro.json", "data/coin-pro.skel", "data/coin-pma.atlas", 0.5f);

+ 2 - 0
spine-sfml/cpp/example/main.cpp

@@ -564,6 +564,7 @@ void owl(SkeletonData *skeletonData, Atlas *atlas) {
 		float delta = deltaClock.getElapsedTime().asSeconds();
 		deltaClock.restart();
 
+		drawable.skeleton->setToSetupPose();
 		drawable.update(delta);
 
 		window.clear();
@@ -644,6 +645,7 @@ DebugExtension dbgExtension(SpineExtension::getInstance());
 int main() {
 	SpineExtension::setInstance(&dbgExtension);
 
+	testcase(vine, "data/vine-pro.json", "data/vine-pro.skel", "data/vine-pma.atlas", 0.5f);
 	testcase(dragon, "data/dragon-ess.json", "data/dragon-ess.skel", "data/dragon-pma.atlas", 0.6f);
 	testcase(vine, "data/vine-pro.json", "data/vine-pro.skel", "data/vine-pma.atlas", 0.5f);
 	testcase(owl, "data/owl-pro.json", "data/owl-pro.skel", "data/owl-pma.atlas", 0.5f);