mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +08:00
Refactoring.
This commit is contained in:
parent
446e18dccd
commit
596b515e66
@ -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=""${workspace_loc:/${ProjName}/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/include}""/>
|
||||
</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=""${workspace_loc:/${ProjName}/src}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/include}""/>
|
||||
</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>
|
||||
|
||||
@ -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);
|
||||
@ -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);
|
||||
|
||||
/**/
|
||||
|
||||
@ -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
|
||||
}
|
||||
@ -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>
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
85
spine-c/src/spine/Json.h
Normal 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_ */
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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_ */
|
||||
|
||||
@ -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=""${workspace_loc:/spine-cpp/include}""/>
|
||||
<listOptionValue builtIn="false" value=""C:\Users\Nate\Desktop\SFML-2.0-rc\include""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/spine-c/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/spine-c/src}""/>
|
||||
</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=""${workspace_loc:/spine-c/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/spine-c/src}""/>
|
||||
</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=""${workspace_loc:/spine-cpp/Debug}""/>
|
||||
<listOptionValue builtIn="false" value=""C:\Users\Nate\Desktop\SFML-2.0-rc\lib""/>
|
||||
</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">
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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_ */
|
||||
@ -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_ */
|
||||
@ -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_ */
|
||||
@ -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_ */
|
||||
@ -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_ */
|
||||
@ -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_ */
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
@ -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 */
|
||||
155
spine-sfml/src/spine/spine-sfml.cpp
Normal file
155
spine-sfml/src/spine/spine-sfml.cpp
Normal 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]);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user