From a725dcd292b21e0b2bc5285fedb4e4ed906b4949 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Tue, 22 Mar 2022 12:51:42 +0100 Subject: [PATCH] [c] Fix sequences for meshes, sanitizer warnings --- spine-c/spine-c/include/spine/Sequence.h | 2 +- spine-c/spine-c/src/spine/Animation.c | 8 +--- .../spine-c/src/spine/AtlasAttachmentLoader.c | 2 +- spine-c/spine-c/src/spine/Sequence.c | 30 ++++++++++++- spine-c/spine-c/src/spine/SkeletonBinary.c | 12 +++--- spine-c/spine-c/src/spine/SkeletonJson.c | 3 +- spine-sfml/c/example/main.cpp | 42 ++++++++++++++++++- spine-sfml/cpp/example/main.cpp | 2 + 8 files changed, 82 insertions(+), 19 deletions(-) diff --git a/spine-c/spine-c/include/spine/Sequence.h b/spine-c/spine-c/include/spine/Sequence.h index 8db01987b..0104d6de9 100644 --- a/spine-c/spine-c/include/spine/Sequence.h +++ b/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 diff --git a/spine-c/spine-c/src/spine/Animation.c b/spine-c/spine-c/src/spine/Animation.c index d5e8d3f4f..2135a8704 100644 --- a/spine-c/spine-c/src/spine/Animation.c +++ b/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) { diff --git a/spine-c/spine-c/src/spine/AtlasAttachmentLoader.c b/spine-c/spine-c/src/spine/AtlasAttachmentLoader.c index 7ccff5d28..30f32a19d 100644 --- a/spine-c/spine-c/src/spine/AtlasAttachmentLoader.c +++ b/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); diff --git a/spine-c/spine-c/src/spine/Sequence.c b/spine-c/spine-c/src/spine/Sequence.c index f9858dbf5..510a8bd39 100644 --- a/spine-c/spine-c/src/spine/Sequence.c +++ b/spine-c/spine-c/src/spine/Sequence.c @@ -29,6 +29,7 @@ #include #include +#include _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); } diff --git a/spine-c/spine-c/src/spine/SkeletonBinary.c b/spine-c/spine-c/src/spine/SkeletonBinary.c index 1bc66d4e0..e0d0e0812 100644 --- a/spine-c/spine-c/src/spine/SkeletonBinary.c +++ b/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; } diff --git a/spine-c/spine-c/src/spine/SkeletonJson.c b/spine-c/spine-c/src/spine/SkeletonJson.c index a6cdd01ab..c0acbfaa6 100644 --- a/spine-c/spine-c/src/spine/SkeletonJson.c +++ b/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) { diff --git a/spine-sfml/c/example/main.cpp b/spine-sfml/c/example/main.cpp index 922d14924..e55e510ee 100644 --- a/spine-sfml/c/example/main.cpp +++ b/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); diff --git a/spine-sfml/cpp/example/main.cpp b/spine-sfml/cpp/example/main.cpp index fd7aa445a..c3fb5a4c7 100644 --- a/spine-sfml/cpp/example/main.cpp +++ b/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);