diff --git a/spine-c/src/SfmlRegionAttachment.c b/spine-c/src/SfmlRegionAttachment.c deleted file mode 100644 index fdaafa721..000000000 --- a/spine-c/src/SfmlRegionAttachment.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "SfmlRegionAttachment.h" -#include - -void _RegionAttachment_init (RegionAttachment* attachment, const char* name); - -void SfmlRegionAttachment_dispose (Attachment* attachment) { - /* SfmlRegionAttachment* this = (SfmlRegionAttachment*)attachment; */ - /* dispose something */ -} - -SfmlRegionAttachment* SfmlRegionAttachment_create (const char* name) { - SfmlRegionAttachment* this = calloc(1, sizeof(SfmlRegionAttachment)); - _RegionAttachment_init(&this->super, name); - ((Attachment*)this)->_dispose = SfmlRegionAttachment_dispose; - return this; -} diff --git a/spine-c/src/SfmlRegionAttachment.h b/spine-c/src/SfmlRegionAttachment.h deleted file mode 100644 index 6e77e1161..000000000 --- a/spine-c/src/SfmlRegionAttachment.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef SPINE_SFMLREGIONATTACHMENT_H_ -#define SPINE_SFMLREGIONATTACHMENT_H_ - -#include - -#ifdef __cplusplus -namespace spine { -extern "C" { -#endif - -typedef struct { - RegionAttachment super; - int meow; -} SfmlRegionAttachment; - -SfmlRegionAttachment* SfmlRegionAttachment_create (const char* name); - -#ifdef __cplusplus -} -} -#endif - -#endif /* SPINE_SFMLREGIONATTACHMENT_H_ */ diff --git a/spine-c/src/SfmlSkeleton.c b/spine-c/src/SfmlSkeleton.c deleted file mode 100644 index 7223cedaa..000000000 --- a/spine-c/src/SfmlSkeleton.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "SfmlSkeleton.h" -#include - -void _Skeleton_init (Skeleton* this, SkeletonData* data); - -void SfmlSkeleton_dispose (Skeleton* skeleton) { - /* SfmlSkeleton* this = (SfmlSkeleton*)skeleton; */ -} - -Skeleton* Skeleton_create (SkeletonData* data) { - SfmlSkeleton* this = calloc(1, sizeof(SfmlSkeleton)); - _Skeleton_init(&this->super, data); - this->super._dispose = SfmlSkeleton_dispose; - return &this->super; -} - -void Skeleton_draw (Skeleton* skeleton) { -} diff --git a/spine-c/src/SfmlSkeleton.h b/spine-c/src/SfmlSkeleton.h deleted file mode 100644 index a4ee5a5b0..000000000 --- a/spine-c/src/SfmlSkeleton.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef SPINE_SFMLSKELETON_H_ -#define SPINE_SFMLSKELETON_H_ - -#include - -#ifdef __cplusplus -namespace spine {extern "C" { -#endif - -typedef struct { - Skeleton super; - int meow; -} SfmlSkeleton; - -Skeleton* Skeleton_create (SkeletonData* data); - -void Skeleton_draw (); - -#ifdef __cplusplus -}} -#endif - -#endif /* SPINE_SFMLSKELETON_H_ */ diff --git a/spine-c/src/main.c b/spine-c/src/main.c index c1c9184a7..59ed3ea5d 100644 --- a/spine-c/src/main.c +++ b/spine-c/src/main.c @@ -1,30 +1,97 @@ +/* This demonstrates implementing an extension to spine-c. spine/extension.h declares the functions that must be implemented along + * with a number of internal methods exposed to facilitate extension. */ + #include #include -#include - #include -#include "SfmlSkeleton.h" -#include "SfmlRegionAttachment.h" -#include "spine/cJSON.h" +#include +#include -Attachment* loadAttachment (AttachmentType type, const char* name) { - return (Attachment*)SfmlRegionAttachment_create(name); +/**/ + +typedef struct { + AtlasPage super; + int extraData; +} ExampleAtlasPage; + +void _ExampleAtlasPage_dispose (AtlasPage* page) { + ExampleAtlasPage* this = (ExampleAtlasPage*)page; + _AtlasPage_deinit(&this->super); + this->extraData = 0; + FREE(this) } +AtlasPage* AtlasPage_create (const char* name) { + ExampleAtlasPage* this = calloc(1, sizeof(ExampleAtlasPage)); + _AtlasPage_init(&this->super, name); + this->extraData = 123; + this->super._dispose = _ExampleAtlasPage_dispose; + return &this->super; +} + +/**/ + +typedef struct { + RegionAttachment super; + int extraData; +} ExampleRegionAttachment; + +void _ExampleRegionAttachment_dispose (Attachment* attachment) { + ExampleRegionAttachment* this = (ExampleRegionAttachment*)attachment; + _RegionAttachment_deinit(&this->super); + this->extraData = 0; + FREE(this) +} + +RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) { + ExampleRegionAttachment* this = calloc(1, sizeof(ExampleRegionAttachment)); + _RegionAttachment_init(&this->super, name); + this->extraData = 456; + this->super.super._dispose = _ExampleRegionAttachment_dispose; + return &this->super; +} + +/**/ + +typedef struct { + Skeleton super; + int extraData; +} ExampleSkeleton; + +void _ExampleSkeleton_dispose (Skeleton* skeleton) { + ExampleSkeleton* this = (ExampleSkeleton*)skeleton; + _Skeleton_deinit(&this->super); + this->extraData = 0; + FREE(this) +} + +Skeleton* Skeleton_create (SkeletonData* data) { + ExampleSkeleton* this = calloc(1, sizeof(ExampleSkeleton)); + _Skeleton_init(&this->super, data); + this->extraData = 789; + this->super._dispose = _ExampleSkeleton_dispose; + return &this->super; +} + +/**/ + int main (void) { - Attachment_setAttachmentLoader(loadAttachment); - - SkeletonJson_readSkeletonDataFile("data/spineboy-skeleton.json"); - if (SkeletonJson_getError()) printf("error: %s\n", SkeletonJson_getError()); - - SkeletonData *skeletonData = SkeletonData_create(); - Skeleton* skeleton = Skeleton_create(skeletonData); - printf("meow? %d\n", ((SfmlSkeleton*)skeleton)->meow); - Skeleton_dispose(skeleton); - printf("meow? %d\n", ((SfmlSkeleton*)skeleton)->meow); - Atlas* atlas = Atlas_readAtlasFile("data/spineboy.atlas"); - printf("%s %d", atlas->regions->name, atlas->regions->y); + printf("First page name: %s, extraData: %d\n", atlas->pages->name, ((ExampleAtlasPage*)atlas->pages)->extraData); + printf("First region name: %s, x: %d, y: %d\n", atlas->regions->name, atlas->regions->x, atlas->regions->y); + + SkeletonJson* json = SkeletonJson_create(atlas); + SkeletonData *skeletonData = SkeletonJson_readSkeletonDataFile(json, "data/spineboy-skeleton.json"); + if (!skeletonData) printf("error: %s\n", json->error); + printf("Attachment extraData: %d\n", ((ExampleRegionAttachment*)skeletonData->defaultSkin->entries->attachment)->extraData); + + Skeleton* skeleton = Skeleton_create(skeletonData); + printf("Skeleton extraData: %d\n", ((ExampleSkeleton*)skeleton)->extraData); + + Skeleton_dispose(skeleton); + SkeletonData_dispose(skeletonData); + SkeletonJson_dispose(json); + Atlas_dispose(atlas); return 0; } diff --git a/spine-c/src/spine/Animation.c b/spine-c/src/spine/Animation.c index fc95d8a3c..7239f35aa 100644 --- a/spine-c/src/spine/Animation.c +++ b/spine-c/src/spine/Animation.c @@ -1,4 +1,5 @@ #include +#include #include Animation* Animation_create () { @@ -14,14 +15,30 @@ void Animation_dispose (Animation* this) { FREE(this) } -void Animation_apply (const Animation* animation, Skeleton* skeleton, float time, int/*bool*/loop) { +void Animation_apply (const Animation* this, Skeleton* skeleton, float time, int/*bool*/loop) { + if (loop && this->duration) time = fmod(time, this->duration); + + int i, n = this->timelineCount; + for (i = 0; i < n; ++i) + Timeline_apply(this->timelines[i], skeleton, time, 1); } -void Animation_mix (const Animation* animation, Skeleton* skeleton, float time, int/*bool*/loop, float alpha) { +void Animation_mix (const Animation* this, Skeleton* skeleton, float time, int/*bool*/loop, float alpha) { + if (loop && this->duration) time = fmod(time, this->duration); + + int i, n = this->timelineCount; + for (i = 0; i < n; ++i) + Timeline_apply(this->timelines[i], skeleton, time, alpha); } /**/ +void _Timeline_init (Timeline* timeline) { +} + +void _Timeline_deinit (Timeline* timeline) { +} + void Timeline_dispose (Timeline* this) { this->_dispose(this); } @@ -37,10 +54,12 @@ static const float CURVE_STEPPED = -1; static const int CURVE_SEGMENTS = 10; void _CurveTimeline_init (CurveTimeline* this, int frameCount) { + _Timeline_init(&this->super); this->curves = calloc(1, sizeof(float) * (frameCount - 1) * 6); } void _CurveTimeline_deinit (CurveTimeline* this) { + _Timeline_deinit(&this->super); FREE(this->curves) } @@ -103,7 +122,7 @@ float CurveTimeline_getCurvePercent (CurveTimeline* this, int frameIndex, float return y + (1 - y) * (percent - x) / (1 - x); /* Last point is 1,1. */ } -/** @param target After the first and before the last entry. */ +/* @param target After the first and before the last entry. */ static int binarySearch (float *values, int valuesLength, float target, int step) { int low = 0; int high = valuesLength / step - 2; @@ -138,8 +157,10 @@ void _BaseTimeline_dispose (Timeline* timeline) { FREE(this); } +/* Many timelines have structure identical to struct BaseTimeline and extend CurveTimeline. **/ struct BaseTimeline* _BaseTimeline_create (int frameCount, int frameSize) { struct BaseTimeline* this = calloc(1, sizeof(struct BaseTimeline)); + _CurveTimeline_init(&this->super, frameCount); ((Timeline*)this)->_dispose = _BaseTimeline_dispose; CAST(int, this->frameCount) = frameCount; @@ -193,7 +214,6 @@ void _RotateTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float RotateTimeline* RotateTimeline_create (int frameCount) { RotateTimeline* this = _BaseTimeline_create(frameCount, 2); ((Timeline*)this)->_apply = _RotateTimeline_apply; - _CurveTimeline_init(&this->super, frameCount); return this; } @@ -239,7 +259,6 @@ void _TranslateTimeline_apply (const Timeline* timeline, Skeleton* skeleton, flo TranslateTimeline* TranslateTimeline_create (int frameCount) { TranslateTimeline* this = _BaseTimeline_create(frameCount, 3); ((Timeline*)this)->_apply = _TranslateTimeline_apply; - _CurveTimeline_init(&this->super, frameCount); return this; } @@ -281,7 +300,6 @@ void _ScaleTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float t ScaleTimeline* ScaleTimeline_create (int frameCount) { ScaleTimeline* this = _BaseTimeline_create(frameCount, 3); ((Timeline*)this)->_apply = _ScaleTimeline_apply; - _CurveTimeline_init(&this->super, frameCount); return this; } @@ -343,7 +361,6 @@ void _ColorTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float t ColorTimeline* ColorTimeline_create (int frameCount) { ColorTimeline* this = (ColorTimeline*)_BaseTimeline_create(frameCount, 5); ((Timeline*)this)->_apply = _ColorTimeline_apply; - _CurveTimeline_init(&this->super, frameCount); return this; } @@ -375,6 +392,7 @@ void _AttachmentTimeline_apply (const Timeline* timeline, Skeleton* skeleton, fl } void _AttachmentTimeline_dispose (Timeline* timeline) { + _Timeline_deinit(timeline); AttachmentTimeline* this = (AttachmentTimeline*)timeline; int i; @@ -382,14 +400,19 @@ void _AttachmentTimeline_dispose (Timeline* timeline) { FREE(this->attachmentNames[i]) FREE(this->attachmentNames) - _BaseTimeline_dispose(timeline); + FREE(this) } AttachmentTimeline* AttachmentTimeline_create (int frameCount) { - AttachmentTimeline* this = (AttachmentTimeline*)_BaseTimeline_create(frameCount, 1); + AttachmentTimeline* this = calloc(1, sizeof(AttachmentTimeline)); + _Timeline_init(&this->super); ((Timeline*)this)->_dispose = _AttachmentTimeline_dispose; ((Timeline*)this)->_apply = _AttachmentTimeline_apply; CAST(char*, this->attachmentNames) = calloc(1, sizeof(char*) * frameCount); + + CAST(int, this->frameCount) = frameCount; + CAST(float*, this->frames) = calloc(1, sizeof(float) * frameCount); + return this; } diff --git a/spine-c/src/spine/Animation.h b/spine-c/src/spine/Animation.h index a59167a6c..2b4a3a028 100644 --- a/spine-c/src/spine/Animation.h +++ b/spine-c/src/spine/Animation.h @@ -43,7 +43,7 @@ typedef struct { void CurveTimeline_setLinear (CurveTimeline* timeline, int frameIndex); void CurveTimeline_setStepped (CurveTimeline* timeline, int frameIndex); -/** Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next. +/* Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next. * cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of * the difference between the keyframe's values. */ void CurveTimeline_setCurve (CurveTimeline* timeline, int frameIndex, float cx1, float cy1, float cx2, float cy2); @@ -103,7 +103,7 @@ typedef struct { AttachmentTimeline* AttachmentTimeline_create (int frameCount); -/** @param attachmentName May be 0. */ +/* @param attachmentName May be 0. */ void AttachmentTimeline_setFrame (AttachmentTimeline* timeline, int frameIndex, float time, const char* attachmentName); #ifdef __cplusplus diff --git a/spine-c/src/spine/Atlas.c b/spine-c/src/spine/Atlas.c index 490dcd7c7..73ad9a022 100644 --- a/spine-c/src/spine/Atlas.c +++ b/spine-c/src/spine/Atlas.c @@ -1,16 +1,19 @@ #include #include #include +#include -AtlasPage* AtlasPage_create () { - AtlasPage* this = calloc(1, sizeof(AtlasPage)); - return this; +void _AtlasPage_init (AtlasPage* this, const char* name) { + this->name = name; /* name is guaranteed to be memory we allocated. */ +} + +void _AtlasPage_deinit (AtlasPage* this) { + FREE(this->name); } void AtlasPage_dispose (AtlasPage* this) { - if (this->next) AtlasPage_dispose(this->next); - FREE(this->name); - FREE(this); + if (this->next) AtlasPage_dispose(this->next); /* BOZO - Don't dispose all in the list. */ + this->_dispose(this); } /**/ @@ -45,7 +48,7 @@ static void trim (Str* str) { str->end++; } -/** Tokenize string without modification. Returns 0 on failure. */ +/* Tokenize string without modification. Returns 0 on failure. */ static int readLine (const char* data, Str* str) { static const char* nextStart; if (data) { @@ -67,7 +70,7 @@ static int readLine (const char* data, Str* str) { return 1; } -/** Moves str->begin past the first occurence of c. Returns 0 on failure. */ +/* Moves str->begin past the first occurence of c. Returns 0 on failure. */ static int beginPast (Str* str, char c) { const char* begin = str->begin; while (1) { @@ -88,7 +91,7 @@ static int readValue (Str* str) { return 1; } -/** Returns the number of tuple values read (2, 4, or 0 for failure). */ +/* Returns the number of tuple values read (2, 4, or 0 for failure). */ static int readTuple (Str tuple[]) { Str str; readLine(0, &str); @@ -150,15 +153,13 @@ Atlas* Atlas_readAtlas (const char* data) { if (str.end - str.begin == 0) { page = 0; } else if (!page) { - page = AtlasPage_create(); + page = AtlasPage_create(mallocString(&str)); if (lastPage) lastPage->next = page; else this->pages = page; lastPage = page; - page->name = mallocString(&str); - if (!readValue(&str)) return 0; page->format = (AtlasFormat)indexOf(formatNames, 7, &str); diff --git a/spine-c/src/spine/Atlas.h b/spine-c/src/spine/Atlas.h index 1e9089e71..a13e88c73 100644 --- a/spine-c/src/spine/Atlas.h +++ b/spine-c/src/spine/Atlas.h @@ -31,8 +31,15 @@ struct AtlasPage { AtlasFilter minFilter, magFilter; AtlasWrap uWrap, vWrap; AtlasPage* next; + + void (*_dispose) (AtlasPage* page); }; +AtlasPage* AtlasPage_create (const char* name); +void AtlasPage_dispose(AtlasPage * this); + +/**/ + typedef struct AtlasRegion AtlasRegion; struct AtlasRegion { const char* name; @@ -48,6 +55,11 @@ struct AtlasRegion { AtlasRegion* next; }; +AtlasRegion* AtlasRegion_create (); +void AtlasRegion_dispose(AtlasRegion * this); + +/**/ + typedef struct { AtlasPage* pages; AtlasRegion* regions; diff --git a/spine-c/src/spine/AtlasAttachmentLoader.c b/spine-c/src/spine/AtlasAttachmentLoader.c new file mode 100644 index 000000000..c827f3a3e --- /dev/null +++ b/spine-c/src/spine/AtlasAttachmentLoader.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include + +void _AtlasAttachmentLoader_dispose (AttachmentLoader* this) { + _AttachmentLoader_deinit(this); +} + +Attachment* _AtlasAttachmentLoader_newAttachment (AttachmentLoader* loader, AttachmentType type, const char* name) { + AtlasAttachmentLoader* this = (AtlasAttachmentLoader*)loader; + switch (type) { + case ATTACHMENT_REGION: { + AtlasRegion* region = Atlas_findRegion(this->atlas, name); + if (!region) return _AttachmentLoader_setError(loader, "Region not found: ", name); + return (Attachment*)RegionAttachment_create(name, region); + } + default: { + char buffer[16]; + sprintf((char*)loader->error2, "%d", type); + return _AttachmentLoader_setError(loader, "Unknown attachment type: ", buffer); + } + } +} + +AtlasAttachmentLoader* AtlasAttachmentLoader_create (Atlas* atlas) { + AtlasAttachmentLoader* this = calloc(1, sizeof(AtlasAttachmentLoader)); + this->atlas = atlas; + this->super._newAttachment = _AtlasAttachmentLoader_newAttachment; + this->super._dispose = _AtlasAttachmentLoader_dispose; + return this; +} diff --git a/spine-c/src/spine/AtlasAttachmentLoader.h b/spine-c/src/spine/AtlasAttachmentLoader.h new file mode 100644 index 000000000..5f51bfc67 --- /dev/null +++ b/spine-c/src/spine/AtlasAttachmentLoader.h @@ -0,0 +1,24 @@ +#ifndef SPINE_ATLASATTACHMENTLOADER_H_ +#define SPINE_ATLASATTACHMENTLOADER_H_ + +#include +#include + +#ifdef __cplusplus +namespace spine { +extern "C" { +#endif + +typedef struct { + AttachmentLoader super; + Atlas* atlas; +} AtlasAttachmentLoader; + +AtlasAttachmentLoader* AtlasAttachmentLoader_create (Atlas* atlas); + +#ifdef __cplusplus +} +} +#endif + +#endif /* SPINE_ATLASATTACHMENTLOADER_H_ */ diff --git a/spine-c/src/spine/Attachment.c b/spine-c/src/spine/Attachment.c index 03755e8ee..46e73fde1 100644 --- a/spine-c/src/spine/Attachment.c +++ b/spine-c/src/spine/Attachment.c @@ -1,22 +1,16 @@ #include #include -static AttachmentLoader loader; - -void Attachment_setAttachmentLoader (AttachmentLoader value) { - loader = value; -} - -AttachmentLoader Attachment_getAttachmentLoader () { - return loader; -} - -void Attachment_init (Attachment* this, const char* name) { +void _Attachment_init (Attachment* this, const char* name, int type) { MALLOC_STR(this->name, name); + this->type = type; +} + +void _Attachment_deinit (Attachment* this) { + FREE(this->name) + FREE(this) } void Attachment_dispose (Attachment* this) { this->_dispose(this); - FREE(this->name) - FREE(this) } diff --git a/spine-c/src/spine/Attachment.h b/spine-c/src/spine/Attachment.h index 5cf5322ce..1d27450b1 100644 --- a/spine-c/src/spine/Attachment.h +++ b/spine-c/src/spine/Attachment.h @@ -13,16 +13,11 @@ typedef enum { typedef struct Attachment Attachment; struct Attachment { const char* const name; + int type; void (*_dispose) (Attachment* attachment); }; -typedef Attachment* (*AttachmentLoader) (AttachmentType type, const char* name); - -void Attachment_setAttachmentLoader (AttachmentLoader loader); -AttachmentLoader Attachment_getAttachmentLoader (); - -void Attachment_init (Attachment* attachment, const char* name); void Attachment_dispose (Attachment* attachment); #ifdef __cplusplus diff --git a/spine-c/src/spine/AttachmentLoader.c b/spine-c/src/spine/AttachmentLoader.c new file mode 100644 index 000000000..93919dfdc --- /dev/null +++ b/spine-c/src/spine/AttachmentLoader.c @@ -0,0 +1,30 @@ +#include +#include + +void _AttachmentLoader_init (AttachmentLoader* this) { +} + +void _AttachmentLoader_deinit (AttachmentLoader* this) { + FREE(this->error1) + FREE(this->error2) +} + +void AttachmentLoader_dispose (AttachmentLoader* this) { + this->_dispose(this); +} + +Attachment* AttachmentLoader_newAttachment (AttachmentLoader* this, AttachmentType type, const char* name) { + FREE(this->error1) + FREE(this->error2) + this->error1 = 0; + this->error2 = 0; + return this->_newAttachment(this, type, name); +} + +void* _AttachmentLoader_setError (AttachmentLoader* this, const char* error1, const char* error2) { + FREE(this->error1) + FREE(this->error2) + MALLOC_STR(this->error1, error1) + MALLOC_STR(this->error2, error2) + return 0; +} diff --git a/spine-c/src/spine/AttachmentLoader.h b/spine-c/src/spine/AttachmentLoader.h new file mode 100644 index 000000000..3ea4f7dd1 --- /dev/null +++ b/spine-c/src/spine/AttachmentLoader.h @@ -0,0 +1,29 @@ +#ifndef SPINE_ATTACHMENTLOADER_H_ +#define SPINE_ATTACHMENTLOADER_H_ + +#include + +#ifdef __cplusplus +namespace spine { +extern "C" { +#endif + +typedef struct AttachmentLoader AttachmentLoader; +struct AttachmentLoader { + const char* error1; + const char* error2; + + Attachment* (*_newAttachment) (AttachmentLoader* loader, AttachmentType type, const char* name); + void (*_dispose) (AttachmentLoader* loader); +}; + +void AttachmentLoader_dispose (AttachmentLoader* loader); + +Attachment* AttachmentLoader_newAttachment (AttachmentLoader* loader, AttachmentType type, const char* name); + +#ifdef __cplusplus +} +} +#endif + +#endif /* SPINE_ATTACHMENTLOADER_H_ */ diff --git a/spine-c/src/spine/Bone.h b/spine-c/src/spine/Bone.h index 71cf744a8..65fdca8d3 100644 --- a/spine-c/src/spine/Bone.h +++ b/spine-c/src/spine/Bone.h @@ -24,7 +24,7 @@ struct Bone { void Bone_setYDown (int/*bool*/yDown); -/** @param parent May be zero. */ +/* @param parent May be zero. */ Bone* Bone_create (BoneData* data, Bone* parent); void Bone_dispose (Bone* bone); diff --git a/spine-c/src/spine/RegionAttachment.c b/spine-c/src/spine/RegionAttachment.c index 79ff08ca8..56761deb5 100644 --- a/spine-c/src/spine/RegionAttachment.c +++ b/spine-c/src/spine/RegionAttachment.c @@ -1,11 +1,16 @@ #include #include #include +#include void _RegionAttachment_init (RegionAttachment* this, const char* name) { - Attachment_init(&this->super, name); this->scaleX = 1; this->scaleY = 1; + _Attachment_init(&this->super, name, ATTACHMENT_REGION); +} + +void _RegionAttachment_deinit (RegionAttachment* this) { + _Attachment_deinit(&this->super); } void RegionAttachment_updateOffset (RegionAttachment* this) { @@ -18,16 +23,16 @@ void RegionAttachment_updateOffset (RegionAttachment* this) { localX2 *= this->scaleX; localY2 *= this->scaleY; float radians = (float)(this->rotation * 3.1415926535897932385 / 180); - float cos = cosf(radians); - float sin = sinf(radians); - float localXCos = localX * cos + this->x; - float localXSin = localX * sin; - float localYCos = localY * cos + this->y; - float localYSin = localY * sin; - float localX2Cos = localX2 * cos + this->x; - float localX2Sin = localX2 * sin; - float localY2Cos = localY2 * cos + this->y; - float localY2Sin = localY2 * sin; + float cosine = cos(radians); + float sine = sin(radians); + float localXCos = localX * cosine + this->x; + float localXSin = localX * sine; + float localYCos = localY * cosine + this->y; + float localYSin = localY * sine; + float localX2Cos = localX2 * cosine + this->x; + float localX2Sin = localX2 * sine; + float localY2Cos = localY2 * cosine + this->y; + float localY2Sin = localY2 * sine; this->offset[0] = localXCos - localYSin; this->offset[1] = localYCos + localXSin; this->offset[2] = localXCos - localY2Sin; diff --git a/spine-c/src/spine/RegionAttachment.h b/spine-c/src/spine/RegionAttachment.h index fb2347a02..1689fe051 100644 --- a/spine-c/src/spine/RegionAttachment.h +++ b/spine-c/src/spine/RegionAttachment.h @@ -2,6 +2,7 @@ #define SPINE_REGIONATTACHMENT_H_ #include +#include #ifdef __cplusplus namespace spine { @@ -17,6 +18,8 @@ struct RegionAttachment { void RegionAttachment_updateOffset (RegionAttachment* attachment); +RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region); + #ifdef __cplusplus } } diff --git a/spine-c/src/spine/Skeleton.c b/spine-c/src/spine/Skeleton.c index 527240071..f5e29406c 100644 --- a/spine-c/src/spine/Skeleton.c +++ b/spine-c/src/spine/Skeleton.c @@ -43,9 +43,7 @@ void _Skeleton_init (Skeleton* this, SkeletonData* data) { memcpy(this->drawOrder, this->slots, sizeof(Slot*) * this->slotCount); } -void Skeleton_dispose (Skeleton* this) { - if (this->_dispose) this->_dispose(this); - +void _Skeleton_deinit (Skeleton* this) { int i; for (i = 0; i < this->boneCount; ++i) Bone_dispose(this->bones[i]); @@ -56,8 +54,10 @@ void Skeleton_dispose (Skeleton* this) { FREE(this->slots) FREE(this->drawOrder) +} - FREE(this) +void Skeleton_dispose (Skeleton* this) { + this->_dispose(this); } void Skeleton_updateWorldTransform (const Skeleton* this) { diff --git a/spine-c/src/spine/Skeleton.h b/spine-c/src/spine/Skeleton.h index 269bd9aa3..84c1b38b7 100644 --- a/spine-c/src/spine/Skeleton.h +++ b/spine-c/src/spine/Skeleton.h @@ -29,6 +29,7 @@ struct Skeleton { void (*_dispose) (Skeleton* skeleton); }; +Skeleton* Skeleton_create (SkeletonData* data); void Skeleton_dispose (Skeleton* skeleton); void Skeleton_updateWorldTransform (const Skeleton* skeleton); @@ -38,26 +39,26 @@ void Skeleton_setBonesToBindPose (const Skeleton* skeleton); void Skeleton_setSlotsToBindPose (const Skeleton* skeleton); Bone* Skeleton_getRootBone (const Skeleton* skeleton); -/** Returns 0 if the bone could not be found. */ +/* Returns 0 if the bone could not be found. */ Bone* Skeleton_findBone (const Skeleton* skeleton, const char* boneName); -/** Returns -1 if the bone could not be found. */ +/* Returns -1 if the bone could not be found. */ int Skeleton_findBoneIndex (const Skeleton* skeleton, const char* boneName); -/** Returns 0 if the slot could not be found. */ +/* Returns 0 if the slot could not be found. */ Slot* Skeleton_findSlot (const Skeleton* skeleton, const char* slotName); -/** Returns -1 if the slot could not be found. */ +/* Returns -1 if the slot could not be found. */ int Skeleton_findSlotIndex (const Skeleton* skeleton, const char* slotName); -/** Returns 0 if the skin could not be found. */ +/* Returns 0 if the skin could not be found. */ int Skeleton_setSkinByName (Skeleton* skeleton, const char* skinName); -/** @param skin May be 0.*/ +/* @param skin May be 0.*/ void Skeleton_setSkin (Skeleton* skeleton, Skin* skin); -/** Returns 0 if the slot or attachment could not be found. */ +/* Returns 0 if the slot or attachment could not be found. */ Attachment* Skeleton_getAttachmentForSlotName (const Skeleton* skeleton, const char* slotName, const char* attachmentName); -/** Returns 0 if the slot or attachment could not be found. */ +/* Returns 0 if the slot or attachment could not be found. */ Attachment* Skeleton_getAttachmentForSlotIndex (const Skeleton* skeleton, int slotIndex, const char* attachmentName); -/** Returns 0 if the slot or attachment could not be found. */ +/* Returns 0 if the slot or attachment could not be found. */ int Skeleton_setAttachment (Skeleton* skeleton, const char* slotName, const char* attachmentName); void Skeleton_update (Skeleton* skeleton, float deltaTime); diff --git a/spine-c/src/spine/SkeletonJson.c b/spine-c/src/spine/SkeletonJson.c index 77e49b909..48f92f634 100644 --- a/spine-c/src/spine/SkeletonJson.c +++ b/spine-c/src/spine/SkeletonJson.c @@ -1,33 +1,47 @@ #include #include +#include #include #include #include +#include -#include +typedef struct { + SkeletonJson json; + int ownsLoader; +} Private; -static float scale; -static const char* error; - -void SkeletonJson_setScale (float value) { - scale = value; +SkeletonJson* SkeletonJson_createWithLoader (AttachmentLoader* attachmentLoader) { + SkeletonJson* this = calloc(1, sizeof(Private)); + this->scale = 1; + this->attachmentLoader = attachmentLoader; + return this; } -void* SkeletonJson_setError (cJSON* root, const char* value1, const char* value2) { - FREE(error) +SkeletonJson* SkeletonJson_create (Atlas* atlas) { + AtlasAttachmentLoader* attachmentLoader = AtlasAttachmentLoader_create(atlas); + Private* this = (Private*)SkeletonJson_createWithLoader(&attachmentLoader->super); + this->ownsLoader = 1; + return &this->json; +} + +void SkeletonJson_dispose (SkeletonJson* this) { + if (((Private*)this)->ownsLoader) AttachmentLoader_dispose(this->attachmentLoader); + FREE(this->error) + FREE(this) +} + +void* _SkeletonJson_setError (SkeletonJson* this, cJSON* root, const char* value1, const char* value2) { + FREE(this->error) char message[256]; strcpy(message, value1); int length = strlen(value1); if (value2) strncat(message + length, value2, 256 - length); - MALLOC_STR(error, message) + MALLOC_STR(this->error, message) if (root) cJSON_dispose(root); return 0; } -const char* SkeletonJson_getError () { - return error; -} - static float toColor (const char* value, int index) { if (strlen(value) != 8) return -1; value += index * 2; @@ -41,20 +55,20 @@ static float toColor (const char* value, int index) { return color / (float)255; } -SkeletonData* SkeletonJson_readSkeletonDataFile (const char* path) { +SkeletonData* SkeletonJson_readSkeletonDataFile (SkeletonJson* this, const char* path) { const char* data = readFile(path); - if (!data) return SkeletonJson_setError(0, "Unable to read file: ", path); - SkeletonData* skeletonData = SkeletonJson_readSkeletonData(data); + if (!data) return _SkeletonJson_setError(this, 0, "Unable to read file: ", path); + SkeletonData* skeletonData = SkeletonJson_readSkeletonData(this, data); FREE(data) return skeletonData; } -SkeletonData* SkeletonJson_readSkeletonData (const char* json) { - FREE(error) - error = 0; +SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* this, const char* json) { + FREE(this->error) + CAST(char*, this->error) = 0; cJSON* root = cJSON_Parse(json); - if (!root) return SkeletonJson_setError(0, "Invalid JSON: ", cJSON_GetErrorPtr()); + if (!root) return _SkeletonJson_setError(this, 0, "Invalid JSON: ", cJSON_GetErrorPtr()); SkeletonData* skeletonData = SkeletonData_create(); int i, ii, iii; @@ -71,13 +85,13 @@ SkeletonData* SkeletonJson_readSkeletonData (const char* json) { const char* parentName = cJSON_GetObjectString(boneMap, "parent", 0); if (parentName) { parent = SkeletonData_findBone(skeletonData, parentName); - if (!parent) return SkeletonJson_setError(root, "Parent bone not found: ", parentName); + if (!parent) return _SkeletonJson_setError(this, root, "Parent bone not found: ", parentName); } BoneData* boneData = BoneData_create(boneName, parent); - boneData->length = cJSON_GetObjectFloat(boneMap, "parent", 0) * scale; - boneData->x = cJSON_GetObjectFloat(boneMap, "x", 0) * scale; - boneData->y = cJSON_GetObjectFloat(boneMap, "y", 0) * scale; + boneData->length = cJSON_GetObjectFloat(boneMap, "parent", 0) * this->scale; + boneData->x = cJSON_GetObjectFloat(boneMap, "x", 0) * this->scale; + boneData->y = cJSON_GetObjectFloat(boneMap, "y", 0) * this->scale; boneData->rotation = cJSON_GetObjectFloat(boneMap, "rotation", 0); boneData->scaleX = cJSON_GetObjectFloat(boneMap, "scaleX", 1); boneData->scaleY = cJSON_GetObjectFloat(boneMap, "scaleY", 1); @@ -97,7 +111,7 @@ SkeletonData* SkeletonJson_readSkeletonData (const char* json) { const char* boneName = cJSON_GetObjectString(slotMap, "bone", 0); BoneData* boneData = SkeletonData_findBone(skeletonData, boneName); - if (!boneData) return SkeletonJson_setError(root, "Slot bone not found: ", boneName); + if (!boneData) return _SkeletonJson_setError(this, root, "Slot bone not found: ", boneName); SlotData* slotData = SlotData_create(slotName, boneData); @@ -138,7 +152,8 @@ SkeletonData* SkeletonJson_readSkeletonData (const char* json) { int attachmentCount = cJSON_GetArraySize(attachmentsMap); for (iii = 0; iii < attachmentCount; ++iii) { cJSON* attachmentMap = cJSON_GetArrayItem(attachmentsMap, iii); - const char* attachmentName = attachmentMap->name; + const char* skinAttachmentName = attachmentMap->name; + const char* attachmentName = cJSON_GetObjectString(attachmentMap, "name", skinAttachmentName); const char* typeString = cJSON_GetObjectString(attachmentMap, "type", "region"); AttachmentType type; @@ -147,24 +162,25 @@ SkeletonData* SkeletonJson_readSkeletonData (const char* json) { else if (strcmp(typeString, "regionSequence") == 0) type = ATTACHMENT_REGION_SEQUENCE; else - return SkeletonJson_setError(root, "Unknown attachment type: ", typeString); + return _SkeletonJson_setError(this, root, "Unknown attachment type: ", typeString); - Attachment* attachment = Attachment_getAttachmentLoader()(type, - cJSON_GetObjectString(attachmentMap, "name", attachmentName)); + Attachment* attachment = AttachmentLoader_newAttachment(this->attachmentLoader, type, attachmentName); + if (!attachment && this->attachmentLoader->error1) + return _SkeletonJson_setError(this, root, this->attachmentLoader->error1, this->attachmentLoader->error2); - if (type == ATTACHMENT_REGION || type == ATTACHMENT_REGION_SEQUENCE) { + if (attachment->type == ATTACHMENT_REGION || attachment->type == ATTACHMENT_REGION_SEQUENCE) { RegionAttachment* regionAttachment = (RegionAttachment*)attachment; - regionAttachment->x = cJSON_GetObjectFloat(attachmentMap, "x", 0) * scale; - regionAttachment->y = cJSON_GetObjectFloat(attachmentMap, "y", 0) * scale; + regionAttachment->x = cJSON_GetObjectFloat(attachmentMap, "x", 0) * this->scale; + regionAttachment->y = cJSON_GetObjectFloat(attachmentMap, "y", 0) * this->scale; regionAttachment->scaleX = cJSON_GetObjectFloat(attachmentMap, "scaleX", 1); regionAttachment->scaleY = cJSON_GetObjectFloat(attachmentMap, "scaleY", 1); regionAttachment->rotation = cJSON_GetObjectFloat(attachmentMap, "rotation", 0); - regionAttachment->width = cJSON_GetObjectFloat(attachmentMap, "width", 32) * scale; - regionAttachment->height = cJSON_GetObjectFloat(attachmentMap, "height", 32) * scale; + regionAttachment->width = cJSON_GetObjectFloat(attachmentMap, "width", 32) * this->scale; + regionAttachment->height = cJSON_GetObjectFloat(attachmentMap, "height", 32) * this->scale; RegionAttachment_updateOffset(regionAttachment); } - Skin_addAttachment(skin, slotIndex, attachmentName, attachment); + Skin_addAttachment(skin, slotIndex, skinAttachmentName, attachment); } } } diff --git a/spine-c/src/spine/SkeletonJson.h b/spine-c/src/spine/SkeletonJson.h index 477ffd8e7..19e04389f 100644 --- a/spine-c/src/spine/SkeletonJson.h +++ b/spine-c/src/spine/SkeletonJson.h @@ -2,21 +2,29 @@ #define SPINE_SKELETONJSON_H_ #include +#include #include +#include #ifdef __cplusplus namespace spine { extern "C" { #endif -void SkeletonJson_setScale (float scale); +typedef struct { + float scale; + AttachmentLoader* attachmentLoader; + const char* const error; +} SkeletonJson; -SkeletonData* SkeletonJson_readSkeletonData (const char* json); -SkeletonData* SkeletonJson_readSkeletonDataFile (const char* path); +SkeletonJson* SkeletonJson_createWithLoader (AttachmentLoader* attachmentLoader); +SkeletonJson* SkeletonJson_create (Atlas* atlas); +void SkeletonJson_dispose (SkeletonJson* skeletonJson); -/* Animation* readAnimation (char* json, const SkeletonData *skeletonData) const; */ +SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* skeletonJson, const char* json); +SkeletonData* SkeletonJson_readSkeletonDataFile (SkeletonJson* skeletonJson, const char* path); -const char* SkeletonJson_getError (); +/* Animation* SkeletonJson_readAnimation (SkeletonJson* skeletonJson, char* json, const SkeletonData *skeletonData); */ #ifdef __cplusplus } diff --git a/spine-c/src/spine/Skin.c b/spine-c/src/spine/Skin.c index bc2605928..50e42dd47 100644 --- a/spine-c/src/spine/Skin.c +++ b/spine-c/src/spine/Skin.c @@ -34,7 +34,7 @@ void Skin_addAttachment (Skin* this, int slotIndex, const char* name, Attachment SkinEntry* newEntry = _SkinEntry_create(slotIndex, name, attachment); SkinEntry* entry = (SkinEntry*)this->entries; if (!entry) - entry = newEntry; + CAST(SkinEntry*, this->entries) = newEntry; else { while (entry->next) entry = (SkinEntry*)entry->next; diff --git a/spine-c/src/spine/Skin.h b/spine-c/src/spine/Skin.h index 5f192a22c..29cd63d7c 100644 --- a/spine-c/src/spine/Skin.h +++ b/spine-c/src/spine/Skin.h @@ -24,9 +24,9 @@ typedef struct { Skin* Skin_create (const char* name); void Skin_dispose (Skin* skin); -/** The Skin owns the attachment. */ +/* The Skin owns the attachment. */ void Skin_addAttachment (Skin* skin, int slotIndex, const char* name, Attachment* attachment); -/** May return null. */ +/* May return null. */ Attachment* Skin_getAttachment (const Skin* skin, int slotIndex, const char* name); #ifdef __cplusplus diff --git a/spine-c/src/spine/Slot.c b/spine-c/src/spine/Slot.c index 692c78f75..085bf625b 100644 --- a/spine-c/src/spine/Slot.c +++ b/spine-c/src/spine/Slot.c @@ -24,7 +24,7 @@ void Slot_dispose (Slot* this) { FREE(this); } -/** @param attachment May be null. */ +/* @param attachment May be null. */ void Slot_setAttachment (Slot* this, Attachment* attachment) { CAST(Attachment*, this->attachment) = attachment; ((Private*)this)->attachmentTime = this->skeleton->time; diff --git a/spine-c/src/spine/Slot.h b/spine-c/src/spine/Slot.h index d6c50502f..6dc703a8d 100644 --- a/spine-c/src/spine/Slot.h +++ b/spine-c/src/spine/Slot.h @@ -23,7 +23,7 @@ typedef struct { Slot* Slot_create (SlotData* data, struct Skeleton* skeleton, Bone* bone); void Slot_dispose (Slot* slot); -/** @param attachment May be null. */ +/* @param attachment May be null. */ void Slot_setAttachment (Slot* slot, Attachment* attachment); void Slot_setAttachmentTime (Slot* slot, float time); diff --git a/spine-c/src/spine/SlotData.h b/spine-c/src/spine/SlotData.h index d5225bdc0..d2ceff98b 100644 --- a/spine-c/src/spine/SlotData.h +++ b/spine-c/src/spine/SlotData.h @@ -18,7 +18,7 @@ typedef struct { SlotData* SlotData_create (const char* name, BoneData* boneData); void SlotData_dispose (SlotData* slotData); -/** @param attachmentName May be zero. */ +/* @param attachmentName May be zero. */ void SlotData_setAttachmentName (SlotData* slotData, const char* attachmentName); #ifdef __cplusplus diff --git a/spine-c/src/spine/cJSON.c b/spine-c/src/spine/cJSON.c index 7e42c047c..f77183673 100644 --- a/spine-c/src/spine/cJSON.c +++ b/spine-c/src/spine/cJSON.c @@ -48,9 +48,7 @@ static int cJSON_strcasecmp (const char* s1, const char* s2) { /* Internal constructor. */ static cJSON *cJSON_create_Item (void) { - cJSON* node = (cJSON*)malloc(sizeof(cJSON)); - if (node) memset(node, 0, sizeof(cJSON)); - return node; + return (cJSON*)calloc(1, sizeof(cJSON)); } /* Delete a cJSON structure. */ diff --git a/spine-c/src/spine/extension.h b/spine-c/src/spine/extension.h new file mode 100644 index 000000000..59463f162 --- /dev/null +++ b/spine-c/src/spine/extension.h @@ -0,0 +1,52 @@ +#ifndef SPINE_EXTENSION_H_ +#define SPINE_EXTENSION_H_ + +#ifdef __cplusplus +namespace spine { +extern "C" { +#endif + +#include +#include +#include +#include +#include + +/* Methods that must be implemented: **/ + +Skeleton* Skeleton_create (SkeletonData* data); + +RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region); + +AtlasPage* AtlasPage_create (const char* name); + +/* Internal methods needed for extension: **/ + +void _Skeleton_init (Skeleton* skeleton, SkeletonData* data); +void _Skeleton_deinit (Skeleton* skeleton); + +void _Attachment_init (Attachment* attachment, const char* name, AttachmentType type); +void _Attachment_deinit (Attachment* attachment); + +void _RegionAttachment_init (RegionAttachment* attachment, const char* name); +void _RegionAttachment_deinit (RegionAttachment* attachment); + +void _Timeline_init (Timeline* timeline); +void _Timeline_deinit (Timeline* timeline); + +void _CurveTimeline_init (CurveTimeline* timeline, int frameCount); +void _CurveTimeline_deinit (CurveTimeline* timeline); + +void _AtlasPage_init (AtlasPage* page, const char* name); +void _AtlasPage_deinit (AtlasPage* page); + +void _AttachmentLoader_init (AttachmentLoader* loader); +void _AttachmentLoader_deinit (AttachmentLoader* loader); +void* _AttachmentLoader_setError (AttachmentLoader* loader, const char* error1, const char* error2); + +#ifdef __cplusplus +} +} +#endif + +#endif /* SPINE_EXTENSION_H_ */ diff --git a/spine-c/src/spine/util.h b/spine-c/src/spine/util.h index 7135a024d..dac623d27 100644 --- a/spine-c/src/spine/util.h +++ b/spine-c/src/spine/util.h @@ -4,7 +4,7 @@ #include #include -/** Used to cast away const on an lvalue. */ +/* Used to cast away const on an lvalue. */ #define CAST(TYPE,VALUE) *(TYPE*)&VALUE #define MALLOC_STR(TO,FROM) strcpy(CAST(char*, TO) = malloc(strlen(FROM)), FROM);