[c] 4.0 porting, skeleton binary.

This commit is contained in:
badlogic 2021-05-19 12:31:40 +02:00
parent 34ccbce8fd
commit 7a7a69592a
8 changed files with 319 additions and 102 deletions

View File

@ -123,6 +123,7 @@ struct spTimeline {
SP_API void spTimeline_dispose (spTimeline* self); SP_API void spTimeline_dispose (spTimeline* self);
SP_API void spTimeline_apply (spTimeline* self, struct spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, SP_API void spTimeline_apply (spTimeline* self, struct spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction); int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction);
SP_API void spTimeline_setBezier(spTimeline* self, int bezier, int frame, float value, float time1, float value1, float cx1, float cy1, float cx2, float cy2, float time2, float value2);
SP_API int spTimeline_getFrameCount (const spTimeline* self); SP_API int spTimeline_getFrameCount (const spTimeline* self);
SP_API float spTimeline_getDuration (const spTimeline* self); SP_API float spTimeline_getDuration (const spTimeline* self);
@ -281,7 +282,7 @@ typedef struct spRGBTimeline {
SP_API spRGBTimeline* spRGBTimeline_create (int framesCount, int bezierCount, int slotIndex); SP_API spRGBTimeline* spRGBTimeline_create (int framesCount, int bezierCount, int slotIndex);
SP_API void spRGBTimeline_setFrame (spRGBATimeline* self, int frameIndex, float time, float r, float g, float b); SP_API void spRGBTimeline_setFrame (spRGBTimeline* self, int frameIndex, float time, float r, float g, float b);
/**/ /**/

View File

@ -49,7 +49,6 @@ struct spMeshAttachment {
int regionWidth, regionHeight; /* Unrotated, stripped pixel size. */ int regionWidth, regionHeight; /* Unrotated, stripped pixel size. */
int regionOriginalWidth, regionOriginalHeight; /* Unrotated, unstripped pixel size. */ int regionOriginalWidth, regionOriginalHeight; /* Unrotated, unstripped pixel size. */
float regionU, regionV, regionU2, regionV2; float regionU, regionV, regionU2, regionV2;
int/*bool*/regionRotate;
int regionDegrees; int regionDegrees;
const char* path; const char* path;

View File

@ -55,7 +55,7 @@ typedef struct spRegionAttachment {
} spRegionAttachment; } spRegionAttachment;
SP_API spRegionAttachment* spRegionAttachment_create (const char* name); SP_API spRegionAttachment* spRegionAttachment_create (const char* name);
SP_API void spRegionAttachment_setUVs (spRegionAttachment* self, float u, float v, float u2, float v2, int/*bool*/rotate); SP_API void spRegionAttachment_setUVs (spRegionAttachment* self, float u, float v, float u2, float v2, float degrees);
SP_API void spRegionAttachment_updateOffset (spRegionAttachment* self); SP_API void spRegionAttachment_updateOffset (spRegionAttachment* self);
SP_API void spRegionAttachment_computeWorldVertices (spRegionAttachment* self, spBone* bone, float* vertices, int offset, int stride); SP_API void spRegionAttachment_computeWorldVertices (spRegionAttachment* self, spBone* bone, float* vertices, int offset, int stride);

View File

@ -128,6 +128,11 @@ void spTimeline_apply (spTimeline* self, spSkeleton* skeleton, float lastTime, f
self->vtable.apply(self, skeleton, lastTime, time, firedEvents, eventsCount, alpha, blend, direction); self->vtable.apply(self, skeleton, lastTime, time, firedEvents, eventsCount, alpha, blend, direction);
} }
void spTimeline_setBezier(spTimeline* self, int bezier, int frame, float value, float time1, float value1, float cx1, float cy1, float cx2, float cy2, float time2, float value2) {
if (self->vtable.setBezier)
self->vtable.setBezier(self, bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
}
int spTimeline_getFrameCount (const spTimeline* self) { int spTimeline_getFrameCount (const spTimeline* self) {
return self->frames->size / self->frameEntries; return self->frames->size / self->frameEntries;
} }
@ -1217,7 +1222,7 @@ spRGBTimeline* spRGBTimeline_create (int framesCount, int bezierCount, int slotI
return timeline; return timeline;
} }
void spRGBTimeline_setFrame (spRGBATimeline* self, int frameIndex, float time, float r, float g, float b) { void spRGBTimeline_setFrame (spRGBTimeline* self, int frameIndex, float time, float r, float g, float b) {
float *frames = self->super.super.frames->items; float *frames = self->super.super.frames->items;
frameIndex *= RGB_ENTRIES; frameIndex *= RGB_ENTRIES;
frames[frameIndex] = time; frames[frameIndex] = time;

View File

@ -43,7 +43,7 @@ spAttachment* _spAtlasAttachmentLoader_createAttachment (spAttachmentLoader* loa
} }
attachment = spRegionAttachment_create(name); attachment = spRegionAttachment_create(name);
attachment->rendererObject = region; attachment->rendererObject = region;
spRegionAttachment_setUVs(attachment, region->u, region->v, region->u2, region->v2, region->rotate); spRegionAttachment_setUVs(attachment, region->u, region->v, region->u2, region->v2, region->degrees);
attachment->regionOffsetX = region->offsetX; attachment->regionOffsetX = region->offsetX;
attachment->regionOffsetY = region->offsetY; attachment->regionOffsetY = region->offsetY;
attachment->regionWidth = region->width; attachment->regionWidth = region->width;
@ -66,7 +66,6 @@ spAttachment* _spAtlasAttachmentLoader_createAttachment (spAttachmentLoader* loa
attachment->regionV = region->v; attachment->regionV = region->v;
attachment->regionU2 = region->u2; attachment->regionU2 = region->u2;
attachment->regionV2 = region->v2; attachment->regionV2 = region->v2;
attachment->regionRotate = region->rotate;
attachment->regionDegrees = region->degrees; attachment->regionDegrees = region->degrees;
attachment->regionOffsetX = region->offsetX; attachment->regionOffsetX = region->offsetX;
attachment->regionOffsetY = region->offsetY; attachment->regionOffsetY = region->offsetY;

View File

@ -56,7 +56,6 @@ spAttachment* _spMeshAttachment_copy (spAttachment* attachment) {
copy->regionV = self->regionV; copy->regionV = self->regionV;
copy->regionU2 = self->regionU2; copy->regionU2 = self->regionU2;
copy->regionV2 = self->regionV2; copy->regionV2 = self->regionV2;
copy->regionRotate = self->regionRotate;
copy->regionDegrees = self->regionDegrees; copy->regionDegrees = self->regionDegrees;
copy->regionOffsetX = self->regionOffsetX; copy->regionOffsetX = self->regionOffsetX;
copy->regionOffsetY = self->regionOffsetY; copy->regionOffsetY = self->regionOffsetY;
@ -95,7 +94,6 @@ spMeshAttachment* spMeshAttachment_newLinkedMesh (spMeshAttachment* self) {
copy->regionV = self->regionV; copy->regionV = self->regionV;
copy->regionU2 = self->regionU2; copy->regionU2 = self->regionU2;
copy->regionV2 = self->regionV2; copy->regionV2 = self->regionV2;
copy->regionRotate = self->regionRotate;
copy->regionDegrees = self->regionDegrees; copy->regionDegrees = self->regionDegrees;
copy->regionOffsetX = self->regionOffsetX; copy->regionOffsetX = self->regionOffsetX;
copy->regionOffsetY = self->regionOffsetY; copy->regionOffsetY = self->regionOffsetY;

View File

@ -74,8 +74,8 @@ spRegionAttachment* spRegionAttachment_create (const char* name) {
return self; return self;
} }
void spRegionAttachment_setUVs (spRegionAttachment* self, float u, float v, float u2, float v2, int/*bool*/rotate) { void spRegionAttachment_setUVs (spRegionAttachment* self, float u, float v, float u2, float v2, float degrees) {
if (rotate) { if (degrees == 90) {
self->uvs[URX] = u; self->uvs[URX] = u;
self->uvs[URY] = v2; self->uvs[URY] = v2;
self->uvs[BRX] = u; self->uvs[BRX] = u;

View File

@ -176,23 +176,32 @@ static void readColor (_dataInput* input, float *r, float *g, float *b, float *a
#define BLEND_MODE_MULTIPLY 2 #define BLEND_MODE_MULTIPLY 2
#define BLEND_MODE_SCREEN 3 #define BLEND_MODE_SCREEN 3
#define CURVE_LINEAR 0
#define CURVE_STEPPED 1
#define CURVE_BEZIER 2
#define BONE_ROTATE 0 #define BONE_ROTATE 0
#define BONE_TRANSLATE 1 #define BONE_TRANSLATE 1
#define BONE_SCALE 2 #define BONE_TRANSLATEX 2
#define BONE_SHEAR 3 #define BONE_TRANSLATEY 3
#define BONE_SCALE 4
#define BONE_SCALEX 5
#define BONE_SCALEY 6
#define BONE_SHEAR 7
#define BONE_SHEARX 8
#define BONE_SHEARY 9
#define SLOT_ATTACHMENT 0 #define SLOT_ATTACHMENT 0
#define SLOT_COLOR 1 #define SLOT_RGBA 1
#define SLOT_TWO_COLOR 2 #define SLOT_RGB 2
#define SLOT_RGBA2 3
#define SLOT_RGB2 4
#define SLOT_ALPHA 5
#define PATH_POSITION 0 #define PATH_POSITION 0
#define PATH_SPACING 1 #define PATH_SPACING 1
#define PATH_MIX 2 #define PATH_MIX 2
#define CURVE_LINEAR 0
#define CURVE_STEPPED 1
#define CURVE_BEZIER 2
#define PATH_POSITION_FIXED 0 #define PATH_POSITION_FIXED 0
#define PATH_POSITION_PERCENT 1 #define PATH_POSITION_PERCENT 1
@ -204,21 +213,63 @@ static void readColor (_dataInput* input, float *r, float *g, float *b, float *a
#define PATH_ROTATE_CHAIN 1 #define PATH_ROTATE_CHAIN 1
#define PATH_ROTATE_CHAIN_SCALE 2 #define PATH_ROTATE_CHAIN_SCALE 2
static void readCurve (_dataInput* input, spCurveTimeline* timeline, int frameIndex) { static void setBezier(_dataInput* input, spTimeline* timeline, int bezier, int frame, int value, float time1, float time2,
switch (readByte(input)) { float value1, float value2, float scale) {
case CURVE_STEPPED: { float cx1 = readFloat(input);
spCurveTimeline_setStepped(timeline, frameIndex); float cy1 = readFloat(input);
break; float cx2 = readFloat(input);
} float cy2 = readFloat(input);
case CURVE_BEZIER: { spTimeline_setBezier(timeline, bezier, frame, value, time1, value1, cx1, cy1 * scale, cx2, cy2 * scale, time2, value2);
float cx1 = readFloat(input); }
float cy1 = readFloat(input);
float cx2 = readFloat(input); static spTimeline* readTimeline (_dataInput *input, spCurveTimeline1 *timeline, float scale) {
float cy2 = readFloat(input); int frame, bezier, frameLast;
spCurveTimeline_setCurve(timeline, frameIndex, cx1, cy1, cx2, cy2); float time2, value2;
break; float time = readFloat(input);
} float value = readFloat(input) * scale;
} for (frame = 0, bezier = 0, frameLast = spTimeline_getFrameCount(SUPER(timeline)) - 1;; frame++) {
spCurveTimeline1_setFrame(timeline, frame, time, value);
if (frame == frameLast) break;
time2 = readFloat(input);
value2 = readFloat(input) * scale;
switch (readSByte(input)) {
case CURVE_STEPPED:
spCurveTimeline_setStepped(timeline, frame);
break;
case CURVE_BEZIER:
setBezier(input, SUPER(timeline), bezier++, frame, 0, time, time2, value, value2, 1);
}
time = time2;
value = value2;
}
return SUPER(timeline);
}
static spTimeline* readTimeline2 (_dataInput *input, spCurveTimeline2 *timeline, float scale) {
int frame, bezier, frameLast;
float time2, nvalue1, nvalue2;
float time = readFloat(input);
float value1 = readFloat(input) * scale;
float value2 = readFloat(input) * scale;
for (frame = 0, bezier = 0, frameLast = spTimeline_getFrameCount(SUPER(timeline)) - 1;; frame++) {
spCurveTimeline2_setFrame(timeline, frame, time, value1, value2);
if (frame == frameLast) break;
time2 = readFloat(input);
nvalue1 = readFloat(input) * scale;
nvalue2 = readFloat(input) * scale;
switch (readSByte(input)) {
case CURVE_STEPPED:
spCurveTimeline_setStepped(timeline, frame);
break;
case CURVE_BEZIER:
setBezier(input, SUPER(timeline), bezier++, frame, 0, time, time2, value1, nvalue1, scale);
setBezier(input, SUPER(timeline), bezier++, frame, 1, time, time2, value2, nvalue2, scale);
}
time = time2;
value1 = nvalue1;
value2 = nvalue2;
}
return SUPER(timeline);
} }
static void _spSkeletonBinary_addLinkedMesh (spSkeletonBinary* self, spMeshAttachment* mesh, static void _spSkeletonBinary_addLinkedMesh (spSkeletonBinary* self, spMeshAttachment* mesh,
@ -250,67 +301,232 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
spTimelineArray* timelines = spTimelineArray_create(18); spTimelineArray* timelines = spTimelineArray_create(18);
float duration = 0; float duration = 0;
int i, n, ii, nn, iii, nnn; int i, n, ii, nn, iii, nnn;
int frameIndex; int frame, bezier;
int drawOrderCount, eventCount; int drawOrderCount, eventCount;
spAnimation* animation; spAnimation* animation;
int numTimelines = readVarint(input, 1);
UNUSED(numTimelines);
/* Slot timelines. */ /* Slot timelines. */
for (i = 0, n = readVarint(input, 1); i < n; ++i) { for (i = 0, n = readVarint(input, 1); i < n; ++i) {
int slotIndex = readVarint(input, 1); int slotIndex = readVarint(input, 1);
for (ii = 0, nn = readVarint(input, 1); ii < nn; ++ii) { for (ii = 0, nn = readVarint(input, 1); ii < nn; ++ii) {
unsigned char timelineType = readByte(input); unsigned char timelineType = readByte(input);
int frameCount = readVarint(input, 1); int frameCount = readVarint(input, 1);
int frameLast = frameCount - 1;
switch (timelineType) { switch (timelineType) {
case SLOT_ATTACHMENT: { case SLOT_ATTACHMENT: {
spAttachmentTimeline* timeline = spAttachmentTimeline_create(frameCount); spAttachmentTimeline *timeline = spAttachmentTimeline_create(frameCount, slotIndex);
timeline->slotIndex = slotIndex; for (frame = 0; frame < frameCount; ++frame) {
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) { float time = readFloat(input);
float time = readFloat(input); const char *attachmentName = readStringRef(input, skeletonData);
const char* attachmentName = readStringRef(input, skeletonData); spAttachmentTimeline_setFrame(timeline, frame, time, attachmentName);
/* TODO Avoid copying of attachmentName inside */ }
spAttachmentTimeline_setFrame(timeline, frameIndex, time, attachmentName); spTimelineArray_add(timelines, SUPER(timeline));
} break;
spTimelineArray_add(timelines, (spTimeline*)timeline); }
duration = MAX(duration, timeline->frames[frameCount - 1]); case SLOT_RGBA: {
break; int bezierCount = readVarint(input, 1);
} spRGBATimeline *timeline = spRGBATimeline_create(frameCount, bezierCount, slotIndex);
case SLOT_COLOR: {
spColorTimeline* timeline = spColorTimeline_create(frameCount); float time = readFloat(input);
timeline->slotIndex = slotIndex; float r = readByte(input) / 255.0;
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) { float g = readByte(input) / 255.0;
float time = readFloat(input); float b = readByte(input) / 255.0;
float r, g, b, a; float a = readByte(input) / 255.0;
readColor(input, &r, &g, &b, &a);
spColorTimeline_setFrame(timeline, frameIndex, time, r, g, b, a); for (frame = 0, bezier = 0;; frame++) {
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex); float time2, r2, g2, b2, a2;
} spRGBATimeline_setFrame(timeline, frame, time, r, g, b, a);
spTimelineArray_add(timelines, (spTimeline*)timeline); if (frame == frameLast) break;
duration = MAX(duration, timeline->frames[(frameCount - 1) * COLOR_ENTRIES]);
break; time2 = readFloat(input);
} r2 = readByte(input) / 255.0;
case SLOT_TWO_COLOR: { g2 = readByte(input) / 255.0;
spTwoColorTimeline* timeline = spTwoColorTimeline_create(frameCount); b2 = readByte(input) / 255.0;
timeline->slotIndex = slotIndex; a2 = readByte(input) / 255.0;
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
float time = readFloat(input); switch (readSByte(input)) {
float r, g, b, a; case CURVE_STEPPED:
float r2, g2, b2, a2; spCurveTimeline_setStepped(SUPER(timeline), frame);
readColor(input, &r, &g, &b, &a); break;
readColor(input, &a2, &r2, &g2, &b2); case CURVE_BEZIER:
spTwoColorTimeline_setFrame(timeline, frameIndex, time, r, g, b, a, r2, g2, b2); setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 0, time, time2, r, r2, 1);
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex); setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 1, time, time2, g, g2, 1);
} setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 2, time, time2, b, b2, 1);
spTimelineArray_add(timelines, (spTimeline*)timeline); setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 3, time, time2, a, a2, 1);
duration = MAX(duration, timeline->frames[(frameCount - 1) * TWOCOLOR_ENTRIES]); }
break; time = time2;
} r = r2;
default: { g = g2;
for (iii = 0; iii < timelines->size; ++iii) b = b2;
spTimeline_dispose(timelines->items[iii]); a = a2;
spTimelineArray_dispose(timelines); }
_spSkeletonBinary_setError(self, "Invalid timeline type for a slot: ", skeletonData->slots[slotIndex]->name); spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
return 0; break;
} }
case SLOT_RGB: {
int bezierCount = readVarint(input, 1);
spRGBTimeline *timeline = spRGBTimeline_create(frameCount, bezierCount, slotIndex);
float time = readFloat(input);
float r = readByte(input) / 255.0;
float g = readByte(input) / 255.0;
float b = readByte(input) / 255.0;
for (frame = 0, bezier = 0;; frame++) {
float time2, r2, g2, b2;
spRGBTimeline_setFrame(timeline, frame, time, r, g, b);
if (frame == frameLast) break;
time2 = readFloat(input);
r2 = readByte(input) / 255.0;
g2 = readByte(input) / 255.0;
b2 = readByte(input) / 255.0;
switch (readSByte(input)) {
case CURVE_STEPPED:
spCurveTimeline_setStepped(SUPER(timeline), frame);
break;
case CURVE_BEZIER:
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 0, time, time2, r, r2, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 1, time, time2, g, g2, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 2, time, time2, b, b2, 1);
}
time = time2;
r = r2;
g = g2;
b = b2;
}
spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
break;
}
case SLOT_RGBA2: {
int bezierCount = readVarint(input, 1);
spRGBA2Timeline *timeline = spRGBA2Timeline_create(frameCount, bezierCount, slotIndex);
float time = readFloat(input);
float r = readByte(input) / 255.0;
float g = readByte(input) / 255.0;
float b = readByte(input) / 255.0;
float a = readByte(input) / 255.0;
float r2 = readByte(input) / 255.0;
float g2 = readByte(input) / 255.0;
float b2 = readByte(input) / 255.0;
for (frame = 0, bezier = 0;; frame++) {
float time2, nr, ng, nb, na, nr2, ng2, nb2;
spRGBA2Timeline_setFrame(timeline, frame, time, r, g, b, a, r2, g2, b2);
if (frame == frameLast) break;
time2 = readFloat(input);
nr = readByte(input) / 255.0;
ng = readByte(input) / 255.0;
nb = readByte(input) / 255.0;
na = readByte(input) / 255.0;
nr2 = readByte(input) / 255.0;
ng2 = readByte(input) / 255.0;
nb2 = readByte(input) / 255.0;
switch (readSByte(input)) {
case CURVE_STEPPED:
spCurveTimeline_setStepped(SUPER(timeline), frame);
break;
case CURVE_BEZIER:
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 0, time, time2, r, nr, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 1, time, time2, g, ng, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 2, time, time2, b, nb, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 3, time, time2, a, na, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 4, time, time2, r2, nr2, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 5, time, time2, g2, ng2, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 6, time, time2, b2, nb2, 1);
}
time = time2;
r = nr;
g = ng;
b = nb;
a = na;
r2 = nr2;
g2 = ng2;
b2 = nb2;
}
spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
break;
}
case SLOT_RGB2: {
int bezierCount = readVarint(input, 1);
spRGB2Timeline *timeline = spRGB2Timeline_create(frameCount, bezierCount, slotIndex);
float time = readFloat(input);
float r = readByte(input) / 255.0;
float g = readByte(input) / 255.0;
float b = readByte(input) / 255.0;
float r2 = readByte(input) / 255.0;
float g2 = readByte(input) / 255.0;
float b2 = readByte(input) / 255.0;
for (frame = 0, bezier = 0;; frame++) {
float time2, nr, ng, nb, nr2, ng2, nb2;
spRGB2Timeline_setFrame(timeline, frame, time, r, g, b, r2, g2, b2);
if (frame == frameLast) break;
time2 = readFloat(input);
nr = readByte(input) / 255.0;
ng = readByte(input) / 255.0;
nb = readByte(input) / 255.0;
nr2 = readByte(input) / 255.0;
ng2 = readByte(input) / 255.0;
nb2 = readByte(input) / 255.0;
switch (readSByte(input)) {
case CURVE_STEPPED:
spCurveTimeline_setStepped(frame);
break;
case CURVE_BEZIER:
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 0, time, time2, r, nr, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 1, time, time2, g, ng, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 2, time, time2, b, nb, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 3, time, time2, r2, nr2, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 4, time, time2, g2, ng2, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 5, time, time2, b2, nb2, 1);
}
time = time2;
r = nr;
g = ng;
b = nb;
r2 = nr2;
g2 = ng2;
b2 = nb2;
}
spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
break;
}
case SLOT_ALPHA: {
int bezierCount = readVarint(input, 1);
spAlphaTimeline *timeline = spAlphaTimeline_create(frameCount, bezierCount, slotIndex);
float time = readFloat(input);
float a = readByte(input) / 255.0;
for (frame = 0, bezier = 0;; frame++) {
float time2, a2;
spAlphaTimeline_setFrame(timeline, frame, time, a);
if (frame == frameLast) break;
time2 = readFloat(input);
a2 = readByte(input) / 255;
switch (readSByte(input)) {
case CURVE_STEPPED:
spCurveTimeline_setStepped(SUPER(timeline), frame);
break;
case CURVE_BEZIER:
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 0, time, time2, a, a2, 1);
}
time = time2;
a = a2;
}
spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
break;
}
default: {
return NULL;
}
} }
} }
} }
@ -873,6 +1089,8 @@ spSkeletonData* spSkeletonBinary_readSkeletonDataFile (spSkeletonBinary* self, c
spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const unsigned char* binary, spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const unsigned char* binary,
const int length) { const int length) {
int i, n, ii, nonessential; int i, n, ii, nonessential;
char buffer[16];
int lowHash, highHash;
spSkeletonData* skeletonData; spSkeletonData* skeletonData;
_spSkeletonBinary* internal = SUB_CAST(_spSkeletonBinary, self); _spSkeletonBinary* internal = SUB_CAST(_spSkeletonBinary, self);
@ -885,24 +1103,18 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
internal->linkedMeshCount = 0; internal->linkedMeshCount = 0;
skeletonData = spSkeletonData_create(); skeletonData = spSkeletonData_create();
lowHash = readInt(input);
skeletonData->hash = readString(input); highHash = readInt(input);
if (!strlen(skeletonData->hash)) { sprintf(buffer, "%x", highHash);
FREE(skeletonData->hash); sprintf(buffer + 8, "%x", lowHash);
skeletonData->hash = 0; buffer[15] = 0;
} skeletonData->hash = strdup(buffer);
skeletonData->version = readString(input); skeletonData->version = readString(input);
if (!strlen(skeletonData->version)) { if (!strlen(skeletonData->version)) {
FREE(skeletonData->version); FREE(skeletonData->version);
skeletonData->version = 0; skeletonData->version = 0;
} }
if (strcmp(skeletonData->version, "3.8.75") == 0) {
FREE(input);
spSkeletonData_dispose(skeletonData);
_spSkeletonBinary_setError(self, "Unsupported skeleton data, please export with a newer version of Spine.", "");
return 0;
}
skeletonData->x = readFloat(input); skeletonData->x = readFloat(input);
skeletonData->y = readFloat(input); skeletonData->y = readFloat(input);
@ -1031,10 +1243,12 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
data->offsetScaleX = readFloat(input); data->offsetScaleX = readFloat(input);
data->offsetScaleY = readFloat(input); data->offsetScaleY = readFloat(input);
data->offsetShearY = readFloat(input); data->offsetShearY = readFloat(input);
data->rotateMix = readFloat(input); data->mixRotate = readFloat(input);
data->translateMix = readFloat(input); data->mixX = readFloat(input);
data->scaleMix = readFloat(input); data->mixY = readFloat(input);
data->shearMix = readFloat(input); data->mixScaleX = readFloat(input);
data->mixScaleY = readFloat(input);
data->mixShearY = readFloat(input);
skeletonData->transformConstraints[i] = data; skeletonData->transformConstraints[i] = data;
} }
@ -1061,8 +1275,9 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
if (data->positionMode == SP_POSITION_MODE_FIXED) data->position *= self->scale; if (data->positionMode == SP_POSITION_MODE_FIXED) data->position *= self->scale;
data->spacing = readFloat(input); data->spacing = readFloat(input);
if (data->spacingMode == SP_SPACING_MODE_LENGTH || data->spacingMode == SP_SPACING_MODE_FIXED) data->spacing *= self->scale; if (data->spacingMode == SP_SPACING_MODE_LENGTH || data->spacingMode == SP_SPACING_MODE_FIXED) data->spacing *= self->scale;
data->rotateMix = readFloat(input); data->mixRotate = readFloat(input);
data->translateMix = readFloat(input); data->mixX = readFloat(input);
data->mixY = readFloat(input);
skeletonData->pathConstraints[i] = data; skeletonData->pathConstraints[i] = data;
} }