diff --git a/spine-c/include/spine/Atlas.h b/spine-c/include/spine/Atlas.h index 14e8175fd..18c9f884e 100644 --- a/spine-c/include/spine/Atlas.h +++ b/spine-c/include/spine/Atlas.h @@ -32,17 +32,17 @@ extern "C" { #endif typedef enum { - ATLAS_ALPHA, ATLAS_INTENSITY, ATLAS_LUMINANCEALPHA, ATLAS_RGB565, ATLAS_RGBA4444, ATLAS_RGB888, ATLAS_RGBA8888 + ATLAS_ALPHA, ATLAS_INTENSITY, ATLAS_LUMINANCE_ALPHA, ATLAS_RGB565, ATLAS_RGBA4444, ATLAS_RGB888, ATLAS_RGBA8888 } AtlasFormat; typedef enum { ATLAS_NEAREST, ATLAS_LINEAR, ATLAS_MIPMAP, - ATLAS_MIPMAPNEARESTNEAREST, - ATLAS_MIPMAPLINEARNEAREST, - ATLAS_MIPMAPNEARESTLINEAR, - ATLAS_MIPMAPLINEARLINEAR + ATLAS_MIPMAP_NEAREST_NEAREST, + ATLAS_MIPMAP_LINEAR_NEAREST, + ATLAS_MIPMAP_NEAREST_LINEAR, + ATLAS_MIPMAP_LINEAR_LINEAR } AtlasFilter; typedef enum { @@ -94,6 +94,7 @@ Atlas* Atlas_readAtlas (const char* data); Atlas* Atlas_readAtlasFile (const char* path); void Atlas_free (Atlas* atlas); +/* Returns 0 if the region was not found. */ AtlasRegion* Atlas_findRegion (const Atlas* atlas, const char* name); #ifdef __cplusplus diff --git a/spine-c/include/spine/Attachment.h b/spine-c/include/spine/Attachment.h index 041280d16..4e7180f76 100644 --- a/spine-c/include/spine/Attachment.h +++ b/spine-c/include/spine/Attachment.h @@ -40,7 +40,7 @@ typedef enum { typedef struct Attachment Attachment; struct Attachment { const char* const name; - int type; + AttachmentType type; const void* const vtable; }; diff --git a/spine-c/include/spine/AttachmentLoader.h b/spine-c/include/spine/AttachmentLoader.h index ab49b44c8..500d6d930 100644 --- a/spine-c/include/spine/AttachmentLoader.h +++ b/spine-c/include/spine/AttachmentLoader.h @@ -43,6 +43,7 @@ struct AttachmentLoader { void AttachmentLoader_free (AttachmentLoader* loader); +/* Returns 0 to not load an attachment. If 0 is returned and AttachmentLoader.error1 is set, an error occurred. */ Attachment* AttachmentLoader_newAttachment (AttachmentLoader* loader, AttachmentType type, const char* name); #ifdef __cplusplus diff --git a/spine-c/include/spine/Bone.h b/spine-c/include/spine/Bone.h index fff25013e..e3ce345a8 100644 --- a/spine-c/include/spine/Bone.h +++ b/spine-c/include/spine/Bone.h @@ -49,7 +49,7 @@ struct Bone { void Bone_setYDown (int/*bool*/yDown); -/* @param parent May be zero. */ +/* @param parent May be 0. */ Bone* Bone_new (BoneData* data, Bone* parent); void Bone_free (Bone* bone); diff --git a/spine-c/include/spine/RegionAttachment.h b/spine-c/include/spine/RegionAttachment.h index 438ecda1e..3ceb798a0 100644 --- a/spine-c/include/spine/RegionAttachment.h +++ b/spine-c/include/spine/RegionAttachment.h @@ -41,10 +41,10 @@ struct RegionAttachment { float offset[8]; }; -void RegionAttachment_updateOffset (RegionAttachment* attachment); - RegionAttachment* RegionAttachment_new (const char* name, AtlasRegion* region); +void RegionAttachment_updateOffset (RegionAttachment* attachment); + #ifdef __cplusplus } } diff --git a/spine-c/include/spine/Skeleton.h b/spine-c/include/spine/Skeleton.h index 4206a224b..d819dd5b3 100644 --- a/spine-c/include/spine/Skeleton.h +++ b/spine-c/include/spine/Skeleton.h @@ -64,26 +64,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 was not found. */ Bone* Skeleton_findBone (const Skeleton* skeleton, const char* boneName); -/* Returns -1 if the bone could not be found. */ +/* Returns -1 if the bone was not found. */ int Skeleton_findBoneIndex (const Skeleton* skeleton, const char* boneName); -/* Returns 0 if the slot could not be found. */ +/* Returns 0 if the slot was not found. */ Slot* Skeleton_findSlot (const Skeleton* skeleton, const char* slotName); -/* Returns -1 if the slot could not be found. */ +/* Returns -1 if the slot was not found. */ int Skeleton_findSlotIndex (const Skeleton* skeleton, const char* slotName); -/* Returns 0 if the skin could not be found. */ +/* Returns 0 if the skin was not found. */ int Skeleton_setSkinByName (Skeleton* skeleton, const char* skinName); /* @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 was not 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 was not 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 was not found. */ int Skeleton_setAttachment (Skeleton* skeleton, const char* slotName, const char* attachmentName); void Skeleton_update (Skeleton* skeleton, float deltaTime); diff --git a/spine-c/include/spine/Skin.h b/spine-c/include/spine/Skin.h index 5327a8a83..b7eb7b762 100644 --- a/spine-c/include/spine/Skin.h +++ b/spine-c/include/spine/Skin.h @@ -51,7 +51,7 @@ void Skin_free (Skin* skin); /* The Skin owns the attachment. */ void Skin_addAttachment (Skin* skin, int slotIndex, const char* name, Attachment* attachment); -/* May return null. */ +/* Returns 0 if the attachment was not found. */ Attachment* Skin_getAttachment (const Skin* skin, int slotIndex, const char* name); #ifdef __cplusplus diff --git a/spine-c/include/spine/Slot.h b/spine-c/include/spine/Slot.h index 1c28151ed..3e4098015 100644 --- a/spine-c/include/spine/Slot.h +++ b/spine-c/include/spine/Slot.h @@ -48,7 +48,7 @@ typedef struct Slot { Slot* Slot_new (SlotData* data, struct Skeleton* skeleton, Bone* bone); void Slot_free (Slot* slot); -/* @param attachment May be null. */ +/* @param attachment May be 0 to clear the attachment for the slot. */ void Slot_setAttachment (Slot* slot, Attachment* attachment); void Slot_setAttachmentTime (Slot* slot, float time); diff --git a/spine-c/include/spine/SlotData.h b/spine-c/include/spine/SlotData.h index 7b4a3d142..608c0c196 100644 --- a/spine-c/include/spine/SlotData.h +++ b/spine-c/include/spine/SlotData.h @@ -43,7 +43,7 @@ typedef struct { SlotData* SlotData_new (const char* name, BoneData* boneData); void SlotData_free (SlotData* slotData); -/* @param attachmentName May be zero. */ +/* @param attachmentName May be 0 for no bind pose attachment. */ void SlotData_setAttachmentName (SlotData* slotData, const char* attachmentName); #ifdef __cplusplus diff --git a/spine-c/include/spine/extension.h b/spine-c/include/spine/extension.h index b9c92cacb..75e149e5e 100644 --- a/spine-c/include/spine/extension.h +++ b/spine-c/include/spine/extension.h @@ -45,7 +45,7 @@ expose a vtable. - The public API hides implementation details such as vtable structs and init/deinit functions. An internal API is exposed in - extension.h to allow classes to be extended. + extension.h to allow classes to be extended. Internal structs and functions begin with underscore (_). - OOP in C tends to lose type safety. Macros are provided in extension.h to give more context about why a cast is being done. */ @@ -70,7 +70,7 @@ /* Casts away const. Can be used as an lvalue. Not type safe, use with care. */ #define CONST_CAST(TYPE,VALUE) (*(TYPE*)&VALUE) -/* Gets the vtable for the specified type. Can be used as an lvalue. */ +/* Gets the vtable for the specified type. Not type safe, use with care. */ #define VTABLE(TYPE,VALUE) ((_##TYPE##Vtable*)((TYPE*)VALUE)->vtable) /* Frees memory. Can be used on const. */ diff --git a/spine-c/src/spine/Atlas.c b/spine-c/src/spine/Atlas.c index f317301db..5263e02f8 100644 --- a/spine-c/src/spine/Atlas.c +++ b/spine-c/src/spine/Atlas.c @@ -39,7 +39,6 @@ void _AtlasPage_deinit (AtlasPage* self) { } void AtlasPage_free (AtlasPage* self) { - if (self->next) AtlasPage_free(self->next); /* BOZO - Don't dispose all in the list. */ VTABLE(AtlasPage, self) ->free(self); } @@ -50,7 +49,6 @@ AtlasRegion* AtlasRegion_new () { } void AtlasRegion_free (AtlasRegion* self) { - if (self->next) AtlasRegion_free(self->next); FREE(self->name); FREE(self->splits); FREE(self->pads); @@ -162,6 +160,11 @@ static int toInt (Str* str) { return strtol(str->begin, (char**)&str->end, 10); } +static Atlas* abort (Atlas* self) { + Atlas_free(self); + return 0; +} + static const char* formatNames[] = {"Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888", "RGBA8888"}; static const char* textureFilterNames[] = {"Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest", "MipMapNearestLinear", "MipMapLinearLinear"}; @@ -186,14 +189,14 @@ Atlas* Atlas_readAtlas (const char* data) { self->pages = page; lastPage = page; - if (!readValue(&str)) return 0; + if (!readValue(&str)) return abort(self); page->format = (AtlasFormat)indexOf(formatNames, 7, &str); - if (!readTuple(tuple)) return 0; + if (!readTuple(tuple)) return abort(self); page->minFilter = (AtlasFilter)indexOf(textureFilterNames, 7, tuple); page->magFilter = (AtlasFilter)indexOf(textureFilterNames, 7, tuple + 1); - if (!readValue(&str)) return 0; + if (!readValue(&str)) return abort(self); if (!equals(&str, "none")) { page->uWrap = *str.begin == 'x' ? ATLAS_REPEAT : (*str.begin == 'y' ? ATLAS_CLAMPTOEDGE : ATLAS_REPEAT); page->vWrap = *str.begin == 'x' ? ATLAS_CLAMPTOEDGE : (*str.begin == 'y' ? ATLAS_REPEAT : ATLAS_REPEAT); @@ -209,19 +212,19 @@ Atlas* Atlas_readAtlas (const char* data) { region->page = page; region->name = mallocString(&str); - if (!readValue(&str)) return 0; + if (!readValue(&str)) return abort(self); region->rotate = equals(&str, "true"); - if (readTuple(tuple) != 2) return 0; + if (readTuple(tuple) != 2) return abort(self); region->x = toInt(tuple); region->y = toInt(tuple + 1); - if (readTuple(tuple) != 2) return 0; + if (readTuple(tuple) != 2) return abort(self); region->width = toInt(tuple); region->height = toInt(tuple + 1); int count; - if (!(count = readTuple(tuple))) return 0; + if (!(count = readTuple(tuple))) return abort(self); if (count == 4) { /* split is optional */ region->splits = MALLOC(int, 4); region->splits[0] = toInt(tuple); @@ -229,7 +232,7 @@ Atlas* Atlas_readAtlas (const char* data) { region->splits[2] = toInt(tuple + 2); region->splits[3] = toInt(tuple + 3); - if (!(count = readTuple(tuple))) return 0; + if (!(count = readTuple(tuple))) return abort(self); if (count == 4) { /* pad is optional, but only present with splits */ region->pads = MALLOC(int, 4); region->pads[0] = toInt(tuple); @@ -237,7 +240,7 @@ Atlas* Atlas_readAtlas (const char* data) { region->pads[2] = toInt(tuple + 2); region->pads[3] = toInt(tuple + 3); - if (!readTuple(tuple)) return 0; + if (!readTuple(tuple)) return abort(self); } } @@ -248,7 +251,7 @@ Atlas* Atlas_readAtlas (const char* data) { region->offsetX = (float)toInt(tuple); region->offsetY = (float)toInt(tuple + 1); - if (!readValue(&str)) return 0; + if (!readValue(&str)) return abort(self); region->index = toInt(&str); } } @@ -265,8 +268,20 @@ Atlas* Atlas_readAtlasFile (const char* path) { } void Atlas_free (Atlas* self) { - if (self->pages) AtlasPage_free(self->pages); - if (self->regions) AtlasRegion_free(self->regions); + AtlasPage* page = self->pages; + while (page) { + AtlasPage* nextPage = page->next; + AtlasPage_free(page); + page = nextPage; + } + + AtlasRegion* region = self->regions; + while (region) { + AtlasRegion* nextRegion = region->next; + AtlasRegion_free(region); + region = nextRegion; + } + FREE(self); } diff --git a/spine-c/src/spine/SkeletonJson.c b/spine-c/src/spine/SkeletonJson.c index b96c0fabd..ec2437e9c 100644 --- a/spine-c/src/spine/SkeletonJson.c +++ b/spine-c/src/spine/SkeletonJson.c @@ -208,10 +208,13 @@ SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* self, const char* jso } Attachment* attachment = AttachmentLoader_newAttachment(self->attachmentLoader, type, attachmentName); - if (!attachment && self->attachmentLoader->error1) { - SkeletonData_free(skeletonData); - _SkeletonJson_setError(self, root, self->attachmentLoader->error1, self->attachmentLoader->error2); - return 0; + if (!attachment) { + if (self->attachmentLoader->error1) { + SkeletonData_free(skeletonData); + _SkeletonJson_setError(self, root, self->attachmentLoader->error1, self->attachmentLoader->error2); + return 0; + } + continue; } if (attachment->type == ATTACHMENT_REGION || attachment->type == ATTACHMENT_REGION_SEQUENCE) { diff --git a/spine-c/src/spine/Skin.c b/spine-c/src/spine/Skin.c index 5bace7530..c8d41485d 100644 --- a/spine-c/src/spine/Skin.c +++ b/spine-c/src/spine/Skin.c @@ -36,7 +36,6 @@ SkinEntry* _SkinEntry_new (int slotIndex, const char* name, Attachment* attachme } void _SkinEntry_free (SkinEntry* self) { - if (self->next) _SkinEntry_free(CONST_CAST(SkinEntry*, self->next) ); Attachment_free(self->attachment); FREE(self->name); FREE(self); @@ -51,7 +50,13 @@ Skin* Skin_new (const char* name) { } void Skin_free (Skin* self) { - _SkinEntry_free(CONST_CAST(SkinEntry*, self->entries) ); + SkinEntry* entry = CONST_CAST(SkinEntry*, self->entries); + while (entry) { + SkinEntry* nextEtry = CONST_CAST(SkinEntry*, entry->next); + _SkinEntry_free(entry); + entry = nextEtry; + } + FREE(self->name); FREE(self); } diff --git a/spine-c/src/spine/Slot.c b/spine-c/src/spine/Slot.c index c55f88588..2844816e6 100644 --- a/spine-c/src/spine/Slot.c +++ b/spine-c/src/spine/Slot.c @@ -48,7 +48,6 @@ void Slot_free (Slot* self) { FREE(self); } -/* @param attachment May be null. */ void Slot_setAttachment (Slot* self, Attachment* attachment) { CONST_CAST(Attachment*, self->attachment) = attachment; SUB_CAST(_Internal, self) ->attachmentTime = self->skeleton->time;