Refactoring.

This commit is contained in:
NathanSweet 2013-03-30 04:13:44 +01:00
parent 446e18dccd
commit 596b515e66
51 changed files with 1145 additions and 1393 deletions

View File

@ -26,7 +26,10 @@
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.exe.debug.1773467815" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.exe.debug"> <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.exe.debug.1773467815" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.exe.debug">
<option id="gnu.cpp.compiler.mingw.exe.debug.option.optimization.level.541156248" name="Optimization Level" superClass="gnu.cpp.compiler.mingw.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/> <option id="gnu.cpp.compiler.mingw.exe.debug.option.optimization.level.541156248" name="Optimization Level" superClass="gnu.cpp.compiler.mingw.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
<option id="gnu.cpp.compiler.mingw.exe.debug.option.debugging.level.393447411" name="Debug Level" superClass="gnu.cpp.compiler.mingw.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/> <option id="gnu.cpp.compiler.mingw.exe.debug.option.debugging.level.393447411" name="Debug Level" superClass="gnu.cpp.compiler.mingw.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
<option id="gnu.cpp.compiler.option.include.paths.1471448443" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths"/> <option id="gnu.cpp.compiler.option.include.paths.1471448443" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/include}&quot;"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.564303729" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.564303729" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool> </tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.debug.613741168" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.debug"> <tool id="cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.debug.613741168" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.debug">
@ -34,12 +37,14 @@
<option id="gnu.c.compiler.mingw.exe.debug.option.debugging.level.2068803714" name="Debug Level" superClass="gnu.c.compiler.mingw.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/> <option id="gnu.c.compiler.mingw.exe.debug.option.debugging.level.2068803714" name="Debug Level" superClass="gnu.c.compiler.mingw.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="gnu.c.compiler.option.include.paths.2051361089" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath"> <option id="gnu.c.compiler.option.include.paths.2051361089" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/include}&quot;"/>
</option> </option>
<option id="gnu.c.compiler.option.misc.other.1829716988" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -std=c89" valueType="string"/> <option id="gnu.c.compiler.option.misc.other.1829716988" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0" valueType="string"/>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.603555848" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.603555848" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool> </tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.mingw.exe.debug.1030541714" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.exe.debug"/> <tool id="cdt.managedbuild.tool.gnu.c.linker.mingw.exe.debug.1030541714" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.exe.debug"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.exe.debug.1176451976" name="MinGW C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.exe.debug"> <tool id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.exe.debug.1176451976" name="MinGW C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.exe.debug">
<option id="gnu.cpp.link.option.libs.1686926703" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.365190259" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.365190259" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/> <additionalInput kind="additionalinput" paths="$(LIBS)"/>
@ -104,21 +109,6 @@
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> <storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="spine-ctest.cdt.managedbuild.target.gnu.mingw.exe.1872348731" name="Executable" projectType="cdt.managedbuild.target.gnu.mingw.exe"/> <project id="spine-ctest.cdt.managedbuild.target.gnu.mingw.exe.1872348731" name="Executable" projectType="cdt.managedbuild.target.gnu.mingw.exe"/>
</storageModule> </storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.exe.release.486571591;cdt.managedbuild.config.gnu.mingw.exe.release.486571591.;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.exe.release.1784931142;cdt.managedbuild.tool.gnu.cpp.compiler.input.1028062039">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.exe.debug.784427509;cdt.managedbuild.config.gnu.mingw.exe.debug.784427509.;cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.debug.613741168;cdt.managedbuild.tool.gnu.c.compiler.input.603555848">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.exe.release.486571591;cdt.managedbuild.config.gnu.mingw.exe.release.486571591.;cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.release.582721725;cdt.managedbuild.tool.gnu.c.compiler.input.575877567">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.exe.debug.784427509;cdt.managedbuild.config.gnu.mingw.exe.debug.784427509.;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.exe.debug.1773467815;cdt.managedbuild.tool.gnu.cpp.compiler.input.564303729">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2"> <storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Release"> <configuration configurationName="Release">
@ -129,4 +119,19 @@
</configuration> </configuration>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/> <storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.exe.release.486571591;cdt.managedbuild.config.gnu.mingw.exe.release.486571591.;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.exe.release.1784931142;cdt.managedbuild.tool.gnu.cpp.compiler.input.1028062039">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.exe.debug.784427509;cdt.managedbuild.config.gnu.mingw.exe.debug.784427509.;cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.debug.613741168;cdt.managedbuild.tool.gnu.c.compiler.input.603555848">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.exe.debug.784427509;cdt.managedbuild.config.gnu.mingw.exe.debug.784427509.;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.exe.debug.1773467815;cdt.managedbuild.tool.gnu.cpp.compiler.input.564303729">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.exe.release.486571591;cdt.managedbuild.config.gnu.mingw.exe.release.486571591.;cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.release.582721725;cdt.managedbuild.tool.gnu.c.compiler.input.575877567">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
</storageModule>
</cproject> </cproject>

View File

@ -17,7 +17,7 @@ typedef struct {
float duration; float duration;
} Animation; } Animation;
Animation* Animation_create (); Animation* Animation_create (int timelineCount);
void Animation_dispose (Animation* animation); void Animation_dispose (Animation* animation);
void Animation_apply (const Animation* animation, Skeleton* skeleton, float time, int/*bool*/loop); void Animation_apply (const Animation* animation, Skeleton* skeleton, float time, int/*bool*/loop);

View File

@ -36,7 +36,7 @@ struct AtlasPage {
}; };
AtlasPage* AtlasPage_create (const char* name); AtlasPage* AtlasPage_create (const char* name);
void AtlasPage_dispose(AtlasPage * this); void AtlasPage_dispose (AtlasPage* page);
/**/ /**/
@ -56,7 +56,7 @@ struct AtlasRegion {
}; };
AtlasRegion* AtlasRegion_create (); AtlasRegion* AtlasRegion_create ();
void AtlasRegion_dispose(AtlasRegion * this); void AtlasRegion_dispose (AtlasRegion* region);
/**/ /**/

View File

@ -5,6 +5,7 @@
#include <spine/AttachmentLoader.h> #include <spine/AttachmentLoader.h>
#include <spine/SkeletonData.h> #include <spine/SkeletonData.h>
#include <spine/Atlas.h> #include <spine/Atlas.h>
#include <spine/Animation.h>
#ifdef __cplusplus #ifdef __cplusplus
namespace spine { namespace spine {
@ -24,7 +25,8 @@ void SkeletonJson_dispose (SkeletonJson* skeletonJson);
SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* skeletonJson, const char* json); SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* skeletonJson, const char* json);
SkeletonData* SkeletonJson_readSkeletonDataFile (SkeletonJson* skeletonJson, const char* path); SkeletonData* SkeletonJson_readSkeletonDataFile (SkeletonJson* skeletonJson, const char* path);
/* Animation* SkeletonJson_readAnimation (SkeletonJson* skeletonJson, char* json, const SkeletonData *skeletonData); */ Animation* SkeletonJson_readAnimation (SkeletonJson* skeletonJson, const char* json, const SkeletonData *skeletonData);
Animation* SkeletonJson_readAnimationFile (SkeletonJson* skeletonJson, const char* path, const SkeletonData *skeletonData);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,8 +1,11 @@
#ifndef SPINE_SPINE_H_ #ifndef SPINE_SPINE_H_
#define SPINE_SPINE_H_ #define SPINE_SPINE_H_
#include <spine/Animation.h>
#include <spine/Atlas.h> #include <spine/Atlas.h>
#include <spine/AtlasAttachmentLoader.h>
#include <spine/Attachment.h> #include <spine/Attachment.h>
#include <spine/AttachmentLoader.h>
#include <spine/Bone.h> #include <spine/Bone.h>
#include <spine/BoneData.h> #include <spine/BoneData.h>
#include <spine/RegionAttachment.h> #include <spine/RegionAttachment.h>

View File

