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">
<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.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"/>
</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">
@ -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.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}/include}&quot;"/>
</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"/>
</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.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">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
@ -104,21 +109,6 @@
<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"/>
</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="refreshScope" versionNumber="2">
<configuration configurationName="Release">
@ -129,4 +119,19 @@
</configuration>
</storageModule>
<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>

View File

@ -17,7 +17,7 @@ typedef struct {
float duration;
} Animation;
Animation* Animation_create ();
Animation* Animation_create (int timelineCount);
void Animation_dispose (Animation* animation);
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);
void AtlasPage_dispose(AtlasPage * this);
void AtlasPage_dispose (AtlasPage* page);
/**/
@ -56,7 +56,7 @@ struct AtlasRegion {
};
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/SkeletonData.h>
#include <spine/Atlas.h>
#include <spine/Animation.h>
#ifdef __cplusplus
namespace spine {
@ -24,7 +25,8 @@ void SkeletonJson_dispose (SkeletonJson* skeletonJson);
SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* skeletonJson, const char* json);
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
}

View File

@ -1,8 +1,11 @@
#ifndef SPINE_SPINE_H_
#define SPINE_SPINE_H_
#include <spine/Animation.h>
#include <spine/Atlas.h>
#include <spine/AtlasAttachmentLoader.h>
#include <spine/Attachment.h>
#include <spine/AttachmentLoader.h>
#include <spine/Bone.h>
#include <spine/BoneData.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
* with a number of internal methods exposed to facilitate extension. */
* with internal methods exposed to facilitate extension. */
#include <stdio.h>
#include <stdlib.h>
@ -15,18 +15,22 @@ typedef struct {
} ExampleAtlasPage;
void _ExampleAtlasPage_dispose (AtlasPage* page) {
ExampleAtlasPage* this = (ExampleAtlasPage*)page;
_AtlasPage_deinit(&this->super);
this->extraData = 0;
FREE(this)
ExampleAtlasPage* self = (ExampleAtlasPage*)page;
_AtlasPage_deinit(&self->super);
self->extraData = 0;
FREE(self)
}
AtlasPage* AtlasPage_create (const char* name) {
ExampleAtlasPage* this = calloc(1, sizeof(ExampleAtlasPage));
_AtlasPage_init(&this->super, name);
this->extraData = 123;
this->super._dispose = _ExampleAtlasPage_dispose;
return &this->super;
ExampleAtlasPage* self = CALLOC(ExampleAtlasPage, 1)
_AtlasPage_init(&self->super, name);
self->super._dispose = _ExampleAtlasPage_dispose;
self->extraData = 123;
return &self->super;
}
/**/
@ -37,18 +41,22 @@ typedef struct {
} ExampleRegionAttachment;
void _ExampleRegionAttachment_dispose (Attachment* attachment) {
ExampleRegionAttachment* this = (ExampleRegionAttachment*)attachment;
_RegionAttachment_deinit(&this->super);
this->extraData = 0;
FREE(this)
ExampleRegionAttachment* self = (ExampleRegionAttachment*)attachment;
_RegionAttachment_deinit(&self->super);
self->extraData = 0;
FREE(self)
}
RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) {
ExampleRegionAttachment* this = calloc(1, sizeof(ExampleRegionAttachment));
_RegionAttachment_init(&this->super, name);
this->extraData = 456;
this->super.super._dispose = _ExampleRegionAttachment_dispose;
return &this->super;
ExampleRegionAttachment* self = CALLOC(ExampleRegionAttachment, 1)
_RegionAttachment_init(&self->super, name);
self->super.super._dispose = _ExampleRegionAttachment_dispose;
self->extraData = 456;
return &self->super;
}
/**/
@ -59,35 +67,43 @@ typedef struct {
} ExampleSkeleton;
void _ExampleSkeleton_dispose (Skeleton* skeleton) {
ExampleSkeleton* this = (ExampleSkeleton*)skeleton;
_Skeleton_deinit(&this->super);
this->extraData = 0;
FREE(this)
ExampleSkeleton* self = (ExampleSkeleton*)skeleton;
_Skeleton_deinit(&self->super);
self->extraData = 0;
FREE(self)
}
Skeleton* Skeleton_create (SkeletonData* data) {
ExampleSkeleton* this = calloc(1, sizeof(ExampleSkeleton));
_Skeleton_init(&this->super, data);
this->extraData = 789;
this->super._dispose = _ExampleSkeleton_dispose;
return &this->super;
ExampleSkeleton* self = CALLOC(ExampleSkeleton, 1)
_Skeleton_init(&self->super, data);
self->super._dispose = _ExampleSkeleton_dispose;
self->extraData = 789;
return &self->super;
}
/**/
int main (void) {
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 page name: %s, extraData: %d\n", atlas->pages->name, ((ExampleAtlasPage*)atlas->pages)->extraData);
SkeletonJson* json = SkeletonJson_create(atlas);
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);
Skeleton* skeleton = Skeleton_create(skeletonData);
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);
SkeletonData_dispose(skeletonData);
SkeletonJson_dispose(json);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,10 +20,10 @@
THE SOFTWARE.
*/
/* cJSON */
/* Json */
/* JSON parser in C. */
#include <spine/cJSON.h>
#include <spine/Json.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
@ -34,11 +34,11 @@
static const char* ep;
const char* cJSON_GetErrorPtr (void) {
const char* Json_getError (void) {
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 (!s2) return 1;
for (; tolower(*s1) == tolower(*s2); ++s1, ++s2)
@ -47,17 +47,17 @@ static int cJSON_strcasecmp (const char* s1, const char* s2) {
}
/* Internal constructor. */
static cJSON *cJSON_create_Item (void) {
return (cJSON*)calloc(1, sizeof(cJSON));
static Json *Json_create_Item (void) {
return (Json*)calloc(1, sizeof(Json));
}
/* Delete a cJSON structure. */
void cJSON_dispose (cJSON *c) {
cJSON *next;
/* Delete a Json structure. */
void Json_dispose (Json *c) {
Json *next;
while (c) {
next = c->next;
if (!(c->type & cJSON_IsReference) && c->child) cJSON_dispose(c->child);
if (!(c->type & cJSON_IsReference) && c->valuestring) free((char*)c->valuestring);
if (c->child) Json_dispose(c->child);
if (c->valuestring) free((char*)c->valuestring);
if (c->name) free((char*)c->name);
free(c);
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. */
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;
int subscale = 0, signsubscale = 1;
@ -95,13 +95,13 @@ static const char* parse_number (cJSON *item, const char* num) {
item->valuefloat = n;
item->valueint = (int)n;
item->type = cJSON_Number;
item->type = Json_Number;
return num;
}
/* 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 char* parse_string (cJSON *item, const char* str) {
static const char* parse_string (Json *item, const char* str) {
const char* ptr = str + 1;
char* ptr2;
char* out;
@ -189,14 +189,14 @@ static const char* parse_string (cJSON *item, const char* str) {
*ptr2 = 0;
if (*ptr == '\"') ptr++;
item->valuestring = out;
item->type = cJSON_String;
item->type = Json_String;
return ptr;
}
/* Predeclare these prototypes. */
static const char* parse_value (cJSON *item, const char* value);
static const char* parse_array (cJSON *item, const char* value);
static const char* parse_object (cJSON *item, const char* value);
static const char* parse_value (Json *item, const char* value);
static const char* parse_array (Json *item, const char* value);
static const char* parse_object (Json *item, const char* value);
/* Utility to jump whitespace and cr/lf */
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. */
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;
cJSON *c = cJSON_create_Item();
Json *c = Json_create_Item();
ep = 0;
if (!c) return 0; /* memory fail */
end = parse_value(c, skip(value));
if (!end) {
cJSON_dispose(c);
Json_dispose(c);
return 0;
} /* 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;
}
/* Default options for cJSON_Parse */
cJSON *cJSON_Parse (const char* value) {
return cJSON_ParseWithOpts(value, 0, 0);
}
/* 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 (!strncmp(value, "null", 4)) {
item->type = cJSON_NULL;
item->type = Json_NULL;
return value + 4;
}
if (!strncmp(value, "false", 5)) {
item->type = cJSON_False;
item->type = Json_False;
return value + 5;
}
if (!strncmp(value, "true", 4)) {
item->type = cJSON_True;
item->type = Json_True;
item->valueint = 1;
return value + 4;
}
@ -270,25 +255,25 @@ static const char* parse_value (cJSON *item, const char* value) {
}
/* Build an array from input text. */
static const char* parse_array (cJSON *item, const char* value) {
cJSON *child;
static const char* parse_array (Json *item, const char* value) {
Json *child;
if (*value != '[') {
ep = value;
return 0;
} /* not an array! */
item->type = cJSON_Array;
item->type = Json_Array;
value = skip(value + 1);
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 */
value = skip(parse_value(child, skip(value))); /* skip any spacing, get the value. */
if (!value) return 0;
while (*value == ',') {
cJSON *new_item;
if (!(new_item = cJSON_create_Item())) return 0; /* memory fail */
Json *new_item;
if (!(new_item = Json_create_Item())) return 0; /* memory fail */
child->next = new_item;
new_item->prev = child;
child = new_item;
@ -302,18 +287,18 @@ static const char* parse_array (cJSON *item, const char* value) {
}
/* Build an object from the text. */
static const char* parse_object (cJSON *item, const char* value) {
cJSON *child;
static const char* parse_object (Json *item, const char* value) {
Json *child;
if (*value != '{') {
ep = value;
return 0;
} /* not an object! */
item->type = cJSON_Object;
item->type = Json_Object;
value = skip(value + 1);
if (*value == '}') return value + 1; /* empty array. */
item->child = child = cJSON_create_Item();
item->child = child = Json_create_Item();
if (!item->child) return 0;
value = skip(parse_string(child, skip(value)));
if (!value) return 0;
@ -327,8 +312,8 @@ static const char* parse_object (cJSON *item, const char* value) {
if (!value) return 0;
while (*value == ',') {
cJSON *new_item;
if (!(new_item = cJSON_create_Item())) return 0; /* memory fail */
Json *new_item;
if (!(new_item = Json_create_Item())) return 0; /* memory fail */
child->next = new_item;
new_item->prev = child;
child = new_item;
@ -350,40 +335,40 @@ static const char* parse_object (cJSON *item, const char* value) {
}
/* Get Array size/item / object item. */
int cJSON_GetArraySize (cJSON *array) {
cJSON *c = array->child;
int Json_getSize (Json *array) {
Json *c = array->child;
int i = 0;
while (c)
i++, c = c->next;
return i;
}
cJSON *cJSON_GetArrayItem (cJSON *array, int item) {
cJSON *c = array->child;
Json *Json_getItemAt (Json *array, int item) {
Json *c = array->child;
while (c && item > 0)
item--, c = c->next;
return c;
}
cJSON *cJSON_GetObjectItem (cJSON *object, const char* string) {
cJSON *c = object->child;
while (c && cJSON_strcasecmp(c->name, string))
Json *Json_getItem (Json *object, const char* string) {
Json *c = object->child;
while (c && Json_strcasecmp(c->name, string))
c = c->next;
return c;
}
const char* cJSON_GetObjectString (cJSON* object, const char* name, const char* defaultValue) {
object = cJSON_GetObjectItem(object, name);
const char* Json_getString (Json* object, const char* name, const char* defaultValue) {
object = Json_getItem(object, name);
if (object) return object->valuestring;
return defaultValue;
}
float cJSON_GetObjectFloat (cJSON* value, const char* name, float defaultValue) {
value = cJSON_GetObjectItem(value, name);
float Json_getFloat (Json* value, const char* name, float defaultValue) {
value = Json_getItem(value, name);
return value ? value->valuefloat : defaultValue;
}
int cJSON_GetObjectInt (cJSON* value, const char* name, int defaultValue) {
value = cJSON_GetObjectItem(value, name);
int Json_getInt (Json* value, const char* name, int defaultValue) {
value = Json_getItem(value, name);
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/extension.h>
void _RegionAttachment_init (RegionAttachment* this, const char* name) {
this->scaleX = 1;
this->scaleY = 1;
_Attachment_init(&this->super, name, ATTACHMENT_REGION);
void _RegionAttachment_init (RegionAttachment* self, const char* name) {
self->scaleX = 1;
self->scaleY = 1;
_Attachment_init(&self->super, name, ATTACHMENT_REGION);
}
void _RegionAttachment_deinit (RegionAttachment* this) {
_Attachment_deinit(&this->super);
void _RegionAttachment_deinit (RegionAttachment* self) {
_Attachment_deinit(&self->super);
}
void RegionAttachment_updateOffset (RegionAttachment* this) {
float localX2 = this->width / 2;
float localY2 = this->height / 2;
void RegionAttachment_updateOffset (RegionAttachment* self) {
float localX2 = self->width / 2;
float localY2 = self->height / 2;
float localX = -localX2;
float localY = -localY2;
localX *= this->scaleX;
localY *= this->scaleY;
localX2 *= this->scaleX;
localY2 *= this->scaleY;
float radians = (float)(this->rotation * 3.1415926535897932385 / 180);
float cosine = cos(radians);
float sine = sin(radians);
float localXCos = localX * cosine + this->x;
localX *= self->scaleX;
localY *= self->scaleY;
localX2 *= self->scaleX;
localY2 *= self->scaleY;
float radians = (float)(self->rotation * 3.1415926535897932385 / 180);
float cosine = cosf(radians);
float sine = sinf(radians);
float localXCos = localX * cosine + self->x;
float localXSin = localX * sine;
float localYCos = localY * cosine + this->y;
float localYCos = localY * cosine + self->y;
float localYSin = localY * sine;
float localX2Cos = localX2 * cosine + this->x;
float localX2Cos = localX2 * cosine + self->x;
float localX2Sin = localX2 * sine;
float localY2Cos = localY2 * cosine + this->y;
float localY2Cos = localY2 * cosine + self->y;
float localY2Sin = localY2 * sine;
this->offset[0] = localXCos - localYSin;
this->offset[1] = localYCos + localXSin;
this->offset[2] = localXCos - localY2Sin;
this->offset[3] = localY2Cos + localXSin;
this->offset[4] = localX2Cos - localY2Sin;
this->offset[5] = localY2Cos + localX2Sin;
this->offset[6] = localX2Cos - localYSin;
this->offset[7] = localYCos + localX2Sin;
self->offset[0] = localXCos - localYSin;
self->offset[1] = localYCos + localXSin;
self->offset[2] = localXCos - localY2Sin;
self->offset[3] = localY2Cos + localXSin;
self->offset[4] = localX2Cos - localY2Sin;
self->offset[5] = localY2Cos + localX2Sin;
self->offset[6] = localX2Cos - localYSin;
self->offset[7] = localYCos + localX2Sin;
}

View File

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

View File

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

View File

@ -2,44 +2,44 @@
#include <math.h>
#include <stdio.h>
#include <spine/util.h>
#include <spine/cJSON.h>
#include <math.h>
#include <spine/Json.h>
#include <spine/RegionAttachment.h>
#include <spine/AtlasAttachmentLoader.h>
typedef struct {
SkeletonJson json;
int ownsLoader;
} Private;
} Internal;
SkeletonJson* SkeletonJson_createWithLoader (AttachmentLoader* attachmentLoader) {
SkeletonJson* this = calloc(1, sizeof(Private));
this->scale = 1;
this->attachmentLoader = attachmentLoader;
return this;
SkeletonJson* self = (SkeletonJson*)CALLOC(Internal, 1)
self->scale = 1;
self->attachmentLoader = attachmentLoader;
return self;
}
SkeletonJson* SkeletonJson_create (Atlas* atlas) {
AtlasAttachmentLoader* attachmentLoader = AtlasAttachmentLoader_create(atlas);
Private* this = (Private*)SkeletonJson_createWithLoader(&attachmentLoader->super);
this->ownsLoader = 1;
return &this->json;
Internal* self = (Internal*)SkeletonJson_createWithLoader(&attachmentLoader->super);
self->ownsLoader = 1;
return &self->json;
}
void SkeletonJson_dispose (SkeletonJson* this) {
if (((Private*)this)->ownsLoader) AttachmentLoader_dispose(this->attachmentLoader);
FREE(this->error)
FREE(this)
void SkeletonJson_dispose (SkeletonJson* self) {
if (((Internal*)self)->ownsLoader) AttachmentLoader_dispose(self->attachmentLoader);
FREE(self->error)
FREE(self)
}
void* _SkeletonJson_setError (SkeletonJson* this, cJSON* root, const char* value1, const char* value2) {
FREE(this->error)
void _SkeletonJson_setError (SkeletonJson* self, Json* root, const char* value1, const char* value2) {
FREE(self->error)
char message[256];
strcpy(message, value1);
int length = strlen(value1);
if (value2) strncat(message + length, value2, 256 - length);
MALLOC_STR(this->error, message)
if (root) cJSON_dispose(root);
return 0;
MALLOC_STR(self->error, message)
if (root) Json_dispose(root);
}
static float toColor (const char* value, int index) {
@ -55,67 +55,81 @@ static float toColor (const char* value, int index) {
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);
if (!data) return _SkeletonJson_setError(this, 0, "Unable to read file: ", path);
SkeletonData* skeletonData = SkeletonJson_readSkeletonData(this, data);
if (!data) {
_SkeletonJson_setError(self, 0, "Unable to read skeleton file: ", path);
return 0;
}
SkeletonData* skeletonData = SkeletonJson_readSkeletonData(self, data);
FREE(data)
return skeletonData;
}
SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* this, const char* json) {
FREE(this->error)
CAST(char*, this->error) = 0;
SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* self, const char* json) {
FREE(self->error)
CAST(char*, self->error) = 0;
cJSON* root = cJSON_Parse(json);
if (!root) return _SkeletonJson_setError(this, 0, "Invalid JSON: ", cJSON_GetErrorPtr());
Json* root = Json_create(json);
if (!root) {
_SkeletonJson_setError(self, 0, "Invalid skeleton JSON: ", Json_getError());
return 0;
}
SkeletonData* skeletonData = SkeletonData_create();
int i, ii, iii;
cJSON* bones = cJSON_GetObjectItem(root, "bones");
int boneCount = cJSON_GetArraySize(bones);
skeletonData->bones = malloc(sizeof(BoneData*) * boneCount);
Json* bones = Json_getItem(root, "bones");
int boneCount = Json_getSize(bones);
skeletonData->bones = MALLOC(BoneData*, boneCount)
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;
const char* parentName = cJSON_GetObjectString(boneMap, "parent", 0);
const char* parentName = Json_getString(boneMap, "parent", 0);
if (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->length = cJSON_GetObjectFloat(boneMap, "parent", 0) * this->scale;
boneData->x = cJSON_GetObjectFloat(boneMap, "x", 0) * this->scale;
boneData->y = cJSON_GetObjectFloat(boneMap, "y", 0) * this->scale;
boneData->rotation = cJSON_GetObjectFloat(boneMap, "rotation", 0);
boneData->scaleX = cJSON_GetObjectFloat(boneMap, "scaleX", 1);
boneData->scaleY = cJSON_GetObjectFloat(boneMap, "scaleY", 1);
boneData->length = Json_getFloat(boneMap, "parent", 0) * self->scale;
boneData->x = Json_getFloat(boneMap, "x", 0) * self->scale;
boneData->y = Json_getFloat(boneMap, "y", 0) * self->scale;
boneData->rotation = Json_getFloat(boneMap, "rotation", 0);
boneData->scaleX = Json_getFloat(boneMap, "scaleX", 1);
boneData->scaleY = Json_getFloat(boneMap, "scaleY", 1);
skeletonData->bones[i] = boneData;
skeletonData->boneCount++;
}
cJSON* slots = cJSON_GetObjectItem(root, "slots");
Json* slots = Json_getItem(root, "slots");
if (slots) {
int slotCount = cJSON_GetArraySize(slots);
skeletonData->slots = malloc(sizeof(SlotData*) * slotCount);
int slotCount = Json_getSize(slots);
skeletonData->slots = MALLOC(SlotData*, slotCount)
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);
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);
const char* color = cJSON_GetObjectString(slotMap, "color", 0);
const char* color = Json_getString(slotMap, "color", 0);
if (color) {
slotData->r = toColor(color, 0);
slotData->g = toColor(color, 1);
@ -123,7 +137,7 @@ SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* this, const char* jso
slotData->a = toColor(color, 3);
}
cJSON *attachmentItem = cJSON_GetObjectItem(slotMap, "attachment");
Json *attachmentItem = Json_getItem(slotMap, "attachment");
if (attachmentItem) SlotData_setAttachmentName(slotData, attachmentItem->valuestring);
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) {
int skinCount = cJSON_GetArraySize(skinsMap);
skeletonData->skins = malloc(sizeof(Skin*) * skinCount);
int skinCount = Json_getSize(skinsMap);
skeletonData->skins = MALLOC(Skin*, skinCount)
for (i = 0; i < skinCount; ++i) {
cJSON* slotMap = cJSON_GetArrayItem(skinsMap, i);
Json* slotMap = Json_getItemAt(skinsMap, i);
const char* skinName = slotMap->name;
Skin *skin = Skin_create(skinName);
skeletonData->skins[i] = skin;
skeletonData->skinCount++;
if (strcmp(skinName, "default") == 0) skeletonData->defaultSkin = skin;
int slotNameCount = cJSON_GetArraySize(slotMap);
int slotNameCount = Json_getSize(slotMap);
for (ii = 0; ii < slotNameCount; ++ii) {
cJSON* attachmentsMap = cJSON_GetArrayItem(slotMap, ii);
Json* attachmentsMap = Json_getItemAt(slotMap, ii);
const char* slotName = attachmentsMap->name;
int slotIndex = SkeletonData_findSlotIndex(skeletonData, slotName);
int attachmentCount = cJSON_GetArraySize(attachmentsMap);
int attachmentCount = Json_getSize(attachmentsMap);
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* 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;
if (strcmp(typeString, "region") == 0)
type = ATTACHMENT_REGION;
else if (strcmp(typeString, "regionSequence") == 0)
type = ATTACHMENT_REGION_SEQUENCE;
else
return _SkeletonJson_setError(this, root, "Unknown attachment type: ", typeString);
else {
SkeletonData_dispose(skeletonData);
_SkeletonJson_setError(self, root, "Unknown attachment type: ", typeString);
return 0;
}
Attachment* attachment = AttachmentLoader_newAttachment(this->attachmentLoader, type, attachmentName);
if (!attachment && this->attachmentLoader->error1)
return _SkeletonJson_setError(this, root, this->attachmentLoader->error1, this->attachmentLoader->error2);
Attachment* attachment = AttachmentLoader_newAttachment(self->attachmentLoader, type, attachmentName);
if (!attachment && self->attachmentLoader->error1) {
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) {
RegionAttachment* regionAttachment = (RegionAttachment*)attachment;
regionAttachment->x = cJSON_GetObjectFloat(attachmentMap, "x", 0) * this->scale;
regionAttachment->y = cJSON_GetObjectFloat(attachmentMap, "y", 0) * this->scale;
regionAttachment->scaleX = cJSON_GetObjectFloat(attachmentMap, "scaleX", 1);
regionAttachment->scaleY = cJSON_GetObjectFloat(attachmentMap, "scaleY", 1);
regionAttachment->rotation = cJSON_GetObjectFloat(attachmentMap, "rotation", 0);
regionAttachment->width = cJSON_GetObjectFloat(attachmentMap, "width", 32) * this->scale;
regionAttachment->height = cJSON_GetObjectFloat(attachmentMap, "height", 32) * this->scale;
regionAttachment->x = Json_getFloat(attachmentMap, "x", 0) * self->scale;
regionAttachment->y = Json_getFloat(attachmentMap, "y", 0) * self->scale;
regionAttachment->scaleX = Json_getFloat(attachmentMap, "scaleX", 1);
regionAttachment->scaleY = Json_getFloat(attachmentMap, "scaleY", 1);
regionAttachment->rotation = Json_getFloat(attachmentMap, "rotation", 0);
regionAttachment->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
regionAttachment->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
RegionAttachment_updateOffset(regionAttachment);
}
@ -186,6 +206,160 @@ SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* this, const char* jso
}
}
cJSON_dispose(root);
Json_dispose(root);
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>
SkinEntry* _SkinEntry_create (int slotIndex, const char* name, Attachment* attachment) {
SkinEntry* this = calloc(1, sizeof(SkinEntry));
this->slotIndex = slotIndex;
MALLOC_STR(this->name, name)
this->attachment = attachment;
return this;
SkinEntry* self = CALLOC(SkinEntry, 1)
self->slotIndex = slotIndex;
MALLOC_STR(self->name, name)
self->attachment = attachment;
return self;
}
void _SkinEntry_dispose (SkinEntry* this) {
if (this->next) _SkinEntry_dispose((SkinEntry*)this->next);
Attachment_dispose(this->attachment);
FREE(this->name)
FREE(this)
void _SkinEntry_dispose (SkinEntry* self) {
if (self->next) _SkinEntry_dispose((SkinEntry*)self->next);
Attachment_dispose(self->attachment);
FREE(self->name)
FREE(self)
}
/**/
Skin* Skin_create (const char* name) {
Skin* this = calloc(1, sizeof(Skin));
MALLOC_STR(this->name, name)
return this;
Skin* self = CALLOC(Skin, 1)
MALLOC_STR(self->name, name)
return self;
}
void Skin_dispose (Skin* this) {
_SkinEntry_dispose((SkinEntry*)this->entries);
FREE(this->name)
FREE(this)
void Skin_dispose (Skin* self) {
_SkinEntry_dispose((SkinEntry*)self->entries);
FREE(self->name)
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* entry = (SkinEntry*)this->entries;
SkinEntry* entry = (SkinEntry*)self->entries;
if (!entry)
CAST(SkinEntry*, this->entries) = newEntry;
CAST(SkinEntry*, self->entries) = newEntry;
else {
while (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) {
const SkinEntry* entry = this->entries;
Attachment* Skin_getAttachment (const Skin* self, int slotIndex, const char* name) {
const SkinEntry* entry = self->entries;
while (entry) {
if (entry->slotIndex == slotIndex && strcmp(entry->name, name) == 0) return entry->attachment;
entry = entry->next;

View File

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

View File

@ -2,26 +2,26 @@
#include <spine/util.h>
SlotData* SlotData_create (const char* name, BoneData* boneData) {
SlotData* this = calloc(1, sizeof(SlotData));
MALLOC_STR(this->name, name)
CAST(BoneData*, this->boneData) = boneData;
this->r = 1;
this->g = 1;
this->b = 1;
this->a = 1;
return this;
SlotData* self = CALLOC(SlotData, 1)
MALLOC_STR(self->name, name)
CAST(BoneData*, self->boneData) = boneData;
self->r = 1;
self->g = 1;
self->b = 1;
self->a = 1;
return self;
}
void SlotData_dispose (SlotData* this) {
FREE(this->name);
FREE(this->attachmentName);
FREE(this);
void SlotData_dispose (SlotData* self) {
FREE(self->name);
FREE(self->attachmentName);
FREE(self);
}
void SlotData_setAttachmentName (SlotData* this, const char* attachmentName) {
FREE(this->attachmentName);
void SlotData_setAttachmentName (SlotData* self, const char* attachmentName) {
FREE(self->attachmentName);
if (attachmentName)
MALLOC_STR(this->attachmentName, attachmentName)
MALLOC_STR(self->attachmentName, attachmentName)
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_
#define SPINE_EXTENSION_H_
#ifdef __cplusplus
namespace spine {
extern "C" {
#endif
#include <spine/Skeleton.h>
#include <spine/RegionAttachment.h>
#include <spine/Animation.h>
#include <spine/Atlas.h>
#include <spine/AttachmentLoader.h>
#ifdef __cplusplus
namespace spine {
extern "C" {
#endif
/* Methods that must be implemented: **/
Skeleton* Skeleton_create (SkeletonData* data);
@ -42,7 +42,7 @@ void _AtlasPage_deinit (AtlasPage* page);
void _AttachmentLoader_init (AttachmentLoader* loader);
void _AttachmentLoader_deinit (AttachmentLoader* loader);
void* _AttachmentLoader_setError (AttachmentLoader* loader, const char* error1, const char* error2);
void _AttachmentLoader_setError (AttachmentLoader* loader, const char* error1, const char* error2);
#ifdef __cplusplus
}

View File

@ -4,13 +4,26 @@
#include <stdlib.h>
#include <string.h>
#ifdef __cplusplus
namespace spine {
extern "C" {
#endif
/* Used to cast away const on an lvalue. */
#define CAST(TYPE,VALUE) *(TYPE*)&VALUE
#define MALLOC_STR(TO,FROM) strcpy(CAST(char*, TO) = malloc(strlen(FROM)), FROM);
#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);
const char* readFile (const char* path);
#ifdef __cplusplus
}
}
#endif
#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"/>
<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">
<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"/>
</tool>
<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.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">
<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;${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 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"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1445618618" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</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 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"/>
</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.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">
<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;"/>
</option>
<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-window-d"/>
<listOptionValue builtIn="false" value="sfml-graphics-d"/>
@ -64,19 +65,12 @@
</toolChain>
</folderInfo>
<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>
</configuration>
</storageModule>
<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>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<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">

View File

@ -3,7 +3,6 @@
<name>spine-sfml</name>
<comment></comment>
<projects>
<project>spine-cpp</project>
</projects>
<buildSpec>
<buildCommand>
@ -25,4 +24,11 @@
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>spine-c src</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/spine-c/src</locationURI>
</link>
</linkedResources>
</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 <spine-sfml/spine.h>
#include <spine/spine.h>
#include <SFML/Graphics.hpp>
using namespace std;
@ -33,18 +33,19 @@ using namespace spine;
int main () {
try {
Atlas *atlas = new Atlas("../data/spineboy.atlas");
SkeletonJson json(atlas);
SkeletonData *skeletonData = json.readSkeletonData("../data/spineboy-skeleton.json");
Animation *animation = json.readAnimation("../data/spineboy-walk.json", skeletonData);
Atlas* atlas = Atlas_readAtlasFile("../data/spineboy.atlas");
SkeletonJson* json = SkeletonJson_create(atlas);
SkeletonData *skeletonData = SkeletonJson_readSkeletonDataFile(json, "../data/spineboy-skeleton.json");
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->flipY = false;
skeleton->setToBindPose();
skeleton->getRootBone()->x = 320;
skeleton->getRootBone()->y = 420;
skeleton->updateWorldTransform();
Skeleton_setToBindPose(skeleton);
Skeleton_getRootBone(skeleton)->x = 320;
Skeleton_getRootBone(skeleton)->y = 420;
Skeleton_updateWorldTransform(skeleton);
sf::RenderWindow window(sf::VideoMode(640, 480), "Spine SFML");
window.setFramerateLimit(60);
@ -55,16 +56,20 @@ int main () {
while (window.pollEvent(event))
if (event.type == sf::Event::Closed) window.close();
window.clear();
window.draw(*skeleton);
//window.draw(*skeleton);
window.display();
float delta = deltaClock.getElapsedTime().asSeconds();
deltaClock.restart();
animationTime += delta;
animation->apply(skeleton, animationTime, true);
skeleton->updateWorldTransform();
Animation_apply(animation, skeleton, animationTime, true);
Skeleton_updateWorldTransform(skeleton);
}
Skeleton_dispose(skeleton);
SkeletonData_dispose(skeletonData);
Atlas_dispose(atlas);
} catch (exception &ex) {
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]);
}
}