@ -1,5 +1,5 @@
/* This demonstrates implementing an extension to spine-c. spine/extension.h declares the functions that must be implemented along /* 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. */ * with internal methods exposed to facilitate extension. */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -15,18 +15,22 @@ typedef struct {
} ExampleAtlasPage; } ExampleAtlasPage;
void _ExampleAtlasPage_dispose (AtlasPage* page) { void _ExampleAtlasPage_dispose (AtlasPage* page) {
ExampleAtlasPage* this = (ExampleAtlasPage*)page; ExampleAtlasPage* self = (ExampleAtlasPage*)page;
_AtlasPage_deinit(&this->super); _AtlasPage_deinit(&self->super);
this->extraData = 0;
FREE(this) self->extraData = 0;
FREE(self)
} }
AtlasPage* AtlasPage_create (const char* name) { AtlasPage* AtlasPage_create (const char* name) {
ExampleAtlasPage* this = calloc(1, sizeof(ExampleAtlasPage)); ExampleAtlasPage* self = CALLOC(ExampleAtlasPage, 1)
_AtlasPage_init(&this->super, name); _AtlasPage_init(&self->super, name);
this->extraData = 123; self->super._dispose = _ExampleAtlasPage_dispose;
this->super._dispose = _ExampleAtlasPage_dispose;
return &this->super; self->extraData = 123;
return &self->super;
} }
/**/ /**/
@ -37,18 +41,22 @@ typedef struct {
} ExampleRegionAttachment; } ExampleRegionAttachment;
void _ExampleRegionAttachment_dispose (Attachment* attachment) { void _ExampleRegionAttachment_dispose (Attachment* attachment) {
ExampleRegionAttachment* this = (ExampleRegionAttachment*)attachment; ExampleRegionAttachment* self = (ExampleRegionAttachment*)attachment;
_RegionAttachment_deinit(&this->super); _RegionAttachment_deinit(&self->super);
this->extraData = 0;
FREE(this) self->extraData = 0;
FREE(self)
} }
RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) { RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) {
ExampleRegionAttachment* this = calloc(1, sizeof(ExampleRegionAttachment)); ExampleRegionAttachment* self = CALLOC(ExampleRegionAttachment, 1)
_RegionAttachment_init(&this->super, name); _RegionAttachment_init(&self->super, name);
this->extraData = 456; self->super.super._dispose = _ExampleRegionAttachment_dispose;
this->super.super._dispose = _ExampleRegionAttachment_dispose;
return &this->super; self->extraData = 456;
return &self->super;
} }
/**/ /**/
@ -59,35 +67,43 @@ typedef struct {
} ExampleSkeleton; } ExampleSkeleton;
void _ExampleSkeleton_dispose (Skeleton* skeleton) { void _ExampleSkeleton_dispose (Skeleton* skeleton) {
ExampleSkeleton* this = (ExampleSkeleton*)skeleton; ExampleSkeleton* self = (ExampleSkeleton*)skeleton;
_Skeleton_deinit(&this->super); _Skeleton_deinit(&self->super);
this->extraData = 0;
FREE(this) self->extraData = 0;
FREE(self)
} }
Skeleton* Skeleton_create (SkeletonData* data) { Skeleton* Skeleton_create (SkeletonData* data) {
ExampleSkeleton* this = calloc(1, sizeof(ExampleSkeleton)); ExampleSkeleton* self = CALLOC(ExampleSkeleton, 1)
_Skeleton_init(&this->super, data); _Skeleton_init(&self->super, data);
this->extraData = 789; self->super._dispose = _ExampleSkeleton_dispose;
this->super._dispose = _ExampleSkeleton_dispose;
return &this->super; self->extraData = 789;
return &self->super;
} }
/**/ /**/
int main (void) { int main (void) {
Atlas* atlas = Atlas_readAtlasFile("data/spineboy.atlas"); Atlas* atlas = Atlas_readAtlasFile("data/spineboy.atlas");
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); printf("First region name: %s, x: %d, y: %d\n", atlas->regions->name, atlas->regions->x, atlas->regions->y);
printf("First page name: %s, extraData: %d\n", atlas->pages->name, ((ExampleAtlasPage*)atlas->pages)->extraData);
SkeletonJson* json = SkeletonJson_create(atlas); SkeletonJson* json = SkeletonJson_create(atlas);
SkeletonData *skeletonData = SkeletonJson_readSkeletonDataFile(json, "data/spineboy-skeleton.json"); SkeletonData *skeletonData = SkeletonJson_readSkeletonDataFile(json, "data/spineboy-skeleton.json");
if (!skeletonData) printf("error: %s\n", json->error); if (!skeletonData) printf("Error: %s\n", json->error);
printf("Attachment extraData: %d\n", ((ExampleRegionAttachment*)skeletonData->defaultSkin->entries->attachment)->extraData); printf("Attachment extraData: %d\n", ((ExampleRegionAttachment*)skeletonData->defaultSkin->entries->attachment)->extraData);
Skeleton* skeleton = Skeleton_create(skeletonData); Skeleton* skeleton = Skeleton_create(skeletonData);
printf("Skeleton extraData: %d\n", ((ExampleSkeleton*)skeleton)->extraData); printf("Skeleton extraData: %d\n", ((ExampleSkeleton*)skeleton)->extraData);
Animation* animation = SkeletonJson_readAnimationFile(json, "data/spineboy-walk.json", skeletonData);
if (!animation) printf("Error: %s\n", json->error);
printf("Animation timelineCount: %d\n", animation->timelineCount);
Skeleton_dispose(skeleton); Skeleton_dispose(skeleton);
SkeletonData_dispose(skeletonData); SkeletonData_dispose(skeletonData);
SkeletonJson_dispose(json); SkeletonJson_dispose(json);

View File

@ -2,33 +2,35 @@
#include <math.h> #include <math.h>
#include <spine/util.h> #include <spine/util.h>
Animation* Animation_create () { Animation* Animation_create (int timelineCount) {
Animation* this = calloc(1, sizeof(Animation)); Animation* self = CALLOC(Animation, 1);
return this; self->timelineCount = timelineCount;
self->timelines = MALLOC(Timeline*, timelineCount)
return self;
} }
void Animation_dispose (Animation* this) { void Animation_dispose (Animation* self) {
int i; int i;
for (i = 0; i < this->timelineCount; ++i) for (i = 0; i < self->timelineCount; ++i)
Timeline_dispose(this->timelines[i]); Timeline_dispose(self->timelines[i]);
FREE(this->timelines) FREE(self->timelines)
FREE(this) FREE(self)
} }
void Animation_apply (const Animation* this, Skeleton* skeleton, float time, int/*bool*/loop) { void Animation_apply (const Animation* self, Skeleton* skeleton, float time, int/*bool*/loop) {
if (loop && this->duration) time = fmod(time, this->duration); if (loop && self->duration) time = fmodf(time, self->duration);
int i, n = this->timelineCount; int i, n = self->timelineCount;
for (i = 0; i < n; ++i) for (i = 0; i < n; ++i)
Timeline_apply(this->timelines[i], skeleton, time, 1); Timeline_apply(self->timelines[i], skeleton, time, 1);
} }
void Animation_mix (const Animation* this, Skeleton* skeleton, float time, int/*bool*/loop, float alpha) { void Animation_mix (const Animation* self, Skeleton* skeleton, float time, int/*bool*/loop, float alpha) {
if (loop && this->duration) time = fmod(time, this->duration); if (loop && self->duration) time = fmodf(time, self->duration);
int i, n = this->timelineCount; int i, n = self->timelineCount;
for (i = 0; i < n; ++i) for (i = 0; i < n; ++i)
Timeline_apply(this->timelines[i], skeleton, time, alpha); Timeline_apply(self->timelines[i], skeleton, time, alpha);
} }
/**/ /**/
@ -39,12 +41,12 @@ void _Timeline_init (Timeline* timeline) {
void _Timeline_deinit (Timeline* timeline) { void _Timeline_deinit (Timeline* timeline) {
} }
void Timeline_dispose (Timeline* this) { void Timeline_dispose (Timeline* self) {
this->_dispose(this); self->_dispose(self);
} }
void Timeline_apply (const Timeline *this, Skeleton* skeleton, float time, float alpha) { void Timeline_apply (const Timeline* self, Skeleton* skeleton, float time, float alpha) {
this->_apply(this, skeleton, time, alpha); self->_apply(self, skeleton, time, alpha);
} }
/**/ /**/
@ -53,25 +55,25 @@ static const float CURVE_LINEAR = 0;
static const float CURVE_STEPPED = -1; static const float CURVE_STEPPED = -1;
static const int CURVE_SEGMENTS = 10; static const int CURVE_SEGMENTS = 10;
void _CurveTimeline_init (CurveTimeline* this, int frameCount) { void _CurveTimeline_init (CurveTimeline* self, int frameCount) {
_Timeline_init(&this->super); _Timeline_init(&self->super);
this->curves = calloc(1, sizeof(float) * (frameCount - 1) * 6); self->curves = CALLOC(float, (frameCount - 1) * 6)
} }
void _CurveTimeline_deinit (CurveTimeline* this) { void _CurveTimeline_deinit (CurveTimeline* self) {
_Timeline_deinit(&this->super); _Timeline_deinit(&self->super);
FREE(this->curves) FREE(self->curves)
} }
void CurveTimeline_setLinear (CurveTimeline* this, int frameIndex) { void CurveTimeline_setLinear (CurveTimeline* self, int frameIndex) {
this->curves[frameIndex * 6] = CURVE_LINEAR; self->curves[frameIndex * 6] = CURVE_LINEAR;
} }
void CurveTimeline_setStepped (CurveTimeline* this, int frameIndex) { void CurveTimeline_setStepped (CurveTimeline* self, int frameIndex) {
this->curves[frameIndex * 6] = CURVE_STEPPED; self->curves[frameIndex * 6] = CURVE_STEPPED;
} }
void CurveTimeline_setCurve (CurveTimeline* this, int frameIndex, float cx1, float cy1, float cx2, float cy2) { void CurveTimeline_setCurve (CurveTimeline* self, int frameIndex, float cx1, float cy1, float cx2, float cy2) {
float subdiv_step = 1.0f / CURVE_SEGMENTS; float subdiv_step = 1.0f / CURVE_SEGMENTS;
float subdiv_step2 = subdiv_step * subdiv_step; float subdiv_step2 = subdiv_step * subdiv_step;
float subdiv_step3 = subdiv_step2 * subdiv_step; float subdiv_step3 = subdiv_step2 * subdiv_step;
@ -84,24 +86,24 @@ void CurveTimeline_setCurve (CurveTimeline* this, int frameIndex, float cx1, flo
float tmp2x = (cx1 - cx2) * 3 + 1; float tmp2x = (cx1 - cx2) * 3 + 1;
float tmp2y = (cy1 - cy2) * 3 + 1; float tmp2y = (cy1 - cy2) * 3 + 1;
int i = frameIndex * 6; int i = frameIndex * 6;
this->curves[i] = cx1 * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3; self->curves[i] = cx1 * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3;
this->curves[i + 1] = cy1 * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3; self->curves[i + 1] = cy1 * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3;
this->curves[i + 2] = tmp1x * pre4 + tmp2x * pre5; self->curves[i + 2] = tmp1x * pre4 + tmp2x * pre5;
this->curves[i + 3] = tmp1y * pre4 + tmp2y * pre5; self->curves[i + 3] = tmp1y * pre4 + tmp2y * pre5;
this->curves[i + 4] = tmp2x * pre5; self->curves[i + 4] = tmp2x * pre5;
this->curves[i + 5] = tmp2y * pre5; self->curves[i + 5] = tmp2y * pre5;
} }
float CurveTimeline_getCurvePercent (CurveTimeline* this, int frameIndex, float percent) { float CurveTimeline_getCurvePercent (CurveTimeline* self, int frameIndex, float percent) {
int curveIndex = frameIndex * 6; int curveIndex = frameIndex * 6;
float dfx = this->curves[curveIndex]; float dfx = self->curves[curveIndex];
if (dfx == CURVE_LINEAR) return percent; if (dfx == CURVE_LINEAR) return percent;
if (dfx == CURVE_STEPPED) return 0; if (dfx == CURVE_STEPPED) return 0;
float dfy = this->curves[curveIndex + 1]; float dfy = self->curves[curveIndex + 1];
float ddfx = this->curves[curveIndex + 2]; float ddfx = self->curves[curveIndex + 2];
float ddfy = this->curves[curveIndex + 3]; float ddfy = self->curves[curveIndex + 3];
float dddfx = this->curves[curveIndex + 4]; float dddfx = self->curves[curveIndex + 4];
float dddfy = this->curves[curveIndex + 5]; float dddfy = self->curves[curveIndex + 5];
float x = dfx, y = dfy; float x = dfx, y = dfy;
int i = CURVE_SEGMENTS - 2; int i = CURVE_SEGMENTS - 2;
while (1) { while (1) {
@ -151,22 +153,22 @@ static int binarySearch (float *values, int valuesLength, float target, int step
/**/ /**/
void _BaseTimeline_dispose (Timeline* timeline) { void _BaseTimeline_dispose (Timeline* timeline) {
struct BaseTimeline* this = (struct BaseTimeline*)timeline; struct BaseTimeline* self = (struct BaseTimeline*)timeline;
_CurveTimeline_deinit(&this->super); _CurveTimeline_deinit(&self->super);
FREE(this->frames); FREE(self->frames);
FREE(this); FREE(self);
} }
/* Many timelines have structure identical to struct BaseTimeline and extend CurveTimeline. **/ /* Many timelines have structure identical to struct BaseTimeline and extend CurveTimeline. **/
struct BaseTimeline* _BaseTimeline_create (int frameCount, int frameSize) { struct BaseTimeline* _BaseTimeline_create (int frameCount, int frameSize) {
struct BaseTimeline* this = calloc(1, sizeof(struct BaseTimeline)); struct BaseTimeline* self = CALLOC(struct BaseTimeline, 1)
_CurveTimeline_init(&this->super, frameCount); _CurveTimeline_init(&self->super, frameCount);
((Timeline*)this)->_dispose = _BaseTimeline_dispose; ((Timeline*)self)->_dispose = _BaseTimeline_dispose;
CAST(int, this->frameCount) = frameCount; CAST(int, self->frameCount) = frameCount;
CAST(float*, this->frames) = calloc(1, sizeof(float) * frameCount * frameSize); CAST(float*, self->frames) = CALLOC(float, frameCount * frameSize)
return this; return self;
} }
/**/ /**/
@ -175,14 +177,14 @@ static const int ROTATE_LAST_FRAME_TIME = -2;
static const int ROTATE_FRAME_VALUE = 1; static const int ROTATE_FRAME_VALUE = 1;
void _RotateTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha) { void _RotateTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha) {
RotateTimeline* this = (RotateTimeline*)timeline; RotateTimeline* self = (RotateTimeline*)timeline;
if (time < this->frames[0]) return; /* Time is before first frame. */ if (time < self->frames[0]) return; /* Time is before first frame. */
Bone *bone = skeleton->bones[this->boneIndex]; Bone *bone = skeleton->bones[self->boneIndex];
if (time >= this->frames[this->frameCount - 2]) { /* Time is after last frame. */ if (time >= self->frames[self->frameCount - 2]) { /* Time is after last frame. */
float amount = bone->data->rotation + this->frames[this->frameCount - 1] - bone->rotation; float amount = bone->data->rotation + self->frames[self->frameCount - 1] - bone->rotation;
while (amount > 180) while (amount > 180)
amount -= 360; amount -= 360;
while (amount < -180) while (amount < -180)
@ -192,13 +194,13 @@ void _RotateTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float
} }
/* Interpolate between the last frame and the current frame. */ /* Interpolate between the last frame and the current frame. */
int frameIndex = binarySearch(this->frames, this->frameCount, time, 2); int frameIndex = binarySearch(self->frames, self->frameCount, time, 2);
float lastFrameValue = this->frames[frameIndex - 1]; float lastFrameValue = self->frames[frameIndex - 1];
float frameTime = this->frames[frameIndex]; float frameTime = self->frames[frameIndex];
float percent = 1 - (time - frameTime) / (this->frames[frameIndex + ROTATE_LAST_FRAME_TIME] - frameTime); float percent = 1 - (time - frameTime) / (self->frames[frameIndex + ROTATE_LAST_FRAME_TIME] - frameTime);
percent = CurveTimeline_getCurvePercent(&this->super, frameIndex / 2 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent)); percent = CurveTimeline_getCurvePercent(&self->super, frameIndex / 2 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
float amount = this->frames[frameIndex + ROTATE_FRAME_VALUE] - lastFrameValue; float amount = self->frames[frameIndex + ROTATE_FRAME_VALUE] - lastFrameValue;
while (amount > 180) while (amount > 180)
amount -= 360; amount -= 360;
while (amount < -180) while (amount < -180)
@ -212,15 +214,15 @@ void _RotateTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float
} }
RotateTimeline* RotateTimeline_create (int frameCount) { RotateTimeline* RotateTimeline_create (int frameCount) {
RotateTimeline* this = _BaseTimeline_create(frameCount, 2); RotateTimeline* self = _BaseTimeline_create(frameCount, 2);
((Timeline*)this)->_apply = _RotateTimeline_apply; ((Timeline*)self)->_apply = _RotateTimeline_apply;
return this; return self;
} }
void RotateTimeline_setFrame (RotateTimeline* this, int frameIndex, float time, float angle) { void RotateTimeline_setFrame (RotateTimeline* self, int frameIndex, float time, float angle) {
frameIndex *= 2; frameIndex *= 2;
this->frames[frameIndex] = time; self->frames[frameIndex] = time;
this->frames[frameIndex + 1] = angle; self->frames[frameIndex + 1] = angle;
} }
/**/ /**/
@ -230,81 +232,81 @@ static const int TRANSLATE_FRAME_X = 1;
static const int TRANSLATE_FRAME_Y = 2; static const int TRANSLATE_FRAME_Y = 2;
void _TranslateTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha) { void _TranslateTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha) {
TranslateTimeline* this = (TranslateTimeline*)timeline; TranslateTimeline* self = (TranslateTimeline*)timeline;
if (time < this->frames[0]) return; /* Time is before first frame. */ if (time < self->frames[0]) return; /* Time is before first frame. */
Bone *bone = skeleton->bones[this->boneIndex]; Bone *bone = skeleton->bones[self->boneIndex];
if (time >= this->frames[this->frameCount - 3]) { /* Time is after last frame. */ if (time >= self->frames[self->frameCount - 3]) { /* Time is after last frame. */
bone->x += (bone->data->x + this->frames[this->frameCount - 2] - bone->x) * alpha; bone->x += (bone->data->x + self->frames[self->frameCount - 2] - bone->x) * alpha;
bone->y += (bone->data->y + this->frames[this->frameCount - 1] - bone->y) * alpha; bone->y += (bone->data->y + self->frames[self->frameCount - 1] - bone->y) * alpha;
return; return;
} }
/* Interpolate between the last frame and the current frame. */ /* Interpolate between the last frame and the current frame. */
int frameIndex = binarySearch(this->frames, this->frameCount, time, 3); int frameIndex = binarySearch(self->frames, self->frameCount, time, 3);
float lastFrameX = this->frames[frameIndex - 2]; float lastFrameX = self->frames[frameIndex - 2];
float lastFrameY = this->frames[frameIndex - 1]; float lastFrameY = self->frames[frameIndex - 1];
float frameTime = this->frames[frameIndex]; float frameTime = self->frames[frameIndex];
float percent = 1 - (time - frameTime) / (this->frames[frameIndex + TRANSLATE_LAST_FRAME_TIME] - frameTime); float percent = 1 - (time - frameTime) / (self->frames[frameIndex + TRANSLATE_LAST_FRAME_TIME] - frameTime);
percent = CurveTimeline_getCurvePercent(&this->super, frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent)); percent = CurveTimeline_getCurvePercent(&self->super, frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
bone->x += (bone->data->x + lastFrameX + (this->frames[frameIndex + TRANSLATE_FRAME_X] - lastFrameX) * percent - bone->x) bone->x += (bone->data->x + lastFrameX + (self->frames[frameIndex + TRANSLATE_FRAME_X] - lastFrameX) * percent - bone->x)
* alpha; * alpha;
bone->y += (bone->data->y + lastFrameY + (this->frames[frameIndex + TRANSLATE_FRAME_Y] - lastFrameY) * percent - bone->y) bone->y += (bone->data->y + lastFrameY + (self->frames[frameIndex + TRANSLATE_FRAME_Y] - lastFrameY) * percent - bone->y)
* alpha; * alpha;
} }
TranslateTimeline* TranslateTimeline_create (int frameCount) { TranslateTimeline* TranslateTimeline_create (int frameCount) {
TranslateTimeline* this = _BaseTimeline_create(frameCount, 3); TranslateTimeline* self = _BaseTimeline_create(frameCount, 3);
((Timeline*)this)->_apply = _TranslateTimeline_apply; ((Timeline*)self)->_apply = _TranslateTimeline_apply;
return this; return self;
} }
void TranslateTimeline_setFrame (TranslateTimeline* this, int frameIndex, float time, float x, float y) { void TranslateTimeline_setFrame (TranslateTimeline* self, int frameIndex, float time, float x, float y) {
frameIndex *= 3; frameIndex *= 3;
this->frames[frameIndex] = time; self->frames[frameIndex] = time;
this->frames[frameIndex + 1] = x; self->frames[frameIndex + 1] = x;
this->frames[frameIndex + 2] = y; self->frames[frameIndex + 2] = y;
} }
/**/ /**/
void _ScaleTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha) { void _ScaleTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha) {
ScaleTimeline* this = (ScaleTimeline*)timeline; ScaleTimeline* self = (ScaleTimeline*)timeline;
if (time < this->frames[0]) return; /* Time is before first frame. */ if (time < self->frames[0]) return; /* Time is before first frame. */
Bone *bone = skeleton->bones[this->boneIndex]; Bone *bone = skeleton->bones[self->boneIndex];
if (time >= this->frames[this->frameCount - 3]) { /* Time is after last frame. */ if (time >= self->frames[self->frameCount - 3]) { /* Time is after last frame. */
bone->scaleX += (bone->data->scaleX - 1 + this->frames[this->frameCount - 2] - bone->scaleX) * alpha; bone->scaleX += (bone->data->scaleX - 1 + self->frames[self->frameCount - 2] - bone->scaleX) * alpha;
bone->scaleY += (bone->data->scaleY - 1 + this->frames[this->frameCount - 1] - bone->scaleY) * alpha; bone->scaleY += (bone->data->scaleY - 1 + self->frames[self->frameCount - 1] - bone->scaleY) * alpha;
return; return;
} }
/* Interpolate between the last frame and the current frame. */ /* Interpolate between the last frame and the current frame. */
int frameIndex = binarySearch(this->frames, this->frameCount, time, 3); int frameIndex = binarySearch(self->frames, self->frameCount, time, 3);
float lastFrameX = this->frames[frameIndex - 2]; float lastFrameX = self->frames[frameIndex - 2];
float lastFrameY = this->frames[frameIndex - 1]; float lastFrameY = self->frames[frameIndex - 1];
float frameTime = this->frames[frameIndex]; float frameTime = self->frames[frameIndex];
float percent = 1 - (time - frameTime) / (this->frames[frameIndex + TRANSLATE_LAST_FRAME_TIME] - frameTime); float percent = 1 - (time - frameTime) / (self->frames[frameIndex + TRANSLATE_LAST_FRAME_TIME] - frameTime);
percent = CurveTimeline_getCurvePercent(&this->super, frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent)); percent = CurveTimeline_getCurvePercent(&self->super, frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
bone->scaleX += (bone->data->scaleX - 1 + lastFrameX + (this->frames[frameIndex + TRANSLATE_FRAME_X] - lastFrameX) * percent bone->scaleX += (bone->data->scaleX - 1 + lastFrameX + (self->frames[frameIndex + TRANSLATE_FRAME_X] - lastFrameX) * percent
- bone->scaleX) * alpha; - bone->scaleX) * alpha;
bone->scaleY += (bone->data->scaleY - 1 + lastFrameY + (this->frames[frameIndex + TRANSLATE_FRAME_Y] - lastFrameY) * percent bone->scaleY += (bone->data->scaleY - 1 + lastFrameY + (self->frames[frameIndex + TRANSLATE_FRAME_Y] - lastFrameY) * percent
- bone->scaleY) * alpha; - bone->scaleY) * alpha;
} }
ScaleTimeline* ScaleTimeline_create (int frameCount) { ScaleTimeline* ScaleTimeline_create (int frameCount) {
ScaleTimeline* this = _BaseTimeline_create(frameCount, 3); ScaleTimeline* self = _BaseTimeline_create(frameCount, 3);
((Timeline*)this)->_apply = _ScaleTimeline_apply; ((Timeline*)self)->_apply = _ScaleTimeline_apply;
return this; return self;
} }
void ScaleTimeline_setFrame (ScaleTimeline* this, int frameIndex, float time, float x, float y) { void ScaleTimeline_setFrame (ScaleTimeline* self, int frameIndex, float time, float x, float y) {
TranslateTimeline_setFrame(this, frameIndex, time, x, y); TranslateTimeline_setFrame(self, frameIndex, time, x, y);
} }
/**/ /**/
@ -316,35 +318,35 @@ static const int COLOR_FRAME_B = 3;
static const int COLOR_FRAME_A = 4; static const int COLOR_FRAME_A = 4;
void _ColorTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha) { void _ColorTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha) {
ColorTimeline* this = (ColorTimeline*)timeline; ColorTimeline* self = (ColorTimeline*)timeline;
if (time < this->frames[0]) return; /* Time is before first frame. */ if (time < self->frames[0]) return; /* Time is before first frame. */
Slot *slot = skeleton->slots[this->slotIndex]; Slot *slot = skeleton->slots[self->slotIndex];
if (time >= this->frames[this->frameCount - 5]) { /* Time is after last frame. */ if (time >= self->frames[self->frameCount - 5]) { /* Time is after last frame. */
int i = this->frameCount - 1; int i = self->frameCount - 1;
slot->r = this->frames[i - 3]; slot->r = self->frames[i - 3];
slot->g = this->frames[i - 2]; slot->g = self->frames[i - 2];
slot->b = this->frames[i - 1]; slot->b = self->frames[i - 1];
slot->a = this->frames[i]; slot->a = self->frames[i];
return; return;
} }
/* Interpolate between the last frame and the current frame. */ /* Interpolate between the last frame and the current frame. */
int frameIndex = binarySearch(this->frames, this->frameCount, time, 5); int frameIndex = binarySearch(self->frames, self->frameCount, time, 5);
float lastFrameR = this->frames[frameIndex - 4]; float lastFrameR = self->frames[frameIndex - 4];
float lastFrameG = this->frames[frameIndex - 3]; float lastFrameG = self->frames[frameIndex - 3];
float lastFrameB = this->frames[frameIndex - 2]; float lastFrameB = self->frames[frameIndex - 2];
float lastFrameA = this->frames[frameIndex - 1]; float lastFrameA = self->frames[frameIndex - 1];
float frameTime = this->frames[frameIndex]; float frameTime = self->frames[frameIndex];
float percent = 1 - (time - frameTime) / (this->frames[frameIndex + COLOR_LAST_FRAME_TIME] - frameTime); float percent = 1 - (time - frameTime) / (self->frames[frameIndex + COLOR_LAST_FRAME_TIME] - frameTime);
percent = CurveTimeline_getCurvePercent(&this->super, frameIndex / 5 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent)); percent = CurveTimeline_getCurvePercent(&self->super, frameIndex / 5 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
float r = lastFrameR + (this->frames[frameIndex + COLOR_FRAME_R] - lastFrameR) * percent; float r = lastFrameR + (self->frames[frameIndex + COLOR_FRAME_R] - lastFrameR) * percent;
float g = lastFrameG + (this->frames[frameIndex + COLOR_FRAME_G] - lastFrameG) * percent; float g = lastFrameG + (self->frames[frameIndex + COLOR_FRAME_G] - lastFrameG) * percent;
float b = lastFrameB + (this->frames[frameIndex + COLOR_FRAME_B] - lastFrameB) * percent; float b = lastFrameB + (self->frames[frameIndex + COLOR_FRAME_B] - lastFrameB) * percent;
float a = lastFrameA + (this->frames[frameIndex + COLOR_FRAME_A] - lastFrameA) * percent; float a = lastFrameA + (self->frames[frameIndex + COLOR_FRAME_A] - lastFrameA) * percent;
if (alpha < 1) { if (alpha < 1) {
slot->r += (r - slot->r) * alpha; slot->r += (r - slot->r) * alpha;
slot->g += (g - slot->g) * alpha; slot->g += (g - slot->g) * alpha;
@ -359,68 +361,68 @@ void _ColorTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float t
} }
ColorTimeline* ColorTimeline_create (int frameCount) { ColorTimeline* ColorTimeline_create (int frameCount) {
ColorTimeline* this = (ColorTimeline*)_BaseTimeline_create(frameCount, 5); ColorTimeline* self = (ColorTimeline*)_BaseTimeline_create(frameCount, 5);
((Timeline*)this)->_apply = _ColorTimeline_apply; ((Timeline*)self)->_apply = _ColorTimeline_apply;
return this; return self;
} }
void ColorTimeline_setFrame (ColorTimeline* this, int frameIndex, float time, float r, float g, float b, float a) { void ColorTimeline_setFrame (ColorTimeline* self, int frameIndex, float time, float r, float g, float b, float a) {
frameIndex *= 5; frameIndex *= 5;
this->frames[frameIndex] = time; self->frames[frameIndex] = time;
this->frames[frameIndex + 1] = r; self->frames[frameIndex + 1] = r;
this->frames[frameIndex + 2] = g; self->frames[frameIndex + 2] = g;
this->frames[frameIndex + 3] = b; self->frames[frameIndex + 3] = b;
this->frames[frameIndex + 4] = a; self->frames[frameIndex + 4] = a;
} }
/**/ /**/
void _AttachmentTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha) { void _AttachmentTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha) {
AttachmentTimeline* this = (AttachmentTimeline*)timeline; AttachmentTimeline* self = (AttachmentTimeline*)timeline;
if (time < this->frames[0]) return; /* Time is before first frame. */ if (time < self->frames[0]) return; /* Time is before first frame. */
int frameIndex; int frameIndex;
if (time >= this->frames[this->frameCount - 1]) /* Time is after last frame. */ if (time >= self->frames[self->frameCount - 1]) /* Time is after last frame. */
frameIndex = this->frameCount - 1; frameIndex = self->frameCount - 1;
else else
frameIndex = binarySearch(this->frames, this->frameCount, time, 1) - 1; frameIndex = binarySearch(self->frames, self->frameCount, time, 1) - 1;
const char* attachmentName = this->attachmentNames[frameIndex]; const char* attachmentName = self->attachmentNames[frameIndex];
Slot_setAttachment(skeleton->slots[this->slotIndex], Slot_setAttachment(skeleton->slots[self->slotIndex],
attachmentName ? Skeleton_getAttachmentForSlotIndex(skeleton, this->slotIndex, attachmentName) : 0); attachmentName ? Skeleton_getAttachmentForSlotIndex(skeleton, self->slotIndex, attachmentName) : 0);
} }
void _AttachmentTimeline_dispose (Timeline* timeline) { void _AttachmentTimeline_dispose (Timeline* timeline) {
_Timeline_deinit(timeline); _Timeline_deinit(timeline);
AttachmentTimeline* this = (AttachmentTimeline*)timeline; AttachmentTimeline* self = (AttachmentTimeline*)timeline;
int i; int i;
for (i = 0; i < this->frameCount; ++i) for (i = 0; i < self->frameCount; ++i)
FREE(this->attachmentNames[i]) FREE(self->attachmentNames[i])
FREE(this->attachmentNames) FREE(self->attachmentNames)
FREE(this) FREE(self)
} }
AttachmentTimeline* AttachmentTimeline_create (int frameCount) { AttachmentTimeline* AttachmentTimeline_create (int frameCount) {
AttachmentTimeline* this = calloc(1, sizeof(AttachmentTimeline)); AttachmentTimeline* self = CALLOC(AttachmentTimeline, 1)
_Timeline_init(&this->super); _Timeline_init(&self->super);
((Timeline*)this)->_dispose = _AttachmentTimeline_dispose; ((Timeline*)self)->_dispose = _AttachmentTimeline_dispose;
((Timeline*)this)->_apply = _AttachmentTimeline_apply; ((Timeline*)self)->_apply = _AttachmentTimeline_apply;
CAST(char*, this->attachmentNames) = calloc(1, sizeof(char*) * frameCount); CAST(char**, self->attachmentNames) = CALLOC(char*, frameCount)
CAST(int, this->frameCount) = frameCount; CAST(int, self->frameCount) = frameCount;
CAST(float*, this->frames) = calloc(1, sizeof(float) * frameCount); CAST(float*, self->frames) = CALLOC(float, frameCount)
return this; return self;
} }
void AttachmentTimeline_setFrame (AttachmentTimeline* this, int frameIndex, float time, const char* attachmentName) { void AttachmentTimeline_setFrame (AttachmentTimeline* self, int frameIndex, float time, const char* attachmentName) {
this->frames[frameIndex] = time; self->frames[frameIndex] = time;
FREE(this->attachmentNames[frameIndex]) FREE(self->attachmentNames[frameIndex])
if (attachmentName) if (attachmentName)
MALLOC_STR(this->attachmentNames[frameIndex], attachmentName) MALLOC_STR(self->attachmentNames[frameIndex], attachmentName)
else else
this->attachmentNames[frameIndex] = 0; self->attachmentNames[frameIndex] = 0;
} }

View File

@ -3,32 +3,32 @@
#include <spine/util.h> #include <spine/util.h>
#include <spine/extension.h> #include <spine/extension.h>
void _AtlasPage_init (AtlasPage* this, const char* name) { void _AtlasPage_init (AtlasPage* self, const char* name) {
this->name = name; /* name is guaranteed to be memory we allocated. */ self->name = name; /* name is guaranteed to be memory we allocated. */
} }
void _AtlasPage_deinit (AtlasPage* this) { void _AtlasPage_deinit (AtlasPage* self) {
FREE(this->name); FREE(self->name);
} }
void AtlasPage_dispose (AtlasPage* this) { void AtlasPage_dispose (AtlasPage* self) {
if (this->next) AtlasPage_dispose(this->next); /* BOZO - Don't dispose all in the list. */ if (self->next) AtlasPage_dispose(self->next); /* BOZO - Don't dispose all in the list. */
this->_dispose(this); self->_dispose(self);
} }
/**/ /**/
AtlasRegion* AtlasRegion_create () { AtlasRegion* AtlasRegion_create () {
AtlasRegion* this = calloc(1, sizeof(AtlasRegion)); AtlasRegion* self = CALLOC(AtlasRegion, 1)
return this; return self;
} }
void AtlasRegion_dispose (AtlasRegion* this) { void AtlasRegion_dispose (AtlasRegion* self) {
if (this->next) AtlasRegion_dispose(this->next); if (self->next) AtlasRegion_dispose(self->next);
FREE(this->name); FREE(self->name);
FREE(this->splits); FREE(self->splits);
FREE(this->pads); FREE(self->pads);
FREE(this); FREE(self);
} }
/**/ /**/
@ -114,7 +114,7 @@ static int readTuple (Str tuple[]) {
static char* mallocString (Str* str) { static char* mallocString (Str* str) {
int length = str->end - str->begin; int length = str->end - str->begin;
char* string = malloc(length + 1); char* string = MALLOC(char, length + 1)
memcpy(string, str->begin, length); memcpy(string, str->begin, length);
string[length] = '\0'; string[length] = '\0';
return string; return string;
@ -128,7 +128,7 @@ static int indexOf (const char** array, int count, Str* str) {
return -1; return -1;
} }
static int equals (Str* str, char* other) { static int equals (Str* str, const char* other) {
return strncmp(other, str->begin, str->end - str->begin) == 0; return strncmp(other, str->begin, str->end - str->begin) == 0;
} }
@ -141,7 +141,7 @@ static const char* textureFilterNames[] = {"Nearest", "Linear", "MipMap", "MipMa
"MipMapNearestLinear", "MipMapLinearLinear"}; "MipMapNearestLinear", "MipMapLinearLinear"};
Atlas* Atlas_readAtlas (const char* data) { Atlas* Atlas_readAtlas (const char* data) {
Atlas* this = calloc(1, sizeof(Atlas)); Atlas* self = CALLOC(Atlas, 1)
AtlasPage *page = 0; AtlasPage *page = 0;
AtlasPage *lastPage = 0; AtlasPage *lastPage = 0;
@ -157,7 +157,7 @@ Atlas* Atlas_readAtlas (const char* data) {
if (lastPage) if (lastPage)
lastPage->next = page; lastPage->next = page;
else else
this->pages = page; self->pages = page;
lastPage = page; lastPage = page;
if (!readValue(&str)) return 0; if (!readValue(&str)) return 0;
@ -177,7 +177,7 @@ Atlas* Atlas_readAtlas (const char* data) {
if (lastRegion) if (lastRegion)
lastRegion->next = region; lastRegion->next = region;
else else
this->regions = region; self->regions = region;
lastRegion = region; lastRegion = region;
region->page = page; region->page = page;
@ -197,7 +197,7 @@ Atlas* Atlas_readAtlas (const char* data) {
int count; int count;
if (!(count = readTuple(tuple))) return 0; if (!(count = readTuple(tuple))) return 0;
if (count == 4) { /* split is optional */ if (count == 4) { /* split is optional */
region->splits = malloc(sizeof(int) * 4); region->splits = MALLOC(int, 4)
region->splits[0] = toInt(tuple); region->splits[0] = toInt(tuple);
region->splits[1] = toInt(tuple + 1); region->splits[1] = toInt(tuple + 1);
region->splits[2] = toInt(tuple + 2); region->splits[2] = toInt(tuple + 2);
@ -205,7 +205,7 @@ Atlas* Atlas_readAtlas (const char* data) {
if (!(count = readTuple(tuple))) return 0; if (!(count = readTuple(tuple))) return 0;
if (count == 4) { /* pad is optional, but only present with splits */ if (count == 4) { /* pad is optional, but only present with splits */
region->pads = malloc(sizeof(int) * 4); region->pads = MALLOC(int, 4)
region->pads[0] = toInt(tuple); region->pads[0] = toInt(tuple);
region->pads[1] = toInt(tuple + 1); region->pads[1] = toInt(tuple + 1);
region->pads[2] = toInt(tuple + 2); region->pads[2] = toInt(tuple + 2);
@ -227,7 +227,7 @@ Atlas* Atlas_readAtlas (const char* data) {
} }
} }
return this; return self;
} }
Atlas* Atlas_readAtlasFile (const char* path) { Atlas* Atlas_readAtlasFile (const char* path) {
@ -238,14 +238,14 @@ Atlas* Atlas_readAtlasFile (const char* path) {
return atlas; return atlas;
} }
void Atlas_dispose (Atlas* this) { void Atlas_dispose (Atlas* self) {
if (this->pages) AtlasPage_dispose(this->pages); if (self->pages) AtlasPage_dispose(self->pages);
if (this->regions) AtlasRegion_dispose(this->regions); if (self->regions) AtlasRegion_dispose(self->regions);
FREE(this) FREE(self)
} }
AtlasRegion* Atlas_findRegion (const Atlas* this, const char* name) { AtlasRegion* Atlas_findRegion (const Atlas* self, const char* name) {
AtlasRegion* region = this->regions; AtlasRegion* region = self->regions;
while (region) { while (region) {
if (strcmp(region->name, name) == 0) return region; if (strcmp(region->name, name) == 0) return region;
region = region->next; region = region->next;

View File

@ -3,30 +3,34 @@
#include <spine/extension.h> #include <spine/extension.h>
#include <stdio.h> #include <stdio.h>
void _AtlasAttachmentLoader_dispose (AttachmentLoader* this) { void _AtlasAttachmentLoader_dispose (AttachmentLoader* self) {
_AttachmentLoader_deinit(this); _AttachmentLoader_deinit(self);
} }
Attachment* _AtlasAttachmentLoader_newAttachment (AttachmentLoader* loader, AttachmentType type, const char* name) { Attachment* _AtlasAttachmentLoader_newAttachment (AttachmentLoader* loader, AttachmentType type, const char* name) {
AtlasAttachmentLoader* this = (AtlasAttachmentLoader*)loader; AtlasAttachmentLoader* self = (AtlasAttachmentLoader*)loader;
switch (type) { switch (type) {
case ATTACHMENT_REGION: { case ATTACHMENT_REGION: {
AtlasRegion* region = Atlas_findRegion(this->atlas, name); AtlasRegion* region = Atlas_findRegion(self->atlas, name);
if (!region) return _AttachmentLoader_setError(loader, "Region not found: ", name); if (!region) {
_AttachmentLoader_setError(loader, "Region not found: ", name);
return 0;
}
return (Attachment*)RegionAttachment_create(name, region); return (Attachment*)RegionAttachment_create(name, region);
} }
default: { default: {
char buffer[16]; char buffer[16];
sprintf((char*)loader->error2, "%d", type); sprintf((char*)loader->error2, "%d", type);
return _AttachmentLoader_setError(loader, "Unknown attachment type: ", buffer); _AttachmentLoader_setError(loader, "Unknown attachment type: ", buffer);
return 0;
} }
} }
} }
AtlasAttachmentLoader* AtlasAttachmentLoader_create (Atlas* atlas) { AtlasAttachmentLoader* AtlasAttachmentLoader_create (Atlas* atlas) {
AtlasAttachmentLoader* this = calloc(1, sizeof(AtlasAttachmentLoader)); AtlasAttachmentLoader* self = CALLOC(AtlasAttachmentLoader, 1)
this->atlas = atlas; self->atlas = atlas;
this->super._newAttachment = _AtlasAttachmentLoader_newAttachment; self->super._newAttachment = _AtlasAttachmentLoader_newAttachment;
this->super._dispose = _AtlasAttachmentLoader_dispose; self->super._dispose = _AtlasAttachmentLoader_dispose;
return this; return self;
} }

View File

@ -1,16 +1,16 @@
#include <spine/Attachment.h> #include <spine/Attachment.h>
#include <spine/util.h> #include <spine/util.h>
void _Attachment_init (Attachment* this, const char* name, int type) { void _Attachment_init (Attachment* self, const char* name, int type) {
MALLOC_STR(this->name, name); MALLOC_STR(self->name, name);
this->type = type; self->type = type;
} }
void _Attachment_deinit (Attachment* this) { void _Attachment_deinit (Attachment* self) {
FREE(this->name) FREE(self->name)
FREE(this) FREE(self)
} }
void Attachment_dispose (Attachment* this) { void Attachment_dispose (Attachment* self) {
this->_dispose(this); self->_dispose(self);
} }

View File

@ -1,30 +1,29 @@
#include <spine/AttachmentLoader.h> #include <spine/AttachmentLoader.h>
#include <spine/util.h> #include <spine/util.h>
void _AttachmentLoader_init (AttachmentLoader* this) { void _AttachmentLoader_init (AttachmentLoader* self) {
} }
void _AttachmentLoader_deinit (AttachmentLoader* this) { void _AttachmentLoader_deinit (AttachmentLoader* self) {
FREE(this->error1) FREE(self->error1)
FREE(this->error2) FREE(self->error2)
} }
void AttachmentLoader_dispose (AttachmentLoader* this) { void AttachmentLoader_dispose (AttachmentLoader* self) {
this->_dispose(this); self->_dispose(self);
} }
Attachment* AttachmentLoader_newAttachment (AttachmentLoader* this, AttachmentType type, const char* name) { Attachment* AttachmentLoader_newAttachment (AttachmentLoader* self, AttachmentType type, const char* name) {
FREE(this->error1) FREE(self->error1)
FREE(this->error2) FREE(self->error2)
this->error1 = 0; self->error1 = 0;
this->error2 = 0; self->error2 = 0;
return this->_newAttachment(this, type, name); return self->_newAttachment(self, type, name);
} }
void* _AttachmentLoader_setError (AttachmentLoader* this, const char* error1, const char* error2) { void _AttachmentLoader_setError (AttachmentLoader* self, const char* error1, const char* error2) {
FREE(this->error1) FREE(self->error1)
FREE(this->error2) FREE(self->error2)
MALLOC_STR(this->error1, error1) MALLOC_STR(self->error1, error1)
MALLOC_STR(this->error2, error2) MALLOC_STR(self->error2, error2)
return 0;
} }

View File

@ -9,57 +9,57 @@ void Bone_setYDown (int value) {
} }
Bone* Bone_create (BoneData* data, Bone* parent) { Bone* Bone_create (BoneData* data, Bone* parent) {
Bone* this = calloc(1, sizeof(Bone)); Bone* self = CALLOC(Bone, 1)
CAST(BoneData*, this->data) = data; CAST(BoneData*, self->data) = data;
CAST(Bone*, this->parent) = parent; CAST(Bone*, self->parent) = parent;
this->scaleX = 1; self->scaleX = 1;
this->scaleY = 1; self->scaleY = 1;
return this; return self;
} }
void Bone_dispose (Bone* this) { void Bone_dispose (Bone* self) {
FREE(this) FREE(self)
} }
void Bone_setToBindPose (Bone* this) { void Bone_setToBindPose (Bone* self) {
this->x = this->data->x; self->x = self->data->x;
this->y = this->data->y; self->y = self->data->y;
this->rotation = this->data->rotation; self->rotation = self->data->rotation;
this->scaleX = this->data->scaleX; self->scaleX = self->data->scaleX;
this->scaleY = this->data->scaleY; self->scaleY = self->data->scaleY;
} }
void Bone_updateWorldTransform (Bone* this, int flipX, int flipY) { void Bone_updateWorldTransform (Bone* self, int flipX, int flipY) {
if (this->parent) { if (self->parent) {
CAST(float, this->worldX) = this->x * this->parent->m00 + this->y * this->parent->m01 + this->parent->worldX; CAST(float, self->worldX) = self->x * self->parent->m00 + self->y * self->parent->m01 + self->parent->worldX;
CAST(float, this->worldY) = this->x * this->parent->m10 + this->y * this->parent->m11 + this->parent->worldY; CAST(float, self->worldY) = self->x * self->parent->m10 + self->y * self->parent->m11 + self->parent->worldY;
CAST(float, this->worldScaleX) = this->parent->worldScaleX * this->scaleX; CAST(float, self->worldScaleX) = self->parent->worldScaleX * self->scaleX;
CAST(float, this->worldScaleY) = this->parent->worldScaleY * this->scaleY; CAST(float, self->worldScaleY) = self->parent->worldScaleY * self->scaleY;
CAST(float, this->worldRotation) = this->parent->worldRotation + this->rotation; CAST(float, self->worldRotation) = self->parent->worldRotation + self->rotation;
} else { } else {
CAST(float, this->worldX) = this->x; CAST(float, self->worldX) = self->x;
CAST(float, this->worldY) = this->y; CAST(float, self->worldY) = self->y;
CAST(float, this->worldScaleX) = this->scaleX; CAST(float, self->worldScaleX) = self->scaleX;
CAST(float, this->worldScaleY) = this->scaleY; CAST(float, self->worldScaleY) = self->scaleY;
CAST(float, this->worldRotation) = this->rotation; CAST(float, self->worldRotation) = self->rotation;
} }
float radians = (float)(this->worldRotation * 3.1415926535897932385 / 180); float radians = (float)(self->worldRotation * 3.1415926535897932385 / 180);
float cosine = cos(radians); float cosine = cosf(radians);
float sine = sin(radians); float sine = sinf(radians);
CAST(float, this->m00) = cosine * this->worldScaleX; CAST(float, self->m00) = cosine * self->worldScaleX;
CAST(float, this->m10) = sine * this->worldScaleX; CAST(float, self->m10) = sine * self->worldScaleX;
CAST(float, this->m01) = -sine * this->worldScaleY; CAST(float, self->m01) = -sine * self->worldScaleY;
CAST(float, this->m11) = cosine * this->worldScaleY; CAST(float, self->m11) = cosine * self->worldScaleY;
if (flipX) { if (flipX) {
CAST(float, this->m00) = -this->m00; CAST(float, self->m00) = -self->m00;
CAST(float, this->m01) = -this->m01; CAST(float, self->m01) = -self->m01;
} }
if (flipY) { if (flipY) {
CAST(float, this->m10) = -this->m10; CAST(float, self->m10) = -self->m10;
CAST(float, this->m11) = -this->m11; CAST(float, self->m11) = -self->m11;
} }
if (yDown) { if (yDown) {
CAST(float, this->m10) = -this->m10; CAST(float, self->m10) = -self->m10;
CAST(float, this->m11) = -this->m11; CAST(float, self->m11) = -self->m11;
} }
} }

View File

@ -2,15 +2,15 @@
#include <spine/util.h> #include <spine/util.h>
BoneData* BoneData_create (const char* name, BoneData* parent) { BoneData* BoneData_create (const char* name, BoneData* parent) {
BoneData* this = calloc(1, sizeof(BoneData)); BoneData* self = CALLOC(BoneData, 1)
MALLOC_STR(this->name, name) MALLOC_STR(self->name, name)
CAST(BoneData*, this->parent) = parent; CAST(BoneData*, self->parent) = parent;
this->scaleX = 1; self->scaleX = 1;
this->scaleY = 1; self->scaleY = 1;
return this; return self;
} }
void BoneData_dispose (BoneData* this) { void BoneData_dispose (BoneData* self) {
FREE(this->name) FREE(self->name)
FREE(this) FREE(self)
} }

View File

@ -20,10 +20,10 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
/* cJSON */ /* Json */
/* JSON parser in C. */ /* JSON parser in C. */
#include <spine/cJSON.h> #include <spine/Json.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
@ -34,11 +34,11 @@
static const char* ep; static const char* ep;
const char* cJSON_GetErrorPtr (void) { const char* Json_getError (void) {
return ep; return ep;
} }
static int cJSON_strcasecmp (const char* s1, const char* s2) { static int Json_strcasecmp (const char* s1, const char* s2) {
if (!s1) return (s1 == s2) ? 0 : 1; if (!s1) return (s1 == s2) ? 0 : 1;
if (!s2) return 1; if (!s2) return 1;
for (; tolower(*s1) == tolower(*s2); ++s1, ++s2) for (; tolower(*s1) == tolower(*s2); ++s1, ++s2)
@ -47,17 +47,17 @@ static int cJSON_strcasecmp (const char* s1, const char* s2) {
} }
/* Internal constructor. */ /* Internal constructor. */
static cJSON *cJSON_create_Item (void) { static Json *Json_create_Item (void) {
return (cJSON*)calloc(1, sizeof(cJSON)); return (Json*)calloc(1, sizeof(Json));
} }
/* Delete a cJSON structure. */ /* Delete a Json structure. */
void cJSON_dispose (cJSON *c) { void Json_dispose (Json *c) {
cJSON *next; Json *next;
while (c) { while (c) {
next = c->next; next = c->next;
if (!(c->type & cJSON_IsReference) && c->child) cJSON_dispose(c->child); if (c->child) Json_dispose(c->child);
if (!(c->type & cJSON_IsReference) && c->valuestring) free((char*)c->valuestring); if (c->valuestring) free((char*)c->valuestring);
if (c->name) free((char*)c->name); if (c->name) free((char*)c->name);
free(c); free(c);
c = next; c = next;
@ -65,7 +65,7 @@ void cJSON_dispose (cJSON *c) {
} }
/* Parse the input text to generate a number, and populate the result into item. */ /* Parse the input text to generate a number, and populate the result into item. */
static const char* parse_number (cJSON *item, const char* num) { static const char* parse_number (Json *item, const char* num) {
float n = 0, sign = 1, scale = 0; float n = 0, sign = 1, scale = 0;
int subscale = 0, signsubscale = 1; int subscale = 0, signsubscale = 1;
@ -95,13 +95,13 @@ static const char* parse_number (cJSON *item, const char* num) {
item->valuefloat = n; item->valuefloat = n;
item->valueint = (int)n; item->valueint = (int)n;
item->type = cJSON_Number; item->type = Json_Number;
return num; return num;
} }
/* Parse the input text into an unescaped cstring, and populate item. */ /* Parse the input text into an unescaped cstring, and populate item. */
static const unsigned char firstByteMark[7] = {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC}; static const unsigned char firstByteMark[7] = {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC};
static const char* parse_string (cJSON *item, const char* str) { static const char* parse_string (Json *item, const char* str) {
const char* ptr = str + 1; const char* ptr = str + 1;
char* ptr2; char* ptr2;
char* out; char* out;
@ -189,14 +189,14 @@ static const char* parse_string (cJSON *item, const char* str) {
*ptr2 = 0; *ptr2 = 0;
if (*ptr == '\"') ptr++; if (*ptr == '\"') ptr++;
item->valuestring = out; item->valuestring = out;
item->type = cJSON_String; item->type = Json_String;
return ptr; return ptr;
} }
/* Predeclare these prototypes. */ /* Predeclare these prototypes. */
static const char* parse_value (cJSON *item, const char* value); static const char* parse_value (Json *item, const char* value);
static const char* parse_array (cJSON *item, const char* value); static const char* parse_array (Json *item, const char* value);
static const char* parse_object (cJSON *item, const char* value); static const char* parse_object (Json *item, const char* value);
/* Utility to jump whitespace and cr/lf */ /* Utility to jump whitespace and cr/lf */
static const char* skip (const char* in) { static const char* skip (const char* in) {
@ -206,49 +206,34 @@ static const char* skip (const char* in) {
} }
/* Parse an object - create a new root, and populate. */ /* Parse an object - create a new root, and populate. */
cJSON *cJSON_ParseWithOpts (const char* value, const char* *return_parse_end, int require_null_terminated) { Json *Json_create (const char* value) {
const char* end = 0; const char* end = 0;
cJSON *c = cJSON_create_Item(); Json *c = Json_create_Item();
ep = 0; ep = 0;
if (!c) return 0; /* memory fail */ if (!c) return 0; /* memory fail */
end = parse_value(c, skip(value)); end = parse_value(c, skip(value));
if (!end) { if (!end) {
cJSON_dispose(c); Json_dispose(c);
return 0; return 0;
} /* parse failure. ep is set. */ } /* parse failure. ep is set. */
/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
if (require_null_terminated) {
end = skip(end);
if (*end) {
cJSON_dispose(c);
ep = end;
return 0;
}
}
if (return_parse_end) *return_parse_end = end;
return c; return c;
} }
/* Default options for cJSON_Parse */
cJSON *cJSON_Parse (const char* value) {
return cJSON_ParseWithOpts(value, 0, 0);
}
/* Parser core - when encountering text, process appropriately. */ /* Parser core - when encountering text, process appropriately. */
static const char* parse_value (cJSON *item, const char* value) { static const char* parse_value (Json *item, const char* value) {
if (!value) return 0; /* Fail on null. */ if (!value) return 0; /* Fail on null. */
if (!strncmp(value, "null", 4)) { if (!strncmp(value, "null", 4)) {
item->type = cJSON_NULL; item->type = Json_NULL;
return value + 4; return value + 4;
} }
if (!strncmp(value, "false", 5)) { if (!strncmp(value, "false", 5)) {
item->type = cJSON_False; item->type = Json_False;
return value + 5; return value + 5;
} }
if (!strncmp(value, "true", 4)) { if (!strncmp(value, "true", 4)) {
item->type = cJSON_True; item->type = Json_True;
item->valueint = 1; item->valueint = 1;
return value + 4; return value + 4;
} }
@ -270,25 +255,25 @@ static const char* parse_value (cJSON *item, const char* value) {
} }
/* Build an array from input text. */ /* Build an array from input text. */
static const char* parse_array (cJSON *item, const char* value) { static const char* parse_array (Json *item, const char* value) {
cJSON *child; Json *child;
if (*value != '[') { if (*value != '[') {
ep = value; ep = value;
return 0; return 0;
} /* not an array! */ } /* not an array! */
item->type = cJSON_Array; item->type = Json_Array;
value = skip(value + 1); value = skip(value + 1);
if (*value == ']') return value + 1; /* empty array. */ if (*value == ']') return value + 1; /* empty array. */
item->child = child = cJSON_create_Item(); item->child = child = Json_create_Item();
if (!item->child) return 0; /* memory fail */ if (!item->child) return 0; /* memory fail */
value = skip(parse_value(child, skip(value))); /* skip any spacing, get the value. */ value = skip(parse_value(child, skip(value))); /* skip any spacing, get the value. */
if (!value) return 0; if (!value) return 0;
while (*value == ',') { while (*value == ',') {
cJSON *new_item; Json *new_item;
if (!(new_item = cJSON_create_Item())) return 0; /* memory fail */ if (!(new_item = Json_create_Item())) return 0; /* memory fail */
child->next = new_item; child->next = new_item;
new_item->prev = child; new_item->prev = child;
child = new_item; child = new_item;
@ -302,18 +287,18 @@ static const char* parse_array (cJSON *item, const char* value) {
} }
/* Build an object from the text. */ /* Build an object from the text. */
static const char* parse_object (cJSON *item, const char* value) { static const char* parse_object (Json *item, const char* value) {
cJSON *child; Json *child;
if (*value != '{') { if (*value != '{') {
ep = value; ep = value;
return 0; return 0;
} /* not an object! */ } /* not an object! */
item->type = cJSON_Object; item->type = Json_Object;
value = skip(value + 1); value = skip(value + 1);
if (*value == '}') return value + 1; /* empty array. */ if (*value == '}') return value + 1; /* empty array. */
item->child = child = cJSON_create_Item(); item->child = child = Json_create_Item();
if (!item->child) return 0; if (!item->child) return 0;
value = skip(parse_string(child, skip(value))); value = skip(parse_string(child, skip(value)));
if (!value) return 0; if (!value) return 0;
@ -327,8 +312,8 @@ static const char* parse_object (cJSON *item, const char* value) {
if (!value) return 0; if (!value) return 0;
while (*value == ',') { while (*value == ',') {
cJSON *new_item; Json *new_item;
if (!(new_item = cJSON_create_Item())) return 0; /* memory fail */ if (!(new_item = Json_create_Item())) return 0; /* memory fail */
child->next = new_item; child->next = new_item;
new_item->prev = child; new_item->prev = child;
child = new_item; child = new_item;
@ -350,40 +335,40 @@ static const char* parse_object (cJSON *item, const char* value) {
} }
/* Get Array size/item / object item. */ /* Get Array size/item / object item. */
int cJSON_GetArraySize (cJSON *array) { int Json_getSize (Json *array) {
cJSON *c = array->child; Json *c = array->child;
int i = 0; int i = 0;
while (c) while (c)
i++, c = c->next; i++, c = c->next;
return i; return i;
} }
cJSON *cJSON_GetArrayItem (cJSON *array, int item) { Json *Json_getItemAt (Json *array, int item) {
cJSON *c = array->child; Json *c = array->child;
while (c && item > 0) while (c && item > 0)
item--, c = c->next; item--, c = c->next;
return c; return c;
} }
cJSON *cJSON_GetObjectItem (cJSON *object, const char* string) { Json *Json_getItem (Json *object, const char* string) {
cJSON *c = object->child; Json *c = object->child;
while (c && cJSON_strcasecmp(c->name, string)) while (c && Json_strcasecmp(c->name, string))
c = c->next; c = c->next;
return c; return c;
} }
const char* cJSON_GetObjectString (cJSON* object, const char* name, const char* defaultValue) { const char* Json_getString (Json* object, const char* name, const char* defaultValue) {
object = cJSON_GetObjectItem(object, name); object = Json_getItem(object, name);
if (object) return object->valuestring; if (object) return object->valuestring;
return defaultValue; return defaultValue;
} }
float cJSON_GetObjectFloat (cJSON* value, const char* name, float defaultValue) { float Json_getFloat (Json* value, const char* name, float defaultValue) {
value = cJSON_GetObjectItem(value, name); value = Json_getItem(value, name);
return value ? value->valuefloat : defaultValue; return value ? value->valuefloat : defaultValue;
} }
int cJSON_GetObjectInt (cJSON* value, const char* name, int defaultValue) { int Json_getInt (Json* value, const char* name, int defaultValue) {
value = cJSON_GetObjectItem(value, name); value = Json_getItem(value, name);
return value ? value->valuefloat : defaultValue; return value ? value->valuefloat : defaultValue;
} }

85
spine-c/src/spine/Json.h Normal file
View File

@ -0,0 +1,85 @@
/*
Copyright (c) 2009 Dave Gamble
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/* Esoteric Software: Removed everything except parsing, shorter method names, more get methods, double to float, formatted. */
#ifndef SPINE_JSON_H_
#define SPINE_JSON_H_
#include <stdlib.h>
#ifdef __cplusplus
namespace spine {
extern "C" {
#endif
/* Json Types: */
#define Json_False 0
#define Json_True 1
#define Json_NULL 2
#define Json_Number 3
#define Json_String 4
#define Json_Array 5
#define Json_Object 6
/* The Json structure: */
typedef struct Json {
struct Json* next;
struct Json* prev; /* next/prev allow you to walk array/object chains. Alternatively, use getSize/getItemAt/getItem */
struct Json* child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
int type; /* The type of the item, as above. */
const char* valuestring; /* The item's string, if type==Json_String */
int valueint; /* The item's number, if type==Json_Number */
float valuefloat; /* The item's number, if type==Json_Number */
const char* name; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} Json;
/* Supply a block of JSON, and this returns a Json object you can interrogate. Call Json_dispose when finished. */
extern Json* Json_create (const char* value);
/* Delete a Json entity and all subentities. */
extern void Json_dispose (Json* json);
/* Returns the number of items in an array (or object). */
extern int Json_getSize (Json* json);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
extern Json* Json_getItemAt (Json* json, int item);
/* Get item "string" from object. Case insensitive. */
extern Json* Json_getItem (Json* json, const char* string);
extern const char* Json_getString (Json* json, const char* name, const char* defaultValue);
extern float Json_getFloat (Json* json, const char* name, float defaultValue);
extern int Json_getInt (Json* json, const char* name, int defaultValue);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when Json_create() returns 0. 0 when Json_create() succeeds. */
extern const char* Json_getError (void);
#ifdef __cplusplus
}
}
#endif
#endif /* SPINE_JSON_H_ */

View File

@ -3,42 +3,42 @@
#include <spine/util.h> #include <spine/util.h>
#include <spine/extension.h> #include <spine/extension.h>
void _RegionAttachment_init (RegionAttachment* this, const char* name) { void _RegionAttachment_init (RegionAttachment* self, const char* name) {
this->scaleX = 1; self->scaleX = 1;
this->scaleY = 1; self->scaleY = 1;
_Attachment_init(&this->super, name, ATTACHMENT_REGION); _Attachment_init(&self->super, name, ATTACHMENT_REGION);
} }
void _RegionAttachment_deinit (RegionAttachment* this) { void _RegionAttachment_deinit (RegionAttachment* self) {
_Attachment_deinit(&this->super); _Attachment_deinit(&self->super);
} }
void RegionAttachment_updateOffset (RegionAttachment* this) { void RegionAttachment_updateOffset (RegionAttachment* self) {
float localX2 = this->width / 2; float localX2 = self->width / 2;
float localY2 = this->height / 2; float localY2 = self->height / 2;
float localX = -localX2; float localX = -localX2;
float localY = -localY2; float localY = -localY2;
localX *= this->scaleX; localX *= self->scaleX;
localY *= this->scaleY; localY *= self->scaleY;
localX2 *= this->scaleX; localX2 *= self->scaleX;
localY2 *= this->scaleY; localY2 *= self->scaleY;
float radians = (float)(this->rotation * 3.1415926535897932385 / 180); float radians = (float)(self->rotation * 3.1415926535897932385 / 180);
float cosine = cos(radians); float cosine = cosf(radians);
float sine = sin(radians); float sine = sinf(radians);
float localXCos = localX * cosine + this->x; float localXCos = localX * cosine + self->x;
float localXSin = localX * sine; float localXSin = localX * sine;
float localYCos = localY * cosine + this->y; float localYCos = localY * cosine + self->y;
float localYSin = localY * sine; float localYSin = localY * sine;
float localX2Cos = localX2 * cosine + this->x; float localX2Cos = localX2 * cosine + self->x;
float localX2Sin = localX2 * sine; float localX2Sin = localX2 * sine;
float localY2Cos = localY2 * cosine + this->y; float localY2Cos = localY2 * cosine + self->y;
float localY2Sin = localY2 * sine; float localY2Sin = localY2 * sine;
this->offset[0] = localXCos - localYSin; self->offset[0] = localXCos - localYSin;
this->offset[1] = localYCos + localXSin; self->offset[1] = localYCos + localXSin;
this->offset[2] = localXCos - localY2Sin; self->offset[2] = localXCos - localY2Sin;
this->offset[3] = localY2Cos + localXSin; self->offset[3] = localY2Cos + localXSin;
this->offset[4] = localX2Cos - localY2Sin; self->offset[4] = localX2Cos - localY2Sin;
this->offset[5] = localY2Cos + localX2Sin; self->offset[5] = localY2Cos + localX2Sin;
this->offset[6] = localX2Cos - localYSin; self->offset[6] = localX2Cos - localYSin;
this->offset[7] = localYCos + localX2Sin; self->offset[7] = localYCos + localX2Sin;
} }

View File

@ -1,134 +1,134 @@
#include <spine/Skeleton.h> #include <spine/Skeleton.h>
#include <spine/util.h> #include <spine/util.h>
void _Skeleton_init (Skeleton* this, SkeletonData* data) { void _Skeleton_init (Skeleton* self, SkeletonData* data) {
CAST(SkeletonData*, this->data) = data; CAST(SkeletonData*, self->data) = data;
this->boneCount = this->data->boneCount; self->boneCount = self->data->boneCount;
this->bones = malloc(sizeof(Bone*) * this->boneCount); self->bones = MALLOC(Bone*, self->boneCount)
int i, ii; int i, ii;
for (i = 0; i < this->boneCount; ++i) { for (i = 0; i < self->boneCount; ++i) {
BoneData* boneData = this->data->bones[i]; BoneData* boneData = self->data->bones[i];
Bone* parent = 0; Bone* parent = 0;
if (boneData->parent) { if (boneData->parent) {
/* Find parent bone. */ /* Find parent bone. */
for (ii = 0; ii < this->boneCount; ++ii) { for (ii = 0; ii < self->boneCount; ++ii) {
if (data->bones[ii] == boneData->parent) { if (data->bones[ii] == boneData->parent) {
parent = this->bones[ii]; parent = self->bones[ii];
break; break;
} }
} }
} }
this->bones[i] = Bone_create(boneData, parent); self->bones[i] = Bone_create(boneData, parent);
} }
this->slotCount = data->slotCount; self->slotCount = data->slotCount;
this->slots = malloc(sizeof(Slot*) * this->slotCount); self->slots = MALLOC(Slot*, self->slotCount)
for (i = 0; i < this->slotCount; ++i) { for (i = 0; i < self->slotCount; ++i) {
SlotData *slotData = data->slots[i]; SlotData *slotData = data->slots[i];
/* Find bone for the slotData's boneData. */ /* Find bone for the slotData's boneData. */
Bone *bone; Bone *bone;
for (ii = 0; ii < this->boneCount; ++ii) { for (ii = 0; ii < self->boneCount; ++ii) {
if (data->bones[ii] == slotData->boneData) { if (data->bones[ii] == slotData->boneData) {
bone = this->bones[ii]; bone = self->bones[ii];
break; break;
} }
} }
this->slots[i] = Slot_create(slotData, this, bone); self->slots[i] = Slot_create(slotData, self, bone);
} }
this->drawOrder = malloc(sizeof(Slot*) * this->slotCount); self->drawOrder = MALLOC(Slot*, self->slotCount)
memcpy(this->drawOrder, this->slots, sizeof(Slot*) * this->slotCount); memcpy(self->drawOrder, self->slots, sizeof(Slot*) * self->slotCount);
} }
void _Skeleton_deinit (Skeleton* this) { void _Skeleton_deinit (Skeleton* self) {
int i; int i;
for (i = 0; i < this->boneCount; ++i) for (i = 0; i < self->boneCount; ++i)
Bone_dispose(this->bones[i]); Bone_dispose(self->bones[i]);
FREE(this->bones) FREE(self->bones)
for (i = 0; i < this->slotCount; ++i) for (i = 0; i < self->slotCount; ++i)
Slot_dispose(this->slots[i]); Slot_dispose(self->slots[i]);
FREE(this->slots) FREE(self->slots)
FREE(this->drawOrder) FREE(self->drawOrder)
} }
void Skeleton_dispose (Skeleton* this) { void Skeleton_dispose (Skeleton* self) {
this->_dispose(this); self->_dispose(self);
} }
void Skeleton_updateWorldTransform (const Skeleton* this) { void Skeleton_updateWorldTransform (const Skeleton* self) {
int i; int i;
for (i = 0; i < this->boneCount; ++i) for (i = 0; i < self->boneCount; ++i)
Bone_updateWorldTransform(this->bones[i], this->flipX, this->flipY); Bone_updateWorldTransform(self->bones[i], self->flipX, self->flipY);
} }
void Skeleton_setToBindPose (const Skeleton* this) { void Skeleton_setToBindPose (const Skeleton* self) {
Skeleton_setBonesToBindPose(this); Skeleton_setBonesToBindPose(self);
Skeleton_setSlotsToBindPose(this); Skeleton_setSlotsToBindPose(self);
} }
void Skeleton_setBonesToBindPose (const Skeleton* this) { void Skeleton_setBonesToBindPose (const Skeleton* self) {
int i; int i;
for (i = 0; i < this->boneCount; ++i) for (i = 0; i < self->boneCount; ++i)
Bone_setToBindPose(this->bones[i]); Bone_setToBindPose(self->bones[i]);
} }
void Skeleton_setSlotsToBindPose (const Skeleton* this) { void Skeleton_setSlotsToBindPose (const Skeleton* self) {
int i; int i;
for (i = 0; i < this->slotCount; ++i) for (i = 0; i < self->slotCount; ++i)
Slot_setToBindPose(this->slots[i]); Slot_setToBindPose(self->slots[i]);
} }
Bone* Skeleton_getRootBone (const Skeleton* this) { Bone* Skeleton_getRootBone (const Skeleton* self) {
if (this->boneCount == 0) return 0; if (self->boneCount == 0) return 0;
return this->bones[0]; return self->bones[0];
} }
Bone* Skeleton_findBone (const Skeleton* this, const char* boneName) { Bone* Skeleton_findBone (const Skeleton* self, const char* boneName) {
int i; int i;
for (i = 0; i < this->boneCount; ++i) for (i = 0; i < self->boneCount; ++i)
if (this->data->bones[i]->name == boneName) return this->bones[i]; if (self->data->bones[i]->name == boneName) return self->bones[i];
return 0; return 0;
} }
int Skeleton_findBoneIndex (const Skeleton* this, const char* boneName) { int Skeleton_findBoneIndex (const Skeleton* self, const char* boneName) {
int i; int i;
for (i = 0; i < this->boneCount; ++i) for (i = 0; i < self->boneCount; ++i)
if (this->data->bones[i]->name == boneName) return i; if (self->data->bones[i]->name == boneName) return i;
return -1; return -1;
} }
Slot* Skeleton_findSlot (const Skeleton* this, const char* slotName) { Slot* Skeleton_findSlot (const Skeleton* self, const char* slotName) {
int i; int i;
for (i = 0; i < this->slotCount; ++i) for (i = 0; i < self->slotCount; ++i)
if (this->data->slots[i]->name == slotName) return this->slots[i]; if (self->data->slots[i]->name == slotName) return self->slots[i];
return 0; return 0;
} }
int Skeleton_findSlotIndex (const Skeleton* this, const char* slotName) { int Skeleton_findSlotIndex (const Skeleton* self, const char* slotName) {
int i; int i;
for (i = 0; i < this->slotCount; ++i) for (i = 0; i < self->slotCount; ++i)
if (this->data->slots[i]->name == slotName) return i; if (self->data->slots[i]->name == slotName) return i;
return -1; return -1;
} }
int Skeleton_setSkinByName (Skeleton* this, const char* skinName) { int Skeleton_setSkinByName (Skeleton* self, const char* skinName) {
Skin *skin = SkeletonData_findSkin(this->data, skinName); Skin *skin = SkeletonData_findSkin(self->data, skinName);
if (!skin) return 0; if (!skin) return 0;
Skeleton_setSkin(this, skin); Skeleton_setSkin(self, skin);
return 1; return 1;
} }
void Skeleton_setSkin (Skeleton* this, Skin* newSkin) { void Skeleton_setSkin (Skeleton* self, Skin* newSkin) {
if (this->skin && newSkin) { if (self->skin && newSkin) {
/* Attach each attachment in the new skin if the corresponding attachment in the old skin is currently attached. */ /* Attach each attachment in the new skin if the corresponding attachment in the old skin is currently attached. */
const SkinEntry *entry = this->skin->entries; const SkinEntry *entry = self->skin->entries;
while (entry) { while (entry) {
Slot *slot = this->slots[entry->slotIndex]; Slot *slot = self->slots[entry->slotIndex];
if (slot->attachment == entry->attachment) { if (slot->attachment == entry->attachment) {
Attachment *attachment = Skin_getAttachment(newSkin, entry->slotIndex, entry->name); Attachment *attachment = Skin_getAttachment(newSkin, entry->slotIndex, entry->name);
if (attachment) Slot_setAttachment(slot, attachment); if (attachment) Slot_setAttachment(slot, attachment);
@ -136,33 +136,33 @@ void Skeleton_setSkin (Skeleton* this, Skin* newSkin) {
entry = entry->next; entry = entry->next;
} }
} }
CAST(Skin*, this->skin) = newSkin; CAST(Skin*, self->skin) = newSkin;
} }
Attachment* Skeleton_getAttachmentForSlotName (const Skeleton* this, const char* slotName, const char* attachmentName) { Attachment* Skeleton_getAttachmentForSlotName (const Skeleton* self, const char* slotName, const char* attachmentName) {
int slotIndex = SkeletonData_findSlotIndex(this->data, slotName); int slotIndex = SkeletonData_findSlotIndex(self->data, slotName);
return Skeleton_getAttachmentForSlotIndex(this, slotIndex, attachmentName); return Skeleton_getAttachmentForSlotIndex(self, slotIndex, attachmentName);
} }
Attachment* Skeleton_getAttachmentForSlotIndex (const Skeleton* this, int slotIndex, const char* attachmentName) { Attachment* Skeleton_getAttachmentForSlotIndex (const Skeleton* self, int slotIndex, const char* attachmentName) {
if (slotIndex == -1) return 0; if (slotIndex == -1) return 0;
if (this->skin) { if (self->skin) {
Attachment *attachment = Skin_getAttachment(this->skin, slotIndex, attachmentName); Attachment *attachment = Skin_getAttachment(self->skin, slotIndex, attachmentName);
if (attachment) return attachment; if (attachment) return attachment;
} }
if (this->data->defaultSkin) { if (self->data->defaultSkin) {
Attachment *attachment = Skin_getAttachment(this->data->defaultSkin, slotIndex, attachmentName); Attachment *attachment = Skin_getAttachment(self->data->defaultSkin, slotIndex, attachmentName);
if (attachment) return attachment; if (attachment) return attachment;
} }
return 0; return 0;
} }
int Skeleton_setAttachment (Skeleton* this, const char* slotName, const char* attachmentName) { int Skeleton_setAttachment (Skeleton* self, const char* slotName, const char* attachmentName) {
int i; int i;
for (i = 0; i < this->slotCount; ++i) { for (i = 0; i < self->slotCount; ++i) {
Slot *slot = this->slots[i]; Slot *slot = self->slots[i];
if (slot->data->name == slotName) { if (slot->data->name == slotName) {
Attachment* attachment = Skeleton_getAttachmentForSlotIndex(this, i, attachmentName); Attachment* attachment = Skeleton_getAttachmentForSlotIndex(self, i, attachmentName);
if (!attachment) return 0; if (!attachment) return 0;
Slot_setAttachment(slot, attachment); Slot_setAttachment(slot, attachment);
return 1; return 1;
@ -171,6 +171,6 @@ int Skeleton_setAttachment (Skeleton* this, const char* slotName, const char* at
return 0; return 0;
} }
void Skeleton_update (Skeleton* this, float deltaTime) { void Skeleton_update (Skeleton* self, float deltaTime) {
this->time += deltaTime; self->time += deltaTime;
} }

View File

@ -2,45 +2,45 @@
#include <spine/util.h> #include <spine/util.h>
SkeletonData* SkeletonData_create () { SkeletonData* SkeletonData_create () {
SkeletonData* this = calloc(1, sizeof(SkeletonData)); SkeletonData* self = CALLOC(SkeletonData, 1)
return this; return self;
} }
void SkeletonData_dispose (SkeletonData* this) { void SkeletonData_dispose (SkeletonData* self) {
FREE(this) FREE(self)
} }
BoneData* SkeletonData_findBone (const SkeletonData* this, const char* boneName) { BoneData* SkeletonData_findBone (const SkeletonData* self, const char* boneName) {
int i; int i;
for (i = 0; i < this->boneCount; ++i) for (i = 0; i < self->boneCount; ++i)
if (strcmp(this->bones[i]->name, boneName) == 0) return this->bones[i]; if (strcmp(self->bones[i]->name, boneName) == 0) return self->bones[i];
return 0; return 0;
} }
int SkeletonData_findBoneIndex (const SkeletonData* this, const char* boneName) { int SkeletonData_findBoneIndex (const SkeletonData* self, const char* boneName) {
int i; int i;
for (i = 0; i < this->boneCount; ++i) for (i = 0; i < self->boneCount; ++i)
if (strcmp(this->bones[i]->name, boneName) == 0) return i; if (strcmp(self->bones[i]->name, boneName) == 0) return i;
return 0; return 0;
} }
SlotData* SkeletonData_findSlot (const SkeletonData* this, const char* slotName) { SlotData* SkeletonData_findSlot (const SkeletonData* self, const char* slotName) {
int i; int i;
for (i = 0; i < this->slotCount; ++i) for (i = 0; i < self->slotCount; ++i)
if (strcmp(this->slots[i]->name, slotName) == 0) return this->slots[i]; if (strcmp(self->slots[i]->name, slotName) == 0) return self->slots[i];
return 0; return 0;
} }
int SkeletonData_findSlotIndex (const SkeletonData* this, const char* slotName) { int SkeletonData_findSlotIndex (const SkeletonData* self, const char* slotName) {
int i; int i;
for (i = 0; i < this->slotCount; ++i) for (i = 0; i < self->slotCount; ++i)
if (strcmp(this->slots[i]->name, slotName) == 0) return i; if (strcmp(self->slots[i]->name, slotName) == 0) return i;
return 0; return 0;
} }
Skin* SkeletonData_findSkin (const SkeletonData* this, const char* skinName) { Skin* SkeletonData_findSkin (const SkeletonData* self, const char* skinName) {
int i; int i;
for (i = 0; i < this->skinCount; ++i) for (i = 0; i < self->skinCount; ++i)
if (strcmp(this->skins[i]->name, skinName) == 0) return this->skins[i]; if (strcmp(self->skins[i]->name, skinName) == 0) return self->skins[i];
return 0; return 0;
} }

View File

@ -2,44 +2,44 @@
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#include <spine/util.h> #include <spine/util.h>
#include <spine/cJSON.h> #include <math.h>
#include <spine/Json.h>
#include <spine/RegionAttachment.h> #include <spine/RegionAttachment.h>
#include <spine/AtlasAttachmentLoader.h> #include <spine/AtlasAttachmentLoader.h>
typedef struct { typedef struct {
SkeletonJson json; SkeletonJson json;
int ownsLoader; int ownsLoader;
} Private; } Internal;
SkeletonJson* SkeletonJson_createWithLoader (AttachmentLoader* attachmentLoader) { SkeletonJson* SkeletonJson_createWithLoader (AttachmentLoader* attachmentLoader) {
SkeletonJson* this = calloc(1, sizeof(Private)); SkeletonJson* self = (SkeletonJson*)CALLOC(Internal, 1)
this->scale = 1; self->scale = 1;
this->attachmentLoader = attachmentLoader; self->attachmentLoader = attachmentLoader;
return this; return self;
} }
SkeletonJson* SkeletonJson_create (Atlas* atlas) { SkeletonJson* SkeletonJson_create (Atlas* atlas) {
AtlasAttachmentLoader* attachmentLoader = AtlasAttachmentLoader_create(atlas); AtlasAttachmentLoader* attachmentLoader = AtlasAttachmentLoader_create(atlas);
Private* this = (Private*)SkeletonJson_createWithLoader(&attachmentLoader->super); Internal* self = (Internal*)SkeletonJson_createWithLoader(&attachmentLoader->super);
this->ownsLoader = 1; self->ownsLoader = 1;
return &this->json; return &self->json;
} }
void SkeletonJson_dispose (SkeletonJson* this) { void SkeletonJson_dispose (SkeletonJson* self) {
if (((Private*)this)->ownsLoader) AttachmentLoader_dispose(this->attachmentLoader); if (((Internal*)self)->ownsLoader) AttachmentLoader_dispose(self->attachmentLoader);
FREE(this->error) FREE(self->error)
FREE(this) FREE(self)
} }
void* _SkeletonJson_setError (SkeletonJson* this, cJSON* root, const char* value1, const char* value2) { void _SkeletonJson_setError (SkeletonJson* self, Json* root, const char* value1, const char* value2) {
FREE(this->error) FREE(self->error)
char message[256]; char message[256];
strcpy(message, value1); strcpy(message, value1);
int length = strlen(value1); int length = strlen(value1);
if (value2) strncat(message + length, value2, 256 - length); if (value2) strncat(message + length, value2, 256 - length);
MALLOC_STR(this->error, message) MALLOC_STR(self->error, message)
if (root) cJSON_dispose(root); if (root) Json_dispose(root);
return 0;
} }
static float toColor (const char* value, int index) { static float toColor (const char* value, int index) {
@ -55,67 +55,81 @@ static float toColor (const char* value, int index) {
return color / (float)255; return color / (float)255;
} }
SkeletonData* SkeletonJson_readSkeletonDataFile (SkeletonJson* this, const char* path) { SkeletonData* SkeletonJson_readSkeletonDataFile (SkeletonJson* self, const char* path) {
const char* data = readFile(path); const char* data = readFile(path);
if (!data) return _SkeletonJson_setError(this, 0, "Unable to read file: ", path); if (!data) {
SkeletonData* skeletonData = SkeletonJson_readSkeletonData(this, data); _SkeletonJson_setError(self, 0, "Unable to read skeleton file: ", path);
return 0;
}
SkeletonData* skeletonData = SkeletonJson_readSkeletonData(self, data);
FREE(data) FREE(data)
return skeletonData; return skeletonData;
} }
SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* this, const char* json) { SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* self, const char* json) {
FREE(this->error) FREE(self->error)
CAST(char*, this->error) = 0; CAST(char*, self->error) = 0;
cJSON* root = cJSON_Parse(json); Json* root = Json_create(json);
if (!root) return _SkeletonJson_setError(this, 0, "Invalid JSON: ", cJSON_GetErrorPtr()); if (!root) {
_SkeletonJson_setError(self, 0, "Invalid skeleton JSON: ", Json_getError());
return 0;
}
SkeletonData* skeletonData = SkeletonData_create(); SkeletonData* skeletonData = SkeletonData_create();
int i, ii, iii; int i, ii, iii;
cJSON* bones = cJSON_GetObjectItem(root, "bones"); Json* bones = Json_getItem(root, "bones");
int boneCount = cJSON_GetArraySize(bones); int boneCount = Json_getSize(bones);
skeletonData->bones = malloc(sizeof(BoneData*) * boneCount); skeletonData->bones = MALLOC(BoneData*, boneCount)
for (i = 0; i < boneCount; ++i) { for (i = 0; i < boneCount; ++i) {
cJSON* boneMap = cJSON_GetArrayItem(bones, i); Json* boneMap = Json_getItemAt(bones, i);
const char* boneName = cJSON_GetObjectString(boneMap, "name", 0); const char* boneName = Json_getString(boneMap, "name", 0);
BoneData* parent = 0; BoneData* parent = 0;
const char* parentName = cJSON_GetObjectString(boneMap, "parent", 0); const char* parentName = Json_getString(boneMap, "parent", 0);
if (parentName) { if (parentName) {
parent = SkeletonData_findBone(skeletonData, parentName); parent = SkeletonData_findBone(skeletonData, parentName);
if (!parent) return _SkeletonJson_setError(this, root, "Parent bone not found: ", parentName); if (!parent) {
SkeletonData_dispose(skeletonData);
_SkeletonJson_setError(self, root, "Parent bone not found: ", parentName);
return 0;
}
} }
BoneData* boneData = BoneData_create(boneName, parent); BoneData* boneData = BoneData_create(boneName, parent);
boneData->length = cJSON_GetObjectFloat(boneMap, "parent", 0) * this->scale; boneData->length = Json_getFloat(boneMap, "parent", 0) * self->scale;
boneData->x = cJSON_GetObjectFloat(boneMap, "x", 0) * this->scale; boneData->x = Json_getFloat(boneMap, "x", 0) * self->scale;
boneData->y = cJSON_GetObjectFloat(boneMap, "y", 0) * this->scale; boneData->y = Json_getFloat(boneMap, "y", 0) * self->scale;
boneData->rotation = cJSON_GetObjectFloat(boneMap, "rotation", 0); boneData->rotation = Json_getFloat(boneMap, "rotation", 0);
boneData->scaleX = cJSON_GetObjectFloat(boneMap, "scaleX", 1); boneData->scaleX = Json_getFloat(boneMap, "scaleX", 1);
boneData->scaleY = cJSON_GetObjectFloat(boneMap, "scaleY", 1); boneData->scaleY = Json_getFloat(boneMap, "scaleY", 1);
skeletonData->bones[i] = boneData; skeletonData->bones[i] = boneData;
skeletonData->boneCount++; skeletonData->boneCount++;
} }
cJSON* slots = cJSON_GetObjectItem(root, "slots"); Json* slots = Json_getItem(root, "slots");
if (slots) { if (slots) {
int slotCount = cJSON_GetArraySize(slots); int slotCount = Json_getSize(slots);
skeletonData->slots = malloc(sizeof(SlotData*) * slotCount); skeletonData->slots = MALLOC(SlotData*, slotCount)
for (i = 0; i < slotCount; ++i) { for (i = 0; i < slotCount; ++i) {
cJSON* slotMap = cJSON_GetArrayItem(slots, i); Json* slotMap = Json_getItemAt(slots, i);
const char* slotName = cJSON_GetObjectString(slotMap, "name", 0); const char* slotName = Json_getString(slotMap, "name", 0);
const char* boneName = cJSON_GetObjectString(slotMap, "bone", 0); const char* boneName = Json_getString(slotMap, "bone", 0);
BoneData* boneData = SkeletonData_findBone(skeletonData, boneName); BoneData* boneData = SkeletonData_findBone(skeletonData, boneName);
if (!boneData) return _SkeletonJson_setError(this, root, "Slot bone not found: ", boneName); if (!boneData) {
SkeletonData_dispose(skeletonData);
_SkeletonJson_setError(self, root, "Slot bone not found: ", boneName);
return 0;
}
SlotData* slotData = SlotData_create(slotName, boneData); SlotData* slotData = SlotData_create(slotName, boneData);
const char* color = cJSON_GetObjectString(slotMap, "color", 0); const char* color = Json_getString(slotMap, "color", 0);
if (color) { if (color) {
slotData->r = toColor(color, 0); slotData->r = toColor(color, 0);
slotData->g = toColor(color, 1); slotData->g = toColor(color, 1);
@ -123,7 +137,7 @@ SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* this, const char* jso
slotData->a = toColor(color, 3); slotData->a = toColor(color, 3);
} }
cJSON *attachmentItem = cJSON_GetObjectItem(slotMap, "attachment"); Json *attachmentItem = Json_getItem(slotMap, "attachment");
if (attachmentItem) SlotData_setAttachmentName(slotData, attachmentItem->valuestring); if (attachmentItem) SlotData_setAttachmentName(slotData, attachmentItem->valuestring);
skeletonData->slots[i] = slotData; skeletonData->slots[i] = slotData;
@ -131,52 +145,58 @@ SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* this, const char* jso
} }
} }
cJSON* skinsMap = cJSON_GetObjectItem(root, "skins"); Json* skinsMap = Json_getItem(root, "skins");
if (skinsMap) { if (skinsMap) {
int skinCount = cJSON_GetArraySize(skinsMap); int skinCount = Json_getSize(skinsMap);
skeletonData->skins = malloc(sizeof(Skin*) * skinCount); skeletonData->skins = MALLOC(Skin*, skinCount)
for (i = 0; i < skinCount; ++i) { for (i = 0; i < skinCount; ++i) {
cJSON* slotMap = cJSON_GetArrayItem(skinsMap, i); Json* slotMap = Json_getItemAt(skinsMap, i);
const char* skinName = slotMap->name; const char* skinName = slotMap->name;
Skin *skin = Skin_create(skinName); Skin *skin = Skin_create(skinName);
skeletonData->skins[i] = skin; skeletonData->skins[i] = skin;
skeletonData->skinCount++; skeletonData->skinCount++;
if (strcmp(skinName, "default") == 0) skeletonData->defaultSkin = skin; if (strcmp(skinName, "default") == 0) skeletonData->defaultSkin = skin;
int slotNameCount = cJSON_GetArraySize(slotMap); int slotNameCount = Json_getSize(slotMap);
for (ii = 0; ii < slotNameCount; ++ii) { for (ii = 0; ii < slotNameCount; ++ii) {
cJSON* attachmentsMap = cJSON_GetArrayItem(slotMap, ii); Json* attachmentsMap = Json_getItemAt(slotMap, ii);
const char* slotName = attachmentsMap->name; const char* slotName = attachmentsMap->name;
int slotIndex = SkeletonData_findSlotIndex(skeletonData, slotName); int slotIndex = SkeletonData_findSlotIndex(skeletonData, slotName);
int attachmentCount = cJSON_GetArraySize(attachmentsMap); int attachmentCount = Json_getSize(attachmentsMap);
for (iii = 0; iii < attachmentCount; ++iii) { for (iii = 0; iii < attachmentCount; ++iii) {
cJSON* attachmentMap = cJSON_GetArrayItem(attachmentsMap, iii); Json* attachmentMap = Json_getItemAt(attachmentsMap, iii);
const char* skinAttachmentName = attachmentMap->name; const char* skinAttachmentName = attachmentMap->name;
const char* attachmentName = cJSON_GetObjectString(attachmentMap, "name", skinAttachmentName); const char* attachmentName = Json_getString(attachmentMap, "name", skinAttachmentName);
const char* typeString = cJSON_GetObjectString(attachmentMap, "type", "region"); const char* typeString = Json_getString(attachmentMap, "type", "region");
AttachmentType type; AttachmentType type;
if (strcmp(typeString, "region") == 0) if (strcmp(typeString, "region") == 0)
type = ATTACHMENT_REGION; type = ATTACHMENT_REGION;
else if (strcmp(typeString, "regionSequence") == 0) else if (strcmp(typeString, "regionSequence") == 0)
type = ATTACHMENT_REGION_SEQUENCE; type = ATTACHMENT_REGION_SEQUENCE;
else else {
return _SkeletonJson_setError(this, root, "Unknown attachment type: ", typeString); SkeletonData_dispose(skeletonData);
_SkeletonJson_setError(self, root, "Unknown attachment type: ", typeString);
return 0;
}
Attachment* attachment = AttachmentLoader_newAttachment(this->attachmentLoader, type, attachmentName); Attachment* attachment = AttachmentLoader_newAttachment(self->attachmentLoader, type, attachmentName);
if (!attachment && this->attachmentLoader->error1) if (!attachment && self->attachmentLoader->error1) {
return _SkeletonJson_setError(this, root, this->attachmentLoader->error1, this->attachmentLoader->error2); SkeletonData_dispose(skeletonData);
_SkeletonJson_setError(self, root, self->attachmentLoader->error1, self->attachmentLoader->error2);
return 0;
}
if (attachment->type == ATTACHMENT_REGION || attachment->type == ATTACHMENT_REGION_SEQUENCE) { if (attachment->type == ATTACHMENT_REGION || attachment->type == ATTACHMENT_REGION_SEQUENCE) {
RegionAttachment* regionAttachment = (RegionAttachment*)attachment; RegionAttachment* regionAttachment = (RegionAttachment*)attachment;
regionAttachment->x = cJSON_GetObjectFloat(attachmentMap, "x", 0) * this->scale; regionAttachment->x = Json_getFloat(attachmentMap, "x", 0) * self->scale;
regionAttachment->y = cJSON_GetObjectFloat(attachmentMap, "y", 0) * this->scale; regionAttachment->y = Json_getFloat(attachmentMap, "y", 0) * self->scale;
regionAttachment->scaleX = cJSON_GetObjectFloat(attachmentMap, "scaleX", 1); regionAttachment->scaleX = Json_getFloat(attachmentMap, "scaleX", 1);
regionAttachment->scaleY = cJSON_GetObjectFloat(attachmentMap, "scaleY", 1); regionAttachment->scaleY = Json_getFloat(attachmentMap, "scaleY", 1);
regionAttachment->rotation = cJSON_GetObjectFloat(attachmentMap, "rotation", 0); regionAttachment->rotation = Json_getFloat(attachmentMap, "rotation", 0);
regionAttachment->width = cJSON_GetObjectFloat(attachmentMap, "width", 32) * this->scale; regionAttachment->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
regionAttachment->height = cJSON_GetObjectFloat(attachmentMap, "height", 32) * this->scale; regionAttachment->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
RegionAttachment_updateOffset(regionAttachment); RegionAttachment_updateOffset(regionAttachment);
} }
@ -186,6 +206,160 @@ SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* this, const char* jso
} }
} }
cJSON_dispose(root); Json_dispose(root);
return skeletonData; return skeletonData;
} }
Animation* SkeletonJson_readAnimationFile (SkeletonJson* self, const char* path, const SkeletonData *skeletonData) {
const char* data = readFile(path);
if (!data) {
_SkeletonJson_setError(self, 0, "Unable to read animation file: ", path);
return 0;
}
Animation* animation = SkeletonJson_readAnimation(self, data, skeletonData);
FREE(data)
return animation;
}
static void readCurve (CurveTimeline* timeline, int frameIndex, Json* frame) {
Json* curve = Json_getItem(frame, "curve");
if (!curve) return;
if (curve->type == Json_String && strcmp(curve->valuestring, "stepped") == 0)
CurveTimeline_setStepped(timeline, frameIndex);
else if (curve->type == Json_Array) {
CurveTimeline_setCurve(timeline, frameIndex, Json_getItemAt(curve, 0)->valuefloat, Json_getItemAt(curve, 1)->valuefloat,
Json_getItemAt(curve, 2)->valuefloat, Json_getItemAt(curve, 3)->valuefloat);
}
}
Animation* SkeletonJson_readAnimation (SkeletonJson* self, const char* json, const SkeletonData *skeletonData) {
FREE(self->error)
CAST(char*, self->error) = 0;
Json* root = Json_create(json);
if (!root) {
_SkeletonJson_setError(self, 0, "Invalid animation JSON: ", Json_getError());
return 0;
}
Json* bones = Json_getItem(root, "bones");
int boneCount = Json_getSize(bones);
Json* slots = Json_getItem(root, "slots");
int slotCount = slots ? Json_getSize(slots) : 0;
int timelineCount = 0;
int i, ii, iii;
for (i = 0; i < boneCount; ++i)
timelineCount += Json_getSize(Json_getItemAt(bones, i));
for (i = 0; i < slotCount; ++i)
timelineCount += Json_getSize(Json_getItemAt(slots, i));
Animation* animation = Animation_create(timelineCount);
animation->timelineCount = 0;
for (i = 0; i < boneCount; ++i) {
Json* boneMap = Json_getItemAt(bones, i);
const char* boneName = boneMap->name;
int boneIndex = SkeletonData_findBoneIndex(skeletonData, boneName);
if (boneIndex == -1) {
Animation_dispose(animation);
_SkeletonJson_setError(self, root, "Bone not found: ", boneName);
return 0;
}
int timelineCount = Json_getSize(boneMap);
for (ii = 0; ii < timelineCount; ++ii) {
Json* timelineArray = Json_getItemAt(boneMap, ii);
int frameCount = Json_getSize(timelineArray);
const char* timelineType = timelineArray->name;
if (strcmp(timelineType, "rotate") == 0) {
RotateTimeline *timeline = RotateTimeline_create(frameCount);
timeline->boneIndex = boneIndex;
for (iii = 0; iii < frameCount; ++iii) {
Json* frame = Json_getItemAt(timelineArray, iii);
RotateTimeline_setFrame(timeline, iii, Json_getFloat(frame, "time", 0), Json_getFloat(frame, "angle", 0));
readCurve(&timeline->super, iii, frame);
}
animation->timelines[animation->timelineCount++] = (Timeline*)timeline;
animation->duration = fmaxf(animation->duration, timeline->frames[frameCount * 2 - 2]);
} else {
int isScale = strcmp(timelineType, "scale") == 0;
if (isScale || strcmp(timelineType, "translate") == 0) {
TranslateTimeline *timeline = isScale ? ScaleTimeline_create(frameCount) : TranslateTimeline_create(frameCount);
float scale = isScale ? 1 : self->scale;
timeline->boneIndex = boneIndex;
for (iii = 0; iii < frameCount; ++iii) {
Json* frame = Json_getItemAt(timelineArray, iii);
TranslateTimeline_setFrame(timeline, iii, Json_getFloat(frame, "time", 0), Json_getFloat(frame, "x", 0) * scale,
Json_getFloat(frame, "y", 0) * scale);
readCurve(&timeline->super, iii, frame);
}
animation->timelines[animation->timelineCount++] = (Timeline*)timeline;
animation->duration = fmaxf(animation->duration, timeline->frames[frameCount * 3 - 3]);
} else {
Animation_dispose(animation);
_SkeletonJson_setError(self, 0, "Invalid timeline type for a bone: ", timelineType);
return 0;
}
}
}
}
if (!slots) {
for (i = 0; i < slotCount; ++i) {
Json* slotMap = Json_getItemAt(slots, i);
const char* slotName = slotMap->name;
int slotIndex = SkeletonData_findSlotIndex(skeletonData, slotName);
if (slotIndex == -1) {
Animation_dispose(animation);
_SkeletonJson_setError(self, root, "Slot not found: ", slotName);
return 0;
}
int timelineCount = Json_getSize(slotMap);
for (ii = 0; ii < timelineCount; ++ii) {
Json* timelineArray = Json_getItemAt(slotMap, ii);
int frameCount = Json_getSize(timelineArray);
const char* timelineType = timelineArray->name;
if (strcmp(timelineType, "color") == 0) {
ColorTimeline *timeline = ColorTimeline_create(frameCount);
timeline->slotIndex = slotIndex;
for (iii = 0; iii < frameCount; ++iii) {
Json* frame = Json_getItemAt(timelineArray, iii);
const char* s = Json_getString(frame, "color", 0);
ColorTimeline_setFrame(timeline, iii, Json_getFloat(frame, "time", 0), toColor(s, 0), toColor(s, 1),
toColor(s, 2), toColor(s, 3));
readCurve(&timeline->super, iii, frame);
}
animation->timelines[animation->timelineCount++] = (Timeline*)timeline;
animation->duration = fmaxf(animation->duration, timeline->frames[frameCount * 5 - 5]);
} else if (strcmp(timelineType, "attachment") == 0) {
AttachmentTimeline *timeline = AttachmentTimeline_create(frameCount);
timeline->slotIndex = slotIndex;
for (iii = 0; iii < frameCount; ++iii) {
Json* frame = Json_getItemAt(timelineArray, iii);
Json* name = Json_getItem(frame, "name");
AttachmentTimeline_setFrame(timeline, iii, Json_getFloat(frame, "time", 0),
name->type == Json_NULL ? 0 : name->valuestring);
}
animation->timelines[animation->timelineCount++] = (Timeline*)timeline;
animation->duration = fmaxf(animation->duration, timeline->frames[frameCount - 1]);
} else {
Animation_dispose(animation);
_SkeletonJson_setError(self, 0, "Invalid timeline type for a slot: ", timelineType);
return 0;
}
}
}
}
return animation;
}

View File

@ -2,39 +2,39 @@
#include <spine/util.h> #include <spine/util.h>
SkinEntry* _SkinEntry_create (int slotIndex, const char* name, Attachment* attachment) { SkinEntry* _SkinEntry_create (int slotIndex, const char* name, Attachment* attachment) {
SkinEntry* this = calloc(1, sizeof(SkinEntry)); SkinEntry* self = CALLOC(SkinEntry, 1)
this->slotIndex = slotIndex; self->slotIndex = slotIndex;
MALLOC_STR(this->name, name) MALLOC_STR(self->name, name)
this->attachment = attachment; self->attachment = attachment;
return this; return self;
} }
void _SkinEntry_dispose (SkinEntry* this) { void _SkinEntry_dispose (SkinEntry* self) {
if (this->next) _SkinEntry_dispose((SkinEntry*)this->next); if (self->next) _SkinEntry_dispose((SkinEntry*)self->next);
Attachment_dispose(this->attachment); Attachment_dispose(self->attachment);
FREE(this->name) FREE(self->name)
FREE(this) FREE(self)
} }
/**/ /**/
Skin* Skin_create (const char* name) { Skin* Skin_create (const char* name) {
Skin* this = calloc(1, sizeof(Skin)); Skin* self = CALLOC(Skin, 1)
MALLOC_STR(this->name, name) MALLOC_STR(self->name, name)
return this; return self;
} }
void Skin_dispose (Skin* this) { void Skin_dispose (Skin* self) {
_SkinEntry_dispose((SkinEntry*)this->entries); _SkinEntry_dispose((SkinEntry*)self->entries);
FREE(this->name) FREE(self->name)
FREE(this) FREE(self)
} }
void Skin_addAttachment (Skin* this, int slotIndex, const char* name, Attachment* attachment) { void Skin_addAttachment (Skin* self, int slotIndex, const char* name, Attachment* attachment) {
SkinEntry* newEntry = _SkinEntry_create(slotIndex, name, attachment); SkinEntry* newEntry = _SkinEntry_create(slotIndex, name, attachment);
SkinEntry* entry = (SkinEntry*)this->entries; SkinEntry* entry = (SkinEntry*)self->entries;
if (!entry) if (!entry)
CAST(SkinEntry*, this->entries) = newEntry; CAST(SkinEntry*, self->entries) = newEntry;
else { else {
while (entry->next) while (entry->next)
entry = (SkinEntry*)entry->next; entry = (SkinEntry*)entry->next;
@ -42,8 +42,8 @@ void Skin_addAttachment (Skin* this, int slotIndex, const char* name, Attachment
} }
} }
Attachment* Skin_getAttachment (const Skin* this, int slotIndex, const char* name) { Attachment* Skin_getAttachment (const Skin* self, int slotIndex, const char* name) {
const SkinEntry* entry = this->entries; const SkinEntry* entry = self->entries;
while (entry) { while (entry) {
if (entry->slotIndex == slotIndex && strcmp(entry->name, name) == 0) return entry->attachment; if (entry->slotIndex == slotIndex && strcmp(entry->name, name) == 0) return entry->attachment;
entry = entry->next; entry = entry->next;

View File

@ -5,54 +5,54 @@
typedef struct { typedef struct {
Slot slot; Slot slot;
float attachmentTime; float attachmentTime;
} Private; } Internal;
Slot* Slot_create (SlotData* data, Skeleton* skeleton, Bone* bone) { Slot* Slot_create (SlotData* data, Skeleton* skeleton, Bone* bone) {
Private* private = calloc(1, sizeof(Private)); Internal* internal = CALLOC(Internal, 1)
Slot* this = &private->slot; Slot* self = &internal->slot;
CAST(SlotData*, this->data) = data; CAST(SlotData*, self->data) = data;
CAST(Skeleton*, this->skeleton) = skeleton; CAST(Skeleton*, self->skeleton) = skeleton;
CAST(Bone*, this->bone) = bone; CAST(Bone*, self->bone) = bone;
this->r = 1; self->r = 1;
this->g = 1; self->g = 1;
this->b = 1; self->b = 1;
this->a = 1; self->a = 1;
return this; return self;
} }
void Slot_dispose (Slot* this) { void Slot_dispose (Slot* self) {
FREE(this); FREE(self);
} }
/* @param attachment May be null. */ /* @param attachment May be null. */
void Slot_setAttachment (Slot* this, Attachment* attachment) { void Slot_setAttachment (Slot* self, Attachment* attachment) {
CAST(Attachment*, this->attachment) = attachment; CAST(Attachment*, self->attachment) = attachment;
((Private*)this)->attachmentTime = this->skeleton->time; ((Internal*)self)->attachmentTime = self->skeleton->time;
} }
void Slot_setAttachmentTime (Slot* this, float time) { void Slot_setAttachmentTime (Slot* self, float time) {
((Private*)this)->attachmentTime = this->skeleton->time - time; ((Internal*)self)->attachmentTime = self->skeleton->time - time;
} }
float Slot_getAttachmentTime (const Slot* this) { float Slot_getAttachmentTime (const Slot* self) {
return this->skeleton->time - ((Private*)this)->attachmentTime; return self->skeleton->time - ((Internal*)self)->attachmentTime;
} }
void Slot_setToBindPose (Slot* this) { void Slot_setToBindPose (Slot* self) {
this->r = this->data->r; self->r = self->data->r;
this->g = this->data->g; self->g = self->data->g;
this->b = this->data->b; self->b = self->data->b;
this->a = this->data->a; self->a = self->data->a;
Attachment* attachment = 0; Attachment* attachment = 0;
if (this->data->attachmentName) { if (self->data->attachmentName) {
int i; int i;
for (i = 0; i < this->skeleton->data->slotCount; ++i) { for (i = 0; i < self->skeleton->data->slotCount; ++i) {
if (this->data == this->skeleton->data->slots[i]) { if (self->data == self->skeleton->data->slots[i]) {
attachment = Skeleton_getAttachmentForSlotIndex(this->skeleton, i, this->data->attachmentName); attachment = Skeleton_getAttachmentForSlotIndex(self->skeleton, i, self->data->attachmentName);
break; break;
} }
} }
} }
Slot_setAttachment(this, attachment); Slot_setAttachment(self, attachment);
} }

View File

@ -2,26 +2,26 @@
#include <spine/util.h> #include <spine/util.h>
SlotData* SlotData_create (const char* name, BoneData* boneData) { SlotData* SlotData_create (const char* name, BoneData* boneData) {
SlotData* this = calloc(1, sizeof(SlotData)); SlotData* self = CALLOC(SlotData, 1)
MALLOC_STR(this->name, name) MALLOC_STR(self->name, name)
CAST(BoneData*, this->boneData) = boneData; CAST(BoneData*, self->boneData) = boneData;
this->r = 1; self->r = 1;
this->g = 1; self->g = 1;
this->b = 1; self->b = 1;
this->a = 1; self->a = 1;
return this; return self;
} }
void SlotData_dispose (SlotData* this) { void SlotData_dispose (SlotData* self) {
FREE(this->name); FREE(self->name);
FREE(this->attachmentName); FREE(self->attachmentName);
FREE(this); FREE(self);
} }
void SlotData_setAttachmentName (SlotData* this, const char* attachmentName) { void SlotData_setAttachmentName (SlotData* self, const char* attachmentName) {
FREE(this->attachmentName); FREE(self->attachmentName);
if (attachmentName) if (attachmentName)
MALLOC_STR(this->attachmentName, attachmentName) MALLOC_STR(self->attachmentName, attachmentName)
else else
CAST(char*, this->attachmentName) = 0; CAST(char*, self->attachmentName) = 0;
} }

View File

@ -1,84 +0,0 @@
/*
Copyright (c) 2009 Dave Gamble
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/* Esoteric Software: Removed everything except parsing, added cJSON_GetObject*, formatted, double to float. */
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6
#define cJSON_IsReference 256
/* The cJSON structure: */
typedef struct cJSON {
struct cJSON *next, *prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
int type; /* The type of the item, as above. */
const char* valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
float valuefloat; /* The item's number, if type==cJSON_Number */
const char* name; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_dispose when finished. */
extern cJSON *cJSON_Parse (const char* value);
/* Delete a cJSON entity and all subentities. */
extern void cJSON_dispose (cJSON *c);
/* Returns the number of items in an array (or object). */
extern int cJSON_GetArraySize (cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
extern cJSON *cJSON_GetArrayItem (cJSON *array, int item);
/* Get item "string" from object. Case insensitive. */
extern cJSON *cJSON_GetObjectItem (cJSON *object, const char* string);
extern const char* cJSON_GetObjectString (cJSON* object, const char* name, const char* defaultValue);
extern float cJSON_GetObjectFloat (cJSON* value, const char* name, float defaultValue);
extern int cJSON_GetObjectInt (cJSON* value, const char* name, int defaultValue);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
extern const char* cJSON_GetErrorPtr (void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,17 +1,17 @@
#ifndef SPINE_EXTENSION_H_ #ifndef SPINE_EXTENSION_H_
#define SPINE_EXTENSION_H_ #define SPINE_EXTENSION_H_
#ifdef __cplusplus
namespace spine {
extern "C" {
#endif
#include <spine/Skeleton.h> #include <spine/Skeleton.h>
#include <spine/RegionAttachment.h> #include <spine/RegionAttachment.h>
#include <spine/Animation.h> #include <spine/Animation.h>
#include <spine/Atlas.h> #include <spine/Atlas.h>
#include <spine/AttachmentLoader.h> #include <spine/AttachmentLoader.h>
#ifdef __cplusplus
namespace spine {
extern "C" {
#endif
/* Methods that must be implemented: **/ /* Methods that must be implemented: **/
Skeleton* Skeleton_create (SkeletonData* data); Skeleton* Skeleton_create (SkeletonData* data);
@ -42,7 +42,7 @@ void _AtlasPage_deinit (AtlasPage* page);
void _AttachmentLoader_init (AttachmentLoader* loader); void _AttachmentLoader_init (AttachmentLoader* loader);
void _AttachmentLoader_deinit (AttachmentLoader* loader); void _AttachmentLoader_deinit (AttachmentLoader* loader);
void* _AttachmentLoader_setError (AttachmentLoader* loader, const char* error1, const char* error2); void _AttachmentLoader_setError (AttachmentLoader* loader, const char* error1, const char* error2);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -4,13 +4,26 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifdef __cplusplus
namespace spine {
extern "C" {
#endif
/* Used to cast away const on an lvalue. */ /* Used to cast away const on an lvalue. */
#define CAST(TYPE,VALUE) *(TYPE*)&VALUE #define CAST(TYPE,VALUE) *(TYPE*)&VALUE
#define MALLOC_STR(TO,FROM) strcpy(CAST(char*, TO) = malloc(strlen(FROM)), FROM); #define CALLOC(TYPE,COUNT) (TYPE*)calloc(1, sizeof(TYPE) * COUNT);
#define MALLOC(TYPE,COUNT) (TYPE*)malloc(sizeof(TYPE) * COUNT);
#define MALLOC_STR(TO,FROM) strcpy(CAST(char*, TO) = (char*)malloc(strlen(FROM)), FROM);
#define FREE(E) free((void*)E); #define FREE(E) free((void*)E);
const char* readFile (const char* path); const char* readFile (const char* path);
#ifdef __cplusplus
}
}
#endif
#endif /* SPINE_UTIL_H_ */ #endif /* SPINE_UTIL_H_ */

View File

@ -22,7 +22,7 @@
<targetPlatform id="cdt.managedbuild.target.gnu.platform.mingw.exe.debug.797088945" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.mingw.exe.debug"/> <targetPlatform id="cdt.managedbuild.target.gnu.platform.mingw.exe.debug.797088945" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.mingw.exe.debug"/>
<builder buildPath="${workspace_loc:/cpp-generic/Debug}" id="cdt.managedbuild.tool.gnu.builder.mingw.base.1296203303" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CDT Internal Builder" superClass="cdt.managedbuild.tool.gnu.builder.mingw.base"/> <builder buildPath="${workspace_loc:/cpp-generic/Debug}" id="cdt.managedbuild.tool.gnu.builder.mingw.base.1296203303" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CDT Internal Builder" superClass="cdt.managedbuild.tool.gnu.builder.mingw.base"/>
<tool id="cdt.managedbuild.tool.gnu.assembler.mingw.exe.debug.1487845826" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.mingw.exe.debug"> <tool id="cdt.managedbuild.tool.gnu.assembler.mingw.exe.debug.1487845826" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.mingw.exe.debug">
<option id="gnu.both.asm.option.include.paths.1112183959" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath"/> <option id="gnu.both.asm.option.include.paths.1112183959" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths"/>
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.339251819" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> <inputType id="cdt.managedbuild.tool.gnu.assembler.input.339251819" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool> </tool>
<tool id="cdt.managedbuild.tool.gnu.archiver.mingw.base.1265146112" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.mingw.base"/> <tool id="cdt.managedbuild.tool.gnu.archiver.mingw.base.1265146112" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.mingw.base"/>
@ -30,28 +30,29 @@
<option id="gnu.cpp.compiler.mingw.exe.debug.option.optimization.level.1284147695" name="Optimization Level" superClass="gnu.cpp.compiler.mingw.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/> <option id="gnu.cpp.compiler.mingw.exe.debug.option.optimization.level.1284147695" name="Optimization Level" superClass="gnu.cpp.compiler.mingw.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
<option id="gnu.cpp.compiler.mingw.exe.debug.option.debugging.level.1570084302" name="Debug Level" superClass="gnu.cpp.compiler.mingw.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/> <option id="gnu.cpp.compiler.mingw.exe.debug.option.debugging.level.1570084302" name="Debug Level" superClass="gnu.cpp.compiler.mingw.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
<option id="gnu.cpp.compiler.option.include.paths.934414518" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath"> <option id="gnu.cpp.compiler.option.include.paths.934414518" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/spine-cpp/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;C:\Users\Nate\Desktop\SFML-2.0-rc\include&quot;"/> <listOptionValue builtIn="false" value="&quot;C:\Users\Nate\Desktop\SFML-2.0-rc\include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/include}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/spine-c/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/spine-c/src}&quot;"/>
</option> </option>
<option id="gnu.cpp.compiler.option.warnings.allwarn.2053349441" name="All warnings (-Wall)" superClass="gnu.cpp.compiler.option.warnings.allwarn" value="true" valueType="boolean"/> <option id="gnu.cpp.compiler.option.warnings.allwarn.2053349441" name="All warnings (-Wall)" superClass="gnu.cpp.compiler.option.warnings.allwarn" value="true" valueType="boolean"/>
<option id="gnu.cpp.compiler.option.preprocessor.def.1463772359" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def"/> <option id="gnu.cpp.compiler.option.preprocessor.def.1463772359" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1445618618" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1445618618" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool> </tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.debug.344670633" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.debug"> <tool command="gcc" id="cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.debug.344670633" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.debug">
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.mingw.exe.debug.option.optimization.level.1455011160" name="Optimization Level" superClass="gnu.c.compiler.mingw.exe.debug.option.optimization.level" valueType="enumerated"/> <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.mingw.exe.debug.option.optimization.level.1455011160" name="Optimization Level" superClass="gnu.c.compiler.mingw.exe.debug.option.optimization.level" valueType="enumerated"/>
<option id="gnu.c.compiler.mingw.exe.debug.option.debugging.level.242859432" name="Debug Level" superClass="gnu.c.compiler.mingw.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/> <option id="gnu.c.compiler.mingw.exe.debug.option.debugging.level.242859432" name="Debug Level" superClass="gnu.c.compiler.mingw.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="gnu.c.compiler.option.include.paths.991681732" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath"/> <option id="gnu.c.compiler.option.include.paths.991681732" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/spine-c/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/spine-c/src}&quot;"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.753970334" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.753970334" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool> </tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.mingw.exe.debug.913061526" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.exe.debug"/> <tool id="cdt.managedbuild.tool.gnu.c.linker.mingw.exe.debug.913061526" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.exe.debug"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.exe.debug.1697744244" name="MinGW C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.exe.debug"> <tool id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.exe.debug.1697744244" name="MinGW C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.exe.debug">
<option id="gnu.cpp.link.option.paths.1569606245" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths"> <option id="gnu.cpp.link.option.paths.1569606245" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/spine-cpp/Debug}&quot;"/>
<listOptionValue builtIn="false" value="&quot;C:\Users\Nate\Desktop\SFML-2.0-rc\lib&quot;"/> <listOptionValue builtIn="false" value="&quot;C:\Users\Nate\Desktop\SFML-2.0-rc\lib&quot;"/>
</option> </option>
<option id="gnu.cpp.link.option.libs.43946887" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs"> <option id="gnu.cpp.link.option.libs.43946887" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="spine-cpp"/>
<listOptionValue builtIn="false" value="sfml-system-d"/> <listOptionValue builtIn="false" value="sfml-system-d"/>
<listOptionValue builtIn="false" value="sfml-window-d"/> <listOptionValue builtIn="false" value="sfml-window-d"/>
<listOptionValue builtIn="false" value="sfml-graphics-d"/> <listOptionValue builtIn="false" value="sfml-graphics-d"/>
@ -64,19 +65,12 @@
</toolChain> </toolChain>
</folderInfo> </folderInfo>
<sourceEntries> <sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/> <entry excluding="main.c" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="spine-c src"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="src"/>
</sourceEntries> </sourceEntries>
</configuration> </configuration>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"> <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<externalSettings containerId="spine-cpp;" factoryId="org.eclipse.cdt.core.cfg.export.settings.sipplier">
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/spine-cpp/include"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/spine-cpp/Debug"/>
<entry flags="" kind="libraryFile" name="spine-cpp" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
</storageModule>
</cconfiguration> </cconfiguration>
<cconfiguration id="cdt.managedbuild.config.gnu.mingw.exe.release.165980790"> <cconfiguration id="cdt.managedbuild.config.gnu.mingw.exe.release.165980790">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.mingw.exe.release.165980790" moduleId="org.eclipse.cdt.core.settings" name="Release"> <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.mingw.exe.release.165980790" moduleId="org.eclipse.cdt.core.settings" name="Release">

View File

@ -3,7 +3,6 @@
<name>spine-sfml</name> <name>spine-sfml</name>
<comment></comment> <comment></comment>
<projects> <projects>
<project>spine-cpp</project>
</projects> </projects>
<buildSpec> <buildSpec>
<buildCommand> <buildCommand>
@ -25,4 +24,11 @@
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures> </natures>
<linkedResources>
<link>
<name>spine-c src</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/spine-c/src</locationURI>
</link>
</linkedResources>
</projectDescription> </projectDescription>

View File

@ -1,64 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#ifndef SPINE_ATLAS_H_
#define SPINE_ATLAS_H_
#include <spine/BaseAtlas.h>
#include <SFML/Graphics/Texture.hpp>
namespace spine {
class AtlasPage: public BaseAtlasPage {
public:
~AtlasPage ();
sf::Texture *texture;
};
//
class AtlasRegion: public BaseAtlasRegion {
public:
AtlasPage *page;
};
//
class Atlas: public BaseAtlas {
public:
Atlas (const std::string &path);
Atlas (std::istream &input);
Atlas (const char *begin, const char *end);
AtlasRegion* findRegion (const std::string &name);
private:
virtual BaseAtlasPage* newAtlasPage (const std::string &name);
virtual BaseAtlasRegion* newAtlasRegion (BaseAtlasPage* page);
};
} /* namespace spine */
#endif /* SPINE_ATLAS_H_ */

View File

@ -1,45 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#ifndef SPINE_ATLASATTACHMENTLOADER_H_
#define SPINE_ATLASATTACHMENTLOADER_H_
#include <spine/BaseAttachmentLoader.h>
namespace spine {
class Atlas;
class AtlasAttachmentLoader: public BaseAttachmentLoader {
public:
Atlas *atlas;
AtlasAttachmentLoader (Atlas *atlas);
virtual Attachment* newAttachment (AttachmentType type, const std::string &name);
};
} /* namespace spine */
#endif /* SPINE_ATLASATTACHMENTLOADER_H_ */

View File

@ -1,50 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#ifndef SPINE_REGIONATTACHMENT_H_
#define SPINE_REGIONATTACHMENT_H_
#include <spine/BaseRegionAttachment.h>
#include <SFML/Graphics/Vertex.hpp>
#include <SFML/Graphics/Texture.hpp>
namespace spine {
class Bone;
class AtlasRegion;
class RegionAttachment: public BaseRegionAttachment {
public:
sf::Vertex vertices[4];
sf::Texture *texture;
RegionAttachment (AtlasRegion *region);
virtual void updateWorldVertices (Bone *bone);
virtual void draw (Slot *slot);
};
} /* namespace spine */
#endif /* SPINE_REGIONATTACHMENT_H_ */

View File

@ -1,45 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#ifndef SPINE_SKELETON_H_
#define SPINE_SKELETON_H_
#include <spine/BaseSkeleton.h>
#include <SFML/Graphics/VertexArray.hpp>
namespace spine {
class Skeleton: public BaseSkeleton, public sf::Drawable {
public:
sf::VertexArray vertexArray;
sf::Texture *texture; // All region attachments must use the same texture.
Skeleton (SkeletonData *skeletonData);
virtual void draw (sf::RenderTarget& target, sf::RenderStates states) const;
};
} /* namespace spine */
#endif /* SPINE_SKELETON_H_ */

View File

@ -1,43 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#ifndef SPINE_SKELETONJSON_H_
#define SPINE_SKELETONJSON_H_
#include <spine/BaseSkeletonJson.h>
namespace spine {
class Atlas;
class SkeletonJson: public BaseSkeletonJson {
public:
SkeletonJson (Atlas *atlas);
/** The SkeletonJson owns the attachmentLoader */
SkeletonJson (BaseAttachmentLoader *attachmentLoader);
};
} /* namespace spine */
#endif /* SPINE_SKELETONJSON_H_ */

View File

@ -1,46 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#ifndef SPINE_SPINE_H_
#define SPINE_SPINE_H_
#include <spine/SkeletonData.h>
#include <spine/BoneData.h>
#include <spine/SlotData.h>
#include <spine/Skin.h>
#include <spine/Attachment.h>
#include <spine/Animation.h>
#include <spine/AnimationStateData.h>
#include <spine/AnimationState.h>
#include <spine/Slot.h>
#include <spine/Bone.h>
#include <spine-sfml/RegionAttachment.h>
#include <spine-sfml/Atlas.h>
#include <spine-sfml/AtlasAttachmentLoader.h>
#include <spine-sfml/SkeletonJson.h>
#include <spine-sfml/Skeleton.h>
#endif /* SF_SPINE_H_ */

View File

@ -24,7 +24,7 @@
******************************************************************************/ ******************************************************************************/
#include <iostream> #include <iostream>
#include <spine-sfml/spine.h> #include <spine/spine.h>
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
using namespace std; using namespace std;
@ -33,18 +33,19 @@ using namespace spine;
int main () { int main () {
try { try {
Atlas *atlas = new Atlas("../data/spineboy.atlas"); Atlas* atlas = Atlas_readAtlasFile("../data/spineboy.atlas");
SkeletonJson json(atlas); SkeletonJson* json = SkeletonJson_create(atlas);
SkeletonData *skeletonData = json.readSkeletonData("../data/spineboy-skeleton.json"); SkeletonData *skeletonData = SkeletonJson_readSkeletonDataFile(json, "../data/spineboy-skeleton.json");
Animation *animation = json.readAnimation("../data/spineboy-walk.json", skeletonData); Animation* animation = SkeletonJson_readAnimationFile(json, "../data/spineboy-walk.json", skeletonData);
SkeletonJson_dispose(json);
Skeleton *skeleton = new Skeleton(skeletonData); Skeleton* skeleton = Skeleton_create(skeletonData);
skeleton->flipX = false; skeleton->flipX = false;
skeleton->flipY = false; skeleton->flipY = false;
skeleton->setToBindPose(); Skeleton_setToBindPose(skeleton);
skeleton->getRootBone()->x = 320; Skeleton_getRootBone(skeleton)->x = 320;
skeleton->getRootBone()->y = 420; Skeleton_getRootBone(skeleton)->y = 420;
skeleton->updateWorldTransform(); Skeleton_updateWorldTransform(skeleton);
sf::RenderWindow window(sf::VideoMode(640, 480), "Spine SFML"); sf::RenderWindow window(sf::VideoMode(640, 480), "Spine SFML");
window.setFramerateLimit(60); window.setFramerateLimit(60);
@ -55,16 +56,20 @@ int main () {
while (window.pollEvent(event)) while (window.pollEvent(event))
if (event.type == sf::Event::Closed) window.close(); if (event.type == sf::Event::Closed) window.close();
window.clear(); window.clear();
window.draw(*skeleton); //window.draw(*skeleton);
window.display(); window.display();
float delta = deltaClock.getElapsedTime().asSeconds(); float delta = deltaClock.getElapsedTime().asSeconds();
deltaClock.restart(); deltaClock.restart();
animationTime += delta; animationTime += delta;
animation->apply(skeleton, animationTime, true); Animation_apply(animation, skeleton, animationTime, true);
skeleton->updateWorldTransform(); Skeleton_updateWorldTransform(skeleton);
} }
Skeleton_dispose(skeleton);
SkeletonData_dispose(skeletonData);
Atlas_dispose(atlas);
} catch (exception &ex) { } catch (exception &ex) {
cout << ex.what() << endl << flush; cout << ex.what() << endl << flush;
} }

View File

@ -1,66 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#include <SFML/Graphics/Texture.hpp>
#include <spine-sfml/Atlas.h>
namespace spine {
AtlasPage::~AtlasPage () {
delete texture;
}
//
Atlas::Atlas (const std::string &path) {
load(path);
}
Atlas::Atlas (std::istream &input) {
load(input);
}
Atlas::Atlas (const char *begin, const char *end) {
load(begin, end);
}
BaseAtlasPage* Atlas::newAtlasPage (const std::string &name) {
AtlasPage *page = new AtlasPage();
page->texture = new sf::Texture();
page->texture->loadFromFile(name);
return page;
}
BaseAtlasRegion* Atlas::newAtlasRegion (BaseAtlasPage* page) {
AtlasRegion *region = new AtlasRegion();
region->page = reinterpret_cast<AtlasPage*>(page);
return region;
}
AtlasRegion* Atlas::findRegion (const std::string &name) {
return reinterpret_cast<AtlasRegion*>(BaseAtlas::findRegion(name));
}
} /* namespace spine */

View File

@ -1,49 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#include <stdexcept>
#include <spine-sfml/AtlasAttachmentLoader.h>
#include <spine-sfml/Atlas.h>
#include <spine-sfml/RegionAttachment.h>
namespace spine {
AtlasAttachmentLoader::AtlasAttachmentLoader (Atlas *atlas) :
atlas(atlas) {
}
Attachment* AtlasAttachmentLoader::newAttachment (AttachmentType type, const std::string &name) {
switch (type) {
case region: {
AtlasRegion *region = atlas->findRegion(name);
if (!region) throw std::runtime_error("Atlas region not found: " + name);
return new RegionAttachment(region);
}
default:
throw std::runtime_error("Unknown attachment type: " + type);
}
}
} /* namespace spine */

View File

@ -1,108 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#include <iostream>
#include <SFML/System/Vector2.hpp>
#include <spine-sfml/RegionAttachment.h>
#include <spine-sfml/Atlas.h>
#include <spine-sfml/Skeleton.h>
#include <spine/Bone.h>
#include <spine/Slot.h>
namespace spine {
RegionAttachment::RegionAttachment (AtlasRegion *region) {
texture = region->page->texture;
int u = region->x;
int u2 = u + region->width;
int v = region->y;
int v2 = v + region->height;
if (region->rotate) {
vertices[1].texCoords.x = u;
vertices[1].texCoords.y = v2;
vertices[2].texCoords.x = u;
vertices[2].texCoords.y = v;
vertices[3].texCoords.x = u2;
vertices[3].texCoords.y = v;
vertices[0].texCoords.x = u2;
vertices[0].texCoords.y = v2;
} else {
vertices[0].texCoords.x = u;
vertices[0].texCoords.y = v2;
vertices[1].texCoords.x = u;
vertices[1].texCoords.y = v;
vertices[2].texCoords.x = u2;
vertices[2].texCoords.y = v;
vertices[3].texCoords.x = u2;
vertices[3].texCoords.y = v2;
}
}
void RegionAttachment::draw (Slot *slot) {
Skeleton* skeleton = (Skeleton*)slot->skeleton;
sf::Uint8 r = skeleton->r * slot->r * 255;
sf::Uint8 g = skeleton->g * slot->g * 255;
sf::Uint8 b = skeleton->b * slot->b * 255;
sf::Uint8 a = skeleton->a * slot->a * 255;
vertices[0].color.r = r;
vertices[0].color.g = g;
vertices[0].color.b = b;
vertices[0].color.a = a;
vertices[1].color.r = r;
vertices[1].color.g = g;
vertices[1].color.b = b;
vertices[1].color.a = a;
vertices[2].color.r = r;
vertices[2].color.g = g;
vertices[2].color.b = b;
vertices[2].color.a = a;
vertices[3].color.r = r;
vertices[3].color.g = g;
vertices[3].color.b = b;
vertices[3].color.a = a;
updateWorldVertices(slot->bone);
// SMFL doesn't handle batching for us, so we'll just force a single texture per skeleton.
skeleton->texture = texture;
skeleton->vertexArray.append(vertices[0]);
skeleton->vertexArray.append(vertices[1]);
skeleton->vertexArray.append(vertices[2]);
skeleton->vertexArray.append(vertices[3]);
}
void RegionAttachment::updateWorldVertices (spine::Bone *bone) {
vertices[0].position.x = offset[0] * bone->m00 + offset[1] * bone->m01 + bone->worldX;
vertices[0].position.y = offset[0] * bone->m10 + offset[1] * bone->m11 + bone->worldY;
vertices[1].position.x = offset[2] * bone->m00 + offset[3] * bone->m01 + bone->worldX;
vertices[1].position.y = offset[2] * bone->m10 + offset[3] * bone->m11 + bone->worldY;
vertices[2].position.x = offset[4] * bone->m00 + offset[5] * bone->m01 + bone->worldX;
vertices[2].position.y = offset[4] * bone->m10 + offset[5] * bone->m11 + bone->worldY;
vertices[3].position.x = offset[6] * bone->m00 + offset[7] * bone->m01 + bone->worldX;
vertices[3].position.y = offset[6] * bone->m10 + offset[7] * bone->m11 + bone->worldY;
}
} /* namespace spine */

View File

@ -1,55 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#include <iostream>
#include <spine-sfml/Skeleton.h>
#include <spine/SkeletonData.h>
#include <spine/Slot.h>
#include <spine/Attachment.h>
#include <SFML/Graphics/RenderTarget.hpp>
#include <SFML/Graphics/RenderStates.hpp>
#include <SFML/Graphics/Texture.hpp>
using sf::Quads;
using sf::RenderTarget;
using sf::RenderStates;
namespace spine {
Skeleton::Skeleton (SkeletonData *skeletonData) :
BaseSkeleton(skeletonData),
vertexArray(Quads, skeletonData->bones.size() * 4),
texture(0) {
}
void Skeleton::draw (RenderTarget& target, RenderStates states) const {
const_cast<Skeleton*>(this)->vertexArray.clear();
for (int i = 0, n = slots.size(); i < n; i++)
if (slots[i]->attachment) slots[i]->attachment->draw(slots[i]);
states.texture = texture;
target.draw(vertexArray, states);
}
} /* namespace spine */

View File

@ -1,41 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#include <spine-sfml/SkeletonJson.h>
#include <spine-sfml/AtlasAttachmentLoader.h>
namespace spine {
SkeletonJson::SkeletonJson (BaseAttachmentLoader *attachmentLoader) :
BaseSkeletonJson(attachmentLoader) {
yDown = true;
}
SkeletonJson::SkeletonJson (Atlas *atlas) :
BaseSkeletonJson(new AtlasAttachmentLoader(atlas)) {
yDown = true;
}
} /* namespace spine */

View File

@ -0,0 +1,155 @@
#include <spine/spine.h>
#include <spine/extension.h>
#include <spine/util.h>
#include <SFML/Graphics/Vertex.hpp>
#include <SFML/Graphics/VertexArray.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/RenderTarget.hpp>
#include <SFML/Graphics/RenderStates.hpp>
using sf::Quads;
using sf::RenderTarget;
using sf::RenderStates;
using sf::Texture;
using sf::Uint8;
using sf::Vertex;
using sf::VertexArray;
namespace spine {
typedef struct {
AtlasPage super;
Texture *texture;
} SfmlAtlasPage;
void _SfmlAtlasPage_dispose (AtlasPage* page) {
SfmlAtlasPage* self = (SfmlAtlasPage*)page;
_AtlasPage_deinit(&self->super);
delete self->texture;
FREE(page)
}
AtlasPage* AtlasPage_create (const char* name) {
SfmlAtlasPage* self = CALLOC(SfmlAtlasPage, 1)
_AtlasPage_init(&self->super, name);
self->super._dispose = _SfmlAtlasPage_dispose;
self->texture = new Texture();
self->texture->loadFromFile(name);
return &self->super;
}
/**/
typedef struct {
Skeleton super;
VertexArray* vertexArray;
Texture* texture; // All region attachments must use the same texture.
} SfmlSkeleton;
void _SfmlSkeleton_dispose (Skeleton* self) {
_Skeleton_deinit(self);
FREE(self)
}
Skeleton* Skeleton_create (SkeletonData* data) {
SfmlSkeleton* self = CALLOC(SfmlSkeleton, 1)
_Skeleton_init(&self->super, data);
self->super._dispose = _SfmlSkeleton_dispose;
self->vertexArray = new VertexArray(Quads, data->boneCount * 4);
return &self->super;
}
/**/
typedef struct {
RegionAttachment super;
Vertex vertices[4];
Texture *texture;
} SfmlRegionAttachment;
void _SfmlRegionAttachment_dispose (Attachment* self) {
_RegionAttachment_deinit((RegionAttachment*)self);
FREE(self)
}
RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) {
SfmlRegionAttachment* self = CALLOC(SfmlRegionAttachment, 1)
_RegionAttachment_init(&self->super, name);
self->super.super._dispose = _SfmlRegionAttachment_dispose;
self->texture = ((SfmlAtlasPage*)region->page)->texture;
int u = region->x;
int u2 = u + region->width;
int v = region->y;
int v2 = v + region->height;
if (region->rotate) {
self->vertices[1].texCoords.x = u;
self->vertices[1].texCoords.y = v2;
self->vertices[2].texCoords.x = u;
self->vertices[2].texCoords.y = v;
self->vertices[3].texCoords.x = u2;
self->vertices[3].texCoords.y = v;
self->vertices[0].texCoords.x = u2;
self->vertices[0].texCoords.y = v2;
} else {
self->vertices[0].texCoords.x = u;
self->vertices[0].texCoords.y = v2;
self->vertices[1].texCoords.x = u;
self->vertices[1].texCoords.y = v;
self->vertices[2].texCoords.x = u2;
self->vertices[2].texCoords.y = v;
self->vertices[3].texCoords.x = u2;
self->vertices[3].texCoords.y = v2;
}
return &self->super;
}
void _RegionAttachment_draw (SfmlRegionAttachment* self, Slot *slot) {
SfmlSkeleton* skeleton = (SfmlSkeleton*)slot->skeleton;
Uint8 r = skeleton->super.r * slot->r * 255;
Uint8 g = skeleton->super.g * slot->g * 255;
Uint8 b = skeleton->super.b * slot->b * 255;
Uint8 a = skeleton->super.a * slot->a * 255;
sf::Vertex* vertices = self->vertices;
vertices[0].color.r = r;
vertices[0].color.g = g;
vertices[0].color.b = b;
vertices[0].color.a = a;
vertices[1].color.r = r;
vertices[1].color.g = g;
vertices[1].color.b = b;
vertices[1].color.a = a;
vertices[2].color.r = r;
vertices[2].color.g = g;
vertices[2].color.b = b;
vertices[2].color.a = a;
vertices[3].color.r = r;
vertices[3].color.g = g;
vertices[3].color.b = b;
vertices[3].color.a = a;
float* offset = self->super.offset;
Bone* bone = slot->bone;
vertices[0].position.x = offset[0] * bone->m00 + offset[1] * bone->m01 + bone->worldX;
vertices[0].position.y = offset[0] * bone->m10 + offset[1] * bone->m11 + bone->worldY;
vertices[1].position.x = offset[2] * bone->m00 + offset[3] * bone->m01 + bone->worldX;
vertices[1].position.y = offset[2] * bone->m10 + offset[3] * bone->m11 + bone->worldY;
vertices[2].position.x = offset[4] * bone->m00 + offset[5] * bone->m01 + bone->worldX;
vertices[2].position.y = offset[4] * bone->m10 + offset[5] * bone->m11 + bone->worldY;
vertices[3].position.x = offset[6] * bone->m00 + offset[7] * bone->m01 + bone->worldX;
vertices[3].position.y = offset[6] * bone->m10 + offset[7] * bone->m11 + bone->worldY;
// SMFL doesn't handle batching for us, so we'll just force a single texture per skeleton.
skeleton->texture = self->texture;
skeleton->vertexArray->append(vertices[0]);
skeleton->vertexArray->append(vertices[1]);
skeleton->vertexArray->append(vertices[2]);
skeleton->vertexArray->append(vertices[3]);
}
}