mirror of https://github.com/axmolengine/axmol.git
issue #2075: Adding spine editor support. Adding a new test 'SpineTest' in TestCpp, adding the parse code in "extensions/spine". It works only on iOS now.
This commit is contained in:
parent
dc0e89e839
commit
2d1172814d
|
@ -51,7 +51,26 @@ GUI/CCEditBox/CCEditBoxImplAndroid.cpp \
|
|||
network/HttpClient.cpp \
|
||||
physics_nodes/CCPhysicsDebugNode.cpp \
|
||||
physics_nodes/CCPhysicsSprite.cpp \
|
||||
LocalStorage/LocalStorageAndroid.cpp
|
||||
LocalStorage/LocalStorageAndroid.cpp \
|
||||
spine/Animation.cpp \
|
||||
spine/AnimationState.cpp \
|
||||
spine/AnimationStateData.cpp \
|
||||
spine/Atlas.cpp \
|
||||
spine/AtlasAttachmentLoader.cpp \
|
||||
spine/Attachment.cpp \
|
||||
spine/AttachmentLoader.cpp \
|
||||
spine/Bone.cpp \
|
||||
spine/BoneData.cpp \
|
||||
spine/Json.cpp \
|
||||
spine/RegionAttachment.cpp \
|
||||
spine/Skeleton.cpp \
|
||||
spine/SkeletonData.cpp \
|
||||
spine/SkeletonJson.cpp \
|
||||
spine/Skin.cpp \
|
||||
spine/Slot.cpp \
|
||||
spine/SlotData.cpp \
|
||||
spine/extension.cpp \
|
||||
spine/spine-cocos2dx.cpp
|
||||
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static
|
||||
|
|
|
@ -0,0 +1,462 @@
|
|||
/*******************************************************************************
|
||||
* 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/Animation.h>
|
||||
#include <math.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
Animation* Animation_create (const char* name, int timelineCount) {
|
||||
Animation* self = NEW(Animation);
|
||||
MALLOC_STR(self->name, name);
|
||||
self->timelineCount = timelineCount;
|
||||
self->timelines = MALLOC(Timeline*, timelineCount);
|
||||
return self;
|
||||
}
|
||||
|
||||
void Animation_dispose (Animation* self) {
|
||||
int i;
|
||||
for (i = 0; i < self->timelineCount; ++i)
|
||||
Timeline_dispose(self->timelines[i]);
|
||||
FREE(self->timelines);
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
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 = self->timelineCount;
|
||||
for (i = 0; i < n; ++i)
|
||||
Timeline_apply(self->timelines[i], skeleton, time, 1);
|
||||
}
|
||||
|
||||
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 = self->timelineCount;
|
||||
for (i = 0; i < n; ++i)
|
||||
Timeline_apply(self->timelines[i], skeleton, time, alpha);
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct _TimelineVtable {
|
||||
void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha);
|
||||
void (*dispose) (Timeline* self);
|
||||
} _TimelineVtable;
|
||||
|
||||
void _Timeline_init (Timeline* self, //
|
||||
void (*dispose) (Timeline* self), //
|
||||
void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha)) {
|
||||
CONST_CAST(_TimelineVtable*, self->vtable) = NEW(_TimelineVtable);
|
||||
VTABLE(Timeline, self) ->dispose = dispose;
|
||||
VTABLE(Timeline, self) ->apply = apply;
|
||||
}
|
||||
|
||||
void _Timeline_deinit (Timeline* self) {
|
||||
FREE(self->vtable);
|
||||
}
|
||||
|
||||
void Timeline_dispose (Timeline* self) {
|
||||
VTABLE(Timeline, self) ->dispose(self);
|
||||
}
|
||||
|
||||
void Timeline_apply (const Timeline* self, Skeleton* skeleton, float time, float alpha) {
|
||||
VTABLE(Timeline, self) ->apply(self, skeleton, time, alpha);
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
static const float CURVE_LINEAR = 0;
|
||||
static const float CURVE_STEPPED = -1;
|
||||
static const int CURVE_SEGMENTS = 10;
|
||||
|
||||
void _CurveTimeline_init (CurveTimeline* self, int frameCount, //
|
||||
void (*dispose) (Timeline* self), //
|
||||
void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha)) {
|
||||
_Timeline_init(SUPER(self), dispose, apply);
|
||||
self->curves = CALLOC(float, (frameCount - 1) * 6);
|
||||
}
|
||||
|
||||
void _CurveTimeline_deinit (CurveTimeline* self) {
|
||||
_Timeline_deinit(SUPER(self));
|
||||
FREE(self->curves);
|
||||
}
|
||||
|
||||
void CurveTimeline_setLinear (CurveTimeline* self, int frameIndex) {
|
||||
self->curves[frameIndex * 6] = CURVE_LINEAR;
|
||||
}
|
||||
|
||||
void CurveTimeline_setStepped (CurveTimeline* self, int frameIndex) {
|
||||
self->curves[frameIndex * 6] = CURVE_STEPPED;
|
||||
}
|
||||
|
||||
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;
|
||||
float pre1 = 3 * subdiv_step;
|
||||
float pre2 = 3 * subdiv_step2;
|
||||
float pre4 = 6 * subdiv_step2;
|
||||
float pre5 = 6 * subdiv_step3;
|
||||
float tmp1x = -cx1 * 2 + cx2;
|
||||
float tmp1y = -cy1 * 2 + cy2;
|
||||
float tmp2x = (cx1 - cx2) * 3 + 1;
|
||||
float tmp2y = (cy1 - cy2) * 3 + 1;
|
||||
int i = frameIndex * 6;
|
||||
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 (const CurveTimeline* self, int frameIndex, float percent) {
|
||||
int curveIndex = frameIndex * 6;
|
||||
float dfx = self->curves[curveIndex];
|
||||
if (dfx == CURVE_LINEAR) return percent;
|
||||
if (dfx == CURVE_STEPPED) return 0;
|
||||
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) {
|
||||
if (x >= percent) {
|
||||
float lastX = x - dfx;
|
||||
float lastY = y - dfy;
|
||||
return lastY + (y - lastY) * (percent - lastX) / (x - lastX);
|
||||
}
|
||||
if (i == 0) break;
|
||||
i--;
|
||||
dfx += ddfx;
|
||||
dfy += ddfy;
|
||||
ddfx += dddfx;
|
||||
ddfy += dddfy;
|
||||
x += dfx;
|
||||
y += dfy;
|
||||
}
|
||||
return y + (1 - y) * (percent - x) / (1 - x); /* Last point is 1,1. */
|
||||
}
|
||||
|
||||
/* @param target After the first and before the last entry. */
|
||||
static int binarySearch (float *values, int valuesLength, float target, int step) {
|
||||
int low = 0;
|
||||
int high = valuesLength / step - 2;
|
||||
if (high == 0) return step;
|
||||
int current = high >> 1;
|
||||
while (1) {
|
||||
if (values[(current + 1) * step] <= target)
|
||||
low = current + 1;
|
||||
else
|
||||
high = current;
|
||||
if (low == high) return (low + 1) * step;
|
||||
current = (low + high) >> 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*static int linearSearch (float *values, int valuesLength, float target, int step) {
|
||||
int i, last = valuesLength - step;
|
||||
for (i = 0; i <= last; i += step) {
|
||||
if (values[i] <= target) continue;
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}*/
|
||||
|
||||
/**/
|
||||
|
||||
void _BaseTimeline_dispose (Timeline* timeline) {
|
||||
struct BaseTimeline* self = SUB_CAST(struct BaseTimeline, timeline);
|
||||
_CurveTimeline_deinit(SUPER(self));
|
||||
FREE(self->frames);
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
/* Many timelines have structure identical to struct BaseTimeline and extend CurveTimeline. **/
|
||||
struct BaseTimeline* _BaseTimeline_create (int frameCount, int frameSize, //
|
||||
void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha)) {
|
||||
|
||||
struct BaseTimeline* self = NEW(struct BaseTimeline);
|
||||
_CurveTimeline_init(SUPER(self), frameCount, _BaseTimeline_dispose, apply);
|
||||
|
||||
CONST_CAST(int, self->framesLength) = frameCount * frameSize;
|
||||
CONST_CAST(float*, self->frames) = CALLOC(float, self->framesLength);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
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* self = SUB_CAST(RotateTimeline, timeline);
|
||||
|
||||
if (time < self->frames[0]) return; /* Time is before first frame. */
|
||||
|
||||
Bone *bone = skeleton->bones[self->boneIndex];
|
||||
|
||||
if (time >= self->frames[self->framesLength - 2]) { /* Time is after last frame. */
|
||||
float amount = bone->data->rotation + self->frames[self->framesLength - 1] - bone->rotation;
|
||||
while (amount > 180)
|
||||
amount -= 360;
|
||||
while (amount < -180)
|
||||
amount += 360;
|
||||
bone->rotation += amount * alpha;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Interpolate between the last frame and the current frame. */
|
||||
int frameIndex = binarySearch(self->frames, self->framesLength, 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(SUPER(self), frameIndex / 2 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
|
||||
|
||||
float amount = self->frames[frameIndex + ROTATE_FRAME_VALUE] - lastFrameValue;
|
||||
while (amount > 180)
|
||||
amount -= 360;
|
||||
while (amount < -180)
|
||||
amount += 360;
|
||||
amount = bone->data->rotation + (lastFrameValue + amount * percent) - bone->rotation;
|
||||
while (amount > 180)
|
||||
amount -= 360;
|
||||
while (amount < -180)
|
||||
amount += 360;
|
||||
bone->rotation += amount * alpha;
|
||||
}
|
||||
|
||||
RotateTimeline* RotateTimeline_create (int frameCount) {
|
||||
return _BaseTimeline_create(frameCount, 2, _RotateTimeline_apply);
|
||||
}
|
||||
|
||||
void RotateTimeline_setFrame (RotateTimeline* self, int frameIndex, float time, float angle) {
|
||||
frameIndex *= 2;
|
||||
self->frames[frameIndex] = time;
|
||||
self->frames[frameIndex + 1] = angle;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
static const int TRANSLATE_LAST_FRAME_TIME = -3;
|
||||
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* self = SUB_CAST(TranslateTimeline, timeline);
|
||||
|
||||
if (time < self->frames[0]) return; /* Time is before first frame. */
|
||||
|
||||
Bone *bone = skeleton->bones[self->boneIndex];
|
||||
|
||||
if (time >= self->frames[self->framesLength - 3]) { /* Time is after last frame. */
|
||||
bone->x += (bone->data->x + self->frames[self->framesLength - 2] - bone->x) * alpha;
|
||||
bone->y += (bone->data->y + self->frames[self->framesLength - 1] - bone->y) * alpha;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Interpolate between the last frame and the current frame. */
|
||||
int frameIndex = binarySearch(self->frames, self->framesLength, 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(SUPER(self), frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
|
||||
|
||||
bone->x += (bone->data->x + lastFrameX + (self->frames[frameIndex + TRANSLATE_FRAME_X] - lastFrameX) * percent - bone->x)
|
||||
* alpha;
|
||||
bone->y += (bone->data->y + lastFrameY + (self->frames[frameIndex + TRANSLATE_FRAME_Y] - lastFrameY) * percent - bone->y)
|
||||
* alpha;
|
||||
}
|
||||
|
||||
TranslateTimeline* TranslateTimeline_create (int frameCount) {
|
||||
return _BaseTimeline_create(frameCount, 3, _TranslateTimeline_apply);
|
||||
}
|
||||
|
||||
void TranslateTimeline_setFrame (TranslateTimeline* self, int frameIndex, float time, float x, float y) {
|
||||
frameIndex *= 3;
|
||||
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* self = SUB_CAST(ScaleTimeline, timeline);
|
||||
|
||||
if (time < self->frames[0]) return; /* Time is before first frame. */
|
||||
|
||||
Bone *bone = skeleton->bones[self->boneIndex];
|
||||
if (time >= self->frames[self->framesLength - 3]) { /* Time is after last frame. */
|
||||
bone->scaleX += (bone->data->scaleX - 1 + self->frames[self->framesLength - 2] - bone->scaleX) * alpha;
|
||||
bone->scaleY += (bone->data->scaleY - 1 + self->frames[self->framesLength - 1] - bone->scaleY) * alpha;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Interpolate between the last frame and the current frame. */
|
||||
int frameIndex = binarySearch(self->frames, self->framesLength, 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(SUPER(self), frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : 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 + (self->frames[frameIndex + TRANSLATE_FRAME_Y] - lastFrameY) * percent
|
||||
- bone->scaleY) * alpha;
|
||||
}
|
||||
|
||||
ScaleTimeline* ScaleTimeline_create (int frameCount) {
|
||||
return _BaseTimeline_create(frameCount, 3, _ScaleTimeline_apply);
|
||||
}
|
||||
|
||||
void ScaleTimeline_setFrame (ScaleTimeline* self, int frameIndex, float time, float x, float y) {
|
||||
TranslateTimeline_setFrame(self, frameIndex, time, x, y);
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
static const int COLOR_LAST_FRAME_TIME = -5;
|
||||
static const int COLOR_FRAME_R = 1;
|
||||
static const int COLOR_FRAME_G = 2;
|
||||
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* self = (ColorTimeline*)timeline;
|
||||
|
||||
if (time < self->frames[0]) return; /* Time is before first frame. */
|
||||
|
||||
Slot *slot = skeleton->slots[self->slotIndex];
|
||||
|
||||
if (time >= self->frames[self->framesLength - 5]) { /* Time is after last frame. */
|
||||
int i = self->framesLength - 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(self->frames, self->framesLength, 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(SUPER(self), frameIndex / 5 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : 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;
|
||||
slot->b += (b - slot->b) * alpha;
|
||||
slot->a += (a - slot->a) * alpha;
|
||||
} else {
|
||||
slot->r = r;
|
||||
slot->g = g;
|
||||
slot->b = b;
|
||||
slot->a = a;
|
||||
}
|
||||
}
|
||||
|
||||
ColorTimeline* ColorTimeline_create (int frameCount) {
|
||||
return (ColorTimeline*)_BaseTimeline_create(frameCount, 5, _ColorTimeline_apply);
|
||||
}
|
||||
|
||||
void ColorTimeline_setFrame (ColorTimeline* self, int frameIndex, float time, float r, float g, float b, float a) {
|
||||
frameIndex *= 5;
|
||||
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* self = (AttachmentTimeline*)timeline;
|
||||
|
||||
if (time < self->frames[0]) return; /* Time is before first frame. */
|
||||
|
||||
int frameIndex;
|
||||
if (time >= self->frames[self->framesLength - 1]) /* Time is after last frame. */
|
||||
frameIndex = self->framesLength - 1;
|
||||
else
|
||||
frameIndex = binarySearch(self->frames, self->framesLength, time, 1) - 1;
|
||||
|
||||
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* self = (AttachmentTimeline*)timeline;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < self->framesLength; ++i)
|
||||
FREE(self->attachmentNames[i]);
|
||||
FREE(self->attachmentNames);
|
||||
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
AttachmentTimeline* AttachmentTimeline_create (int frameCount) {
|
||||
AttachmentTimeline* self = NEW(AttachmentTimeline);
|
||||
_Timeline_init(SUPER(self), _AttachmentTimeline_dispose, _AttachmentTimeline_apply);
|
||||
|
||||
CONST_CAST(char**, self->attachmentNames) = CALLOC(char*, frameCount);
|
||||
CONST_CAST(int, self->framesLength) = frameCount;
|
||||
CONST_CAST(float*, self->frames) = CALLOC(float, frameCount);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void AttachmentTimeline_setFrame (AttachmentTimeline* self, int frameIndex, float time, const char* attachmentName) {
|
||||
self->frames[frameIndex] = time;
|
||||
FREE(self->attachmentNames[frameIndex]);
|
||||
if (attachmentName)
|
||||
MALLOC_STR(self->attachmentNames[frameIndex], attachmentName);
|
||||
else
|
||||
self->attachmentNames[frameIndex] = 0;
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,132 @@
|
|||
/*******************************************************************************
|
||||
* 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_ANIMATION_H_
|
||||
#define SPINE_ANIMATION_H_
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct Timeline Timeline;
|
||||
struct Skeleton;
|
||||
|
||||
typedef struct {
|
||||
const char* const name;
|
||||
float duration;
|
||||
|
||||
int timelineCount;
|
||||
Timeline** timelines;
|
||||
} Animation;
|
||||
|
||||
Animation* Animation_create (const char* name, int timelineCount);
|
||||
void Animation_dispose (Animation* self);
|
||||
|
||||
void Animation_apply (const Animation* self, struct Skeleton* skeleton, float time, int/*bool*/loop);
|
||||
void Animation_mix (const Animation* self, struct Skeleton* skeleton, float time, int/*bool*/loop, float alpha);
|
||||
|
||||
/**/
|
||||
|
||||
struct Timeline {
|
||||
const void* const vtable;
|
||||
};
|
||||
|
||||
void Timeline_dispose (Timeline* self);
|
||||
void Timeline_apply (const Timeline* self, struct Skeleton* skeleton, float time, float alpha);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct {
|
||||
Timeline super;
|
||||
float* curves; /* dfx, dfy, ddfx, ddfy, dddfx, dddfy, ... */
|
||||
} CurveTimeline;
|
||||
|
||||
void CurveTimeline_setLinear (CurveTimeline* self, int frameIndex);
|
||||
void CurveTimeline_setStepped (CurveTimeline* self, int frameIndex);
|
||||
|
||||
/* Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next.
|
||||
* cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of
|
||||
* the difference between the keyframe's values. */
|
||||
void CurveTimeline_setCurve (CurveTimeline* self, int frameIndex, float cx1, float cy1, float cx2, float cy2);
|
||||
float CurveTimeline_getCurvePercent (const CurveTimeline* self, int frameIndex, float percent);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct BaseTimeline {
|
||||
CurveTimeline super;
|
||||
int const framesLength;
|
||||
float* const frames; /* time, angle, ... for rotate. time, x, y, ... for translate and scale. */
|
||||
int boneIndex;
|
||||
} RotateTimeline;
|
||||
|
||||
RotateTimeline* RotateTimeline_create (int frameCount);
|
||||
|
||||
void RotateTimeline_setFrame (RotateTimeline* self, int frameIndex, float time, float angle);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct BaseTimeline TranslateTimeline;
|
||||
|
||||
TranslateTimeline* TranslateTimeline_create (int frameCount);
|
||||
|
||||
void TranslateTimeline_setFrame (TranslateTimeline* self, int frameIndex, float time, float x, float y);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct BaseTimeline ScaleTimeline;
|
||||
|
||||
ScaleTimeline* ScaleTimeline_create (int frameCount);
|
||||
|
||||
void ScaleTimeline_setFrame (ScaleTimeline* self, int frameIndex, float time, float x, float y);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct {
|
||||
CurveTimeline super;
|
||||
int const framesLength;
|
||||
float* const frames; /* time, r, g, b, a, ... */
|
||||
int slotIndex;
|
||||
} ColorTimeline;
|
||||
|
||||
ColorTimeline* ColorTimeline_create (int frameCount);
|
||||
|
||||
void ColorTimeline_setFrame (ColorTimeline* self, int frameIndex, float time, float r, float g, float b, float a);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct {
|
||||
Timeline super;
|
||||
int const framesLength;
|
||||
float* const frames; /* time, ... */
|
||||
int slotIndex;
|
||||
const char** const attachmentNames;
|
||||
} AttachmentTimeline;
|
||||
|
||||
AttachmentTimeline* AttachmentTimeline_create (int frameCount);
|
||||
|
||||
/* @param attachmentName May be 0. */
|
||||
void AttachmentTimeline_setFrame (AttachmentTimeline* self, int frameIndex, float time, const char* attachmentName);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_ANIMATION_H_ */
|
|
@ -0,0 +1,102 @@
|
|||
/*******************************************************************************
|
||||
* 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/AnimationState.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct {
|
||||
AnimationState super;
|
||||
Animation *previous;
|
||||
float previousTime;
|
||||
int/*bool*/previousLoop;
|
||||
float mixTime;
|
||||
float mixDuration;
|
||||
} _Internal;
|
||||
|
||||
AnimationState* AnimationState_create (AnimationStateData* data) {
|
||||
AnimationState* self = SUPER(NEW(_Internal));
|
||||
CONST_CAST(AnimationStateData*, self->data) = data;
|
||||
return self;
|
||||
}
|
||||
|
||||
void AnimationState_dispose (AnimationState* self) {
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
void AnimationState_update (AnimationState* self, float delta) {
|
||||
self->time += delta;
|
||||
SUB_CAST(_Internal, self) ->previousTime += delta;
|
||||
SUB_CAST(_Internal, self) ->mixTime += delta;
|
||||
}
|
||||
|
||||
void AnimationState_apply (AnimationState* self, Skeleton* skeleton) {
|
||||
if (!self->animation) return;
|
||||
_Internal* internal = SUB_CAST(_Internal, self);
|
||||
if (internal->previous) {
|
||||
Animation_apply(internal->previous, skeleton, internal->previousTime, internal->previousLoop);
|
||||
float alpha = internal->mixTime / internal->mixDuration;
|
||||
if (alpha >= 1) {
|
||||
alpha = 1;
|
||||
internal->previous = 0;
|
||||
}
|
||||
Animation_mix(self->animation, skeleton, self->time, self->loop, alpha);
|
||||
} else
|
||||
Animation_apply(self->animation, skeleton, self->time, self->loop);
|
||||
}
|
||||
|
||||
void AnimationState_setAnimationByName (AnimationState* self, const char* animationName, int/**/loop) {
|
||||
Animation* animation = SkeletonData_findAnimation(self->data->skeletonData, animationName);
|
||||
AnimationState_setAnimation(self, animation, loop);
|
||||
}
|
||||
|
||||
void AnimationState_setAnimation (AnimationState* self, Animation* newAnimation, int/**/loop) {
|
||||
_Internal* internal = SUB_CAST(_Internal, self);
|
||||
internal->previous = 0;
|
||||
if (newAnimation && self->animation && self->data) {
|
||||
internal->mixDuration = AnimationStateData_getMix(self->data, self->animation, newAnimation);
|
||||
if (internal->mixDuration > 0) {
|
||||
internal->mixTime = 0;
|
||||
internal->previous = self->animation;
|
||||
internal->previousTime = self->time;
|
||||
internal->previousLoop = self->loop;
|
||||
}
|
||||
}
|
||||
CONST_CAST(Animation*, self->animation) = newAnimation;
|
||||
self->loop = loop;
|
||||
self->time = 0;
|
||||
}
|
||||
|
||||
void AnimationState_clearAnimation (AnimationState* self) {
|
||||
SUB_CAST(_Internal, self) ->previous = 0;
|
||||
CONST_CAST(Animation*, self->animation) = 0;
|
||||
}
|
||||
|
||||
int/*bool*/AnimationState_isComplete (AnimationState* self) {
|
||||
return !self->animation || self->time >= self->animation->duration;
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,58 @@
|
|||
/*******************************************************************************
|
||||
* 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_ANIMATIONSTATE_H_
|
||||
#define SPINE_ANIMATIONSTATE_H_
|
||||
|
||||
#include <spine/AnimationStateData.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct {
|
||||
AnimationStateData* const data;
|
||||
Animation* const animation;
|
||||
float time;
|
||||
int/*bool*/loop;
|
||||
} AnimationState;
|
||||
|
||||
/* @param data May be 0 for no mixing. */
|
||||
AnimationState* AnimationState_create (AnimationStateData* data);
|
||||
void AnimationState_dispose (AnimationState* self);
|
||||
|
||||
void AnimationState_update (AnimationState* self, float delta);
|
||||
|
||||
void AnimationState_apply (AnimationState* self, struct Skeleton* skeleton);
|
||||
|
||||
/* @param animationName May be 0. */
|
||||
void AnimationState_setAnimationByName (AnimationState* self, const char* animationName, int/**/loop);
|
||||
/* @param animation May be 0. */
|
||||
void AnimationState_setAnimation (AnimationState* self, Animation* animation, int/**/loop);
|
||||
void AnimationState_clearAnimation (AnimationState* self);
|
||||
|
||||
int/*bool*/AnimationState_isComplete (AnimationState* self);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_ANIMATIONSTATE_H_ */
|
|
@ -0,0 +1,144 @@
|
|||
/*******************************************************************************
|
||||
* 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/AnimationStateData.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct _ToEntry _ToEntry;
|
||||
struct _ToEntry {
|
||||
Animation* animation;
|
||||
float duration;
|
||||
_ToEntry* next;
|
||||
};
|
||||
|
||||
_ToEntry* _ToEntry_create (Animation* to, float duration) {
|
||||
_ToEntry* self = NEW(_ToEntry);
|
||||
self->animation = to;
|
||||
self->duration = duration;
|
||||
return self;
|
||||
}
|
||||
|
||||
void _ToEntry_dispose (_ToEntry* self) {
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct _FromEntry _FromEntry;
|
||||
struct _FromEntry {
|
||||
Animation* animation;
|
||||
_ToEntry* toEntries;
|
||||
_FromEntry* next;
|
||||
};
|
||||
|
||||
_FromEntry* _FromEntry_create (Animation* from) {
|
||||
_FromEntry* self = NEW(_FromEntry);
|
||||
self->animation = from;
|
||||
return self;
|
||||
}
|
||||
|
||||
void _FromEntry_dispose (_FromEntry* self) {
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
AnimationStateData* AnimationStateData_create (SkeletonData* skeletonData) {
|
||||
AnimationStateData* self = NEW(AnimationStateData);
|
||||
CONST_CAST(SkeletonData*, self->skeletonData) = skeletonData;
|
||||
return self;
|
||||
}
|
||||
|
||||
void AnimationStateData_dispose (AnimationStateData* self) {
|
||||
_FromEntry* fromEntry = (_FromEntry*)self->entries;
|
||||
while (fromEntry) {
|
||||
_ToEntry* toEntry = fromEntry->toEntries;
|
||||
while (toEntry) {
|
||||
_ToEntry* next = toEntry->next;
|
||||
_ToEntry_dispose(toEntry);
|
||||
toEntry = next;
|
||||
}
|
||||
_FromEntry* next = fromEntry->next;
|
||||
_FromEntry_dispose(fromEntry);
|
||||
fromEntry = next;
|
||||
}
|
||||
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
void AnimationStateData_setMixByName (AnimationStateData* self, const char* fromName, const char* toName, float duration) {
|
||||
Animation* from = SkeletonData_findAnimation(self->skeletonData, fromName);
|
||||
if (!from) return;
|
||||
Animation* to = SkeletonData_findAnimation(self->skeletonData, toName);
|
||||
if (!to) return;
|
||||
AnimationStateData_setMix(self, from, to, duration);
|
||||
}
|
||||
|
||||
void AnimationStateData_setMix (AnimationStateData* self, Animation* from, Animation* to, float duration) {
|
||||
/* Find existing FromEntry. */
|
||||
_FromEntry* fromEntry = (_FromEntry*)self->entries;
|
||||
while (fromEntry) {
|
||||
if (fromEntry->animation == from) {
|
||||
/* Find existing ToEntry. */
|
||||
_ToEntry* toEntry = fromEntry->toEntries;
|
||||
while (toEntry) {
|
||||
if (toEntry->animation == to) {
|
||||
toEntry->duration = duration;
|
||||
return;
|
||||
}
|
||||
toEntry = toEntry->next;
|
||||
}
|
||||
break; /* Add new ToEntry to the existing FromEntry. */
|
||||
}
|
||||
fromEntry = fromEntry->next;
|
||||
}
|
||||
if (!fromEntry) {
|
||||
fromEntry = _FromEntry_create(from);
|
||||
fromEntry->next = (_FromEntry*)self->entries;
|
||||
CONST_CAST(_FromEntry*, self->entries) = fromEntry;
|
||||
}
|
||||
_ToEntry* toEntry = _ToEntry_create(to, duration);
|
||||
toEntry->next = fromEntry->toEntries;
|
||||
fromEntry->toEntries = toEntry;
|
||||
}
|
||||
|
||||
float AnimationStateData_getMix (AnimationStateData* self, Animation* from, Animation* to) {
|
||||
_FromEntry* fromEntry = (_FromEntry*)self->entries;
|
||||
while (fromEntry) {
|
||||
if (fromEntry->animation == from) {
|
||||
_ToEntry* toEntry = fromEntry->toEntries;
|
||||
while (toEntry) {
|
||||
if (toEntry->animation == to) return toEntry->duration;
|
||||
toEntry = toEntry->next;
|
||||
}
|
||||
}
|
||||
fromEntry = fromEntry->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,49 @@
|
|||
/*******************************************************************************
|
||||
* 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_ANIMATIONSTATEDATA_H_
|
||||
#define SPINE_ANIMATIONSTATEDATA_H_
|
||||
|
||||
#include <spine/Animation.h>
|
||||
#include <spine/SkeletonData.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct {
|
||||
SkeletonData* const skeletonData;
|
||||
const void* const entries;
|
||||
} AnimationStateData;
|
||||
|
||||
AnimationStateData* AnimationStateData_create (SkeletonData* skeletonData);
|
||||
void AnimationStateData_dispose (AnimationStateData* self);
|
||||
|
||||
void AnimationStateData_setMixByName (AnimationStateData* self, const char* fromName, const char* toName, float duration);
|
||||
void AnimationStateData_setMix (AnimationStateData* self, Animation* from, Animation* to, float duration);
|
||||
/* Returns 0 if there is no mixing between the animations. */
|
||||
float AnimationStateData_getMix (AnimationStateData* self, Animation* from, Animation* to);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_ANIMATIONSTATEDATA_H_ */
|
|
@ -0,0 +1,327 @@
|
|||
/*******************************************************************************
|
||||
* 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/Atlas.h>
|
||||
#include <ctype.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
AtlasPage* AtlasPage_create (const char* name) {
|
||||
AtlasPage* self = NEW(AtlasPage);
|
||||
MALLOC_STR(self->name, name);
|
||||
return self;
|
||||
}
|
||||
|
||||
void AtlasPage_dispose (AtlasPage* self) {
|
||||
FREE(self->name);
|
||||
_AtlasPage_disposeTexture(self);
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
AtlasRegion* AtlasRegion_create () {
|
||||
return NEW(AtlasRegion) ;
|
||||
}
|
||||
|
||||
void AtlasRegion_dispose (AtlasRegion* self) {
|
||||
FREE(self->name);
|
||||
FREE(self->splits);
|
||||
FREE(self->pads);
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct {
|
||||
const char* begin;
|
||||
const char* end;
|
||||
} Str;
|
||||
|
||||
static void trim (Str* str) {
|
||||
while (isspace(*str->begin) && str->begin < str->end)
|
||||
(str->begin)++;
|
||||
if (str->begin == str->end) return;
|
||||
str->end--;
|
||||
while (isspace(*str->end) && str->end >= str->begin)
|
||||
str->end--;
|
||||
str->end++;
|
||||
}
|
||||
|
||||
/* Tokenize string without modification. Returns 0 on failure. */
|
||||
static int readLine (const char* begin, const char* end, Str* str) {
|
||||
static const char* nextStart;
|
||||
if (begin) {
|
||||
nextStart = begin;
|
||||
return 1;
|
||||
}
|
||||
if (nextStart == end) return 0;
|
||||
str->begin = nextStart;
|
||||
|
||||
/* Find next delimiter. */
|
||||
while (nextStart != end && *nextStart != '\n')
|
||||
nextStart++;
|
||||
|
||||
str->end = nextStart;
|
||||
trim(str);
|
||||
|
||||
if (nextStart != end) nextStart++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Moves str->begin past the first occurence of c. Returns 0 on failure. */
|
||||
static int beginPast (Str* str, char c) {
|
||||
const char* begin = str->begin;
|
||||
while (1) {
|
||||
char lastSkippedChar = *begin;
|
||||
if (begin == str->end) return 0;
|
||||
begin++;
|
||||
if (lastSkippedChar == c) break;
|
||||
}
|
||||
str->begin = begin;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Returns 0 on failure. */
|
||||
static int readValue (const char* end, Str* str) {
|
||||
readLine(0, end, str);
|
||||
if (!beginPast(str, ':')) return 0;
|
||||
trim(str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Returns the number of tuple values read (2, 4, or 0 for failure). */
|
||||
static int readTuple (const char* end, Str tuple[]) {
|
||||
Str str;
|
||||
readLine(0, end, &str);
|
||||
if (!beginPast(&str, ':')) return 0;
|
||||
int i = 0;
|
||||
for (i = 0; i < 3; ++i) {
|
||||
tuple[i].begin = str.begin;
|
||||
if (!beginPast(&str, ',')) {
|
||||
if (i == 0) return 0;
|
||||
break;
|
||||
}
|
||||
tuple[i].end = str.begin - 2;
|
||||
trim(&tuple[i]);
|
||||
}
|
||||
tuple[i].begin = str.begin;
|
||||
tuple[i].end = str.end;
|
||||
trim(&tuple[i]);
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
static char* mallocString (Str* str) {
|
||||
int length = str->end - str->begin;
|
||||
char* string = MALLOC(char, length + 1);
|
||||
memcpy(string, str->begin, length);
|
||||
string[length] = '\0';
|
||||
return string;
|
||||
}
|
||||
|
||||
static int indexOf (const char** array, int count, Str* str) {
|
||||
int length = str->end - str->begin;
|
||||
int i;
|
||||
for (i = count - 1; i >= 0; i--)
|
||||
if (strncmp(array[i], str->begin, length) == 0) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int equals (Str* str, const char* other) {
|
||||
return strncmp(other, str->begin, str->end - str->begin) == 0;
|
||||
}
|
||||
|
||||
static int toInt (Str* str) {
|
||||
return strtol(str->begin, (char**)&str->end, 10);
|
||||
}
|
||||
|
||||
static Atlas* abortAtlas (Atlas* self) {
|
||||
Atlas_dispose(self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char* formatNames[] = {"Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888", "RGBA8888"};
|
||||
static const char* textureFilterNames[] = {"Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest",
|
||||
"MipMapNearestLinear", "MipMapLinearLinear"};
|
||||
|
||||
Atlas* Atlas_readAtlas (const char* begin, int length, const char* dir) {
|
||||
const char* end = begin + length;
|
||||
int dirLength = strlen(dir);
|
||||
int needsSlash = dirLength > 0 && dir[dirLength - 1] != '/' && dir[dirLength - 1] != '\\';
|
||||
|
||||
Atlas* self = NEW(Atlas);
|
||||
|
||||
AtlasPage *page = 0;
|
||||
AtlasPage *lastPage = 0;
|
||||
AtlasRegion *lastRegion = 0;
|
||||
Str str;
|
||||
Str tuple[4];
|
||||
readLine(begin, 0, 0);
|
||||
while (readLine(0, end, &str)) {
|
||||
if (str.end - str.begin == 0) {
|
||||
page = 0;
|
||||
} else if (!page) {
|
||||
char* name = mallocString(&str);
|
||||
char* path = MALLOC(char, dirLength + needsSlash + strlen(name) + 1);
|
||||
memcpy(path, dir, dirLength);
|
||||
if (needsSlash) path[dirLength] = '/';
|
||||
strcpy(path + dirLength + needsSlash, name);
|
||||
|
||||
page = AtlasPage_create(name);
|
||||
FREE(name);
|
||||
if (lastPage)
|
||||
lastPage->next = page;
|
||||
else
|
||||
self->pages = page;
|
||||
lastPage = page;
|
||||
|
||||
if (!readValue(end, &str)) return abortAtlas(self);
|
||||
page->format = (AtlasFormat)indexOf(formatNames, 7, &str);
|
||||
|
||||
if (!readTuple(end, tuple)) return abortAtlas(self);
|
||||
page->minFilter = (AtlasFilter)indexOf(textureFilterNames, 7, tuple);
|
||||
page->magFilter = (AtlasFilter)indexOf(textureFilterNames, 7, tuple + 1);
|
||||
|
||||
if (!readValue(end, &str)) return abortAtlas(self);
|
||||
if (!equals(&str, "none")) {
|
||||
page->uWrap = *str.begin == 'x' ? ATLAS_REPEAT : (*str.begin == 'y' ? ATLAS_CLAMPTOEDGE : ATLAS_REPEAT);
|
||||
page->vWrap = *str.begin == 'x' ? ATLAS_CLAMPTOEDGE : (*str.begin == 'y' ? ATLAS_REPEAT : ATLAS_REPEAT);
|
||||
}
|
||||
|
||||
_AtlasPage_createTexture(page, path);
|
||||
FREE(path);
|
||||
} else {
|
||||
AtlasRegion *region = AtlasRegion_create();
|
||||
if (lastRegion)
|
||||
lastRegion->next = region;
|
||||
else
|
||||
self->regions = region;
|
||||
lastRegion = region;
|
||||
|
||||
region->page = page;
|
||||
region->name = mallocString(&str);
|
||||
|
||||
if (!readValue(end, &str)) return abortAtlas(self);
|
||||
region->rotate = equals(&str, "true");
|
||||
|
||||
if (readTuple(end, tuple) != 2) return abortAtlas(self);
|
||||
region->x = toInt(tuple);
|
||||
region->y = toInt(tuple + 1);
|
||||
|
||||
if (readTuple(end, tuple) != 2) return abortAtlas(self);
|
||||
region->width = toInt(tuple);
|
||||
region->height = toInt(tuple + 1);
|
||||
|
||||
region->u = region->x / (float)page->width;
|
||||
region->v = region->y / (float)page->height;
|
||||
region->u2 = (region->x + region->width) / (float)page->width;
|
||||
region->v2 = (region->y + region->height) / (float)page->height;
|
||||
|
||||
int count;
|
||||
if (!(count = readTuple(end, tuple))) return abortAtlas(self);
|
||||
if (count == 4) { /* split is optional */
|
||||
region->splits = MALLOC(int, 4);
|
||||
region->splits[0] = toInt(tuple);
|
||||
region->splits[1] = toInt(tuple + 1);
|
||||
region->splits[2] = toInt(tuple + 2);
|
||||
region->splits[3] = toInt(tuple + 3);
|
||||
|
||||
if (!(count = readTuple(end, tuple))) return abortAtlas(self);
|
||||
if (count == 4) { /* pad is optional, but only present with splits */
|
||||
region->pads = MALLOC(int, 4);
|
||||
region->pads[0] = toInt(tuple);
|
||||
region->pads[1] = toInt(tuple + 1);
|
||||
region->pads[2] = toInt(tuple + 2);
|
||||
region->pads[3] = toInt(tuple + 3);
|
||||
|
||||
if (!readTuple(end, tuple)) return abortAtlas(self);
|
||||
}
|
||||
}
|
||||
|
||||
region->originalWidth = toInt(tuple);
|
||||
region->originalHeight = toInt(tuple + 1);
|
||||
|
||||
readTuple(end, tuple);
|
||||
region->offsetX = (float)toInt(tuple);
|
||||
region->offsetY = (float)toInt(tuple + 1);
|
||||
|
||||
if (!readValue(end, &str)) return abortAtlas(self);
|
||||
region->index = toInt(&str);
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
Atlas* Atlas_readAtlasFile (const char* path) {
|
||||
Atlas* atlas = 0;
|
||||
|
||||
/* Get directory from atlas path. */
|
||||
const char* lastForwardSlash = strrchr(path, '/');
|
||||
const char* lastBackwardSlash = strrchr(path, '\\');
|
||||
const char* lastSlash = lastForwardSlash > lastBackwardSlash ? lastForwardSlash : lastBackwardSlash;
|
||||
if (lastSlash == path) lastSlash++; /* Never drop starting slash. */
|
||||
int dirLength = lastSlash ? lastSlash - path : 0;
|
||||
char* dir = MALLOC(char, dirLength + 1);
|
||||
memcpy(dir, path, dirLength);
|
||||
dir[dirLength] = '\0';
|
||||
|
||||
int length;
|
||||
const char* data = _Util_readFile(path, &length);
|
||||
if (data) atlas = Atlas_readAtlas(data, length, dir);
|
||||
|
||||
FREE(data);
|
||||
FREE(dir);
|
||||
return atlas;
|
||||
}
|
||||
|
||||
void Atlas_dispose (Atlas* self) {
|
||||
AtlasPage* page = self->pages;
|
||||
while (page) {
|
||||
AtlasPage* nextPage = page->next;
|
||||
AtlasPage_dispose(page);
|
||||
page = nextPage;
|
||||
}
|
||||
|
||||
AtlasRegion* region = self->regions;
|
||||
while (region) {
|
||||
AtlasRegion* nextRegion = region->next;
|
||||
AtlasRegion_dispose(region);
|
||||
region = nextRegion;
|
||||
}
|
||||
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,106 @@
|
|||
/*******************************************************************************
|
||||
* 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_
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef enum {
|
||||
ATLAS_ALPHA, ATLAS_INTENSITY, ATLAS_LUMINANCE_ALPHA, ATLAS_RGB565, ATLAS_RGBA4444, ATLAS_RGB888, ATLAS_RGBA8888
|
||||
} AtlasFormat;
|
||||
|
||||
typedef enum {
|
||||
ATLAS_NEAREST,
|
||||
ATLAS_LINEAR,
|
||||
ATLAS_MIPMAP,
|
||||
ATLAS_MIPMAP_NEAREST_NEAREST,
|
||||
ATLAS_MIPMAP_LINEAR_NEAREST,
|
||||
ATLAS_MIPMAP_NEAREST_LINEAR,
|
||||
ATLAS_MIPMAP_LINEAR_LINEAR
|
||||
} AtlasFilter;
|
||||
|
||||
typedef enum {
|
||||
ATLAS_MIRROREDREPEAT, ATLAS_CLAMPTOEDGE, ATLAS_REPEAT
|
||||
} AtlasWrap;
|
||||
|
||||
typedef struct AtlasPage AtlasPage;
|
||||
struct AtlasPage {
|
||||
const char* name;
|
||||
AtlasFormat format;
|
||||
AtlasFilter minFilter, magFilter;
|
||||
AtlasWrap uWrap, vWrap;
|
||||
|
||||
void* texture;
|
||||
int width, height;
|
||||
|
||||
AtlasPage* next;
|
||||
};
|
||||
|
||||
AtlasPage* AtlasPage_create (const char* name);
|
||||
void AtlasPage_dispose (AtlasPage* self);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct AtlasRegion AtlasRegion;
|
||||
struct AtlasRegion {
|
||||
const char* name;
|
||||
int x, y, width, height;
|
||||
float u, v, u2, v2;
|
||||
float offsetX, offsetY;
|
||||
int originalWidth, originalHeight;
|
||||
int index;
|
||||
int/*bool*/rotate;
|
||||
int/*bool*/flip;
|
||||
int* splits;
|
||||
int* pads;
|
||||
|
||||
AtlasPage* page;
|
||||
|
||||
AtlasRegion* next;
|
||||
};
|
||||
|
||||
AtlasRegion* AtlasRegion_create ();
|
||||
void AtlasRegion_dispose (AtlasRegion* self);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct {
|
||||
AtlasPage* pages;
|
||||
AtlasRegion* regions;
|
||||
} Atlas;
|
||||
|
||||
/* Image files referenced in the atlas file will be prefixed with dir. */
|
||||
Atlas* Atlas_readAtlas (const char* data, int length, const char* dir);
|
||||
/* Image files referenced in the atlas file will be prefixed with the directory containing the atlas file. */
|
||||
Atlas* Atlas_readAtlasFile (const char* path);
|
||||
void Atlas_dispose (Atlas* atlas);
|
||||
|
||||
/* Returns 0 if the region was not found. */
|
||||
AtlasRegion* Atlas_findRegion (const Atlas* self, const char* name);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_ATLAS_H_ */
|
|
@ -0,0 +1,57 @@
|
|||
/*******************************************************************************
|
||||
* 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/AtlasAttachmentLoader.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
Attachment* _AtlasAttachmentLoader_newAttachment (AttachmentLoader* loader, Skin* skin, AttachmentType type, const char* name) {
|
||||
AtlasAttachmentLoader* self = SUB_CAST(AtlasAttachmentLoader, loader);
|
||||
switch (type) {
|
||||
case ATTACHMENT_REGION: {
|
||||
AtlasRegion* region = Atlas_findRegion(self->atlas, name);
|
||||
if (!region) {
|
||||
_AttachmentLoader_setError(loader, "Region not found: ", name);
|
||||
return 0;
|
||||
}
|
||||
RegionAttachment* attachment = RegionAttachment_create(name);
|
||||
attachment->region = region;
|
||||
return SUPER(attachment);
|
||||
}
|
||||
default:
|
||||
_AttachmentLoader_setUnknownTypeError(loader, type);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
AtlasAttachmentLoader* AtlasAttachmentLoader_create (Atlas* atlas) {
|
||||
AtlasAttachmentLoader* self = NEW(AtlasAttachmentLoader);
|
||||
_AttachmentLoader_init(SUPER(self), _AttachmentLoader_deinit, _AtlasAttachmentLoader_newAttachment);
|
||||
self->atlas = atlas;
|
||||
return self;
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,43 @@
|
|||
/*******************************************************************************
|
||||
* 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/AttachmentLoader.h>
|
||||
#include <spine/Atlas.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct {
|
||||
AttachmentLoader super;
|
||||
Atlas* atlas;
|
||||
} AtlasAttachmentLoader;
|
||||
|
||||
AtlasAttachmentLoader* AtlasAttachmentLoader_create (Atlas* atlas);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_ATLASATTACHMENTLOADER_H_ */
|
|
@ -0,0 +1,55 @@
|
|||
/*******************************************************************************
|
||||
* 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/Attachment.h>
|
||||
#include <spine/extension.h>
|
||||
#include <spine/Slot.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct _AttachmentVtable {
|
||||
void (*dispose) (Attachment* self);
|
||||
} _AttachmentVtable;
|
||||
|
||||
void _Attachment_init (Attachment* self, const char* name, AttachmentType type, //
|
||||
void (*dispose) (Attachment* self)) {
|
||||
|
||||
CONST_CAST(_AttachmentVtable*, self->vtable) = NEW(_AttachmentVtable);
|
||||
VTABLE(Attachment, self) ->dispose = dispose;
|
||||
|
||||
MALLOC_STR(self->name, name);
|
||||
self->type = type;
|
||||
}
|
||||
|
||||
void _Attachment_deinit (Attachment* self) {
|
||||
FREE(self->vtable);
|
||||
FREE(self->name);
|
||||
}
|
||||
|
||||
void Attachment_dispose (Attachment* self) {
|
||||
VTABLE(Attachment, self) ->dispose(self);
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,49 @@
|
|||
/*******************************************************************************
|
||||
* 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_ATTACHMENT_H_
|
||||
#define SPINE_ATTACHMENT_H_
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
struct Slot;
|
||||
|
||||
typedef enum {
|
||||
ATTACHMENT_REGION, ATTACHMENT_REGION_SEQUENCE
|
||||
} AttachmentType;
|
||||
|
||||
typedef struct Attachment Attachment;
|
||||
struct Attachment {
|
||||
const char* const name;
|
||||
AttachmentType type;
|
||||
|
||||
const void* const vtable;
|
||||
};
|
||||
|
||||
void Attachment_dispose (Attachment* self);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_ATTACHMENT_H_ */
|
|
@ -0,0 +1,76 @@
|
|||
/*******************************************************************************
|
||||
* 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/AttachmentLoader.h>
|
||||
#include <stdio.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct _AttachmentLoaderVtable {
|
||||
Attachment* (*newAttachment) (AttachmentLoader* self, Skin* skin, AttachmentType type, const char* name);
|
||||
void (*dispose) (AttachmentLoader* self);
|
||||
} _AttachmentLoaderVtable;
|
||||
|
||||
void _AttachmentLoader_init (AttachmentLoader* self, //
|
||||
void (*dispose) (AttachmentLoader* self), //
|
||||
Attachment* (*newAttachment) (AttachmentLoader* self, Skin* skin, AttachmentType type, const char* name)) {
|
||||
CONST_CAST(_AttachmentLoaderVtable*, self->vtable) = NEW(_AttachmentLoaderVtable);
|
||||
VTABLE(AttachmentLoader, self) ->dispose = dispose;
|
||||
VTABLE(AttachmentLoader, self) ->newAttachment = newAttachment;
|
||||
}
|
||||
|
||||
void _AttachmentLoader_deinit (AttachmentLoader* self) {
|
||||
FREE(self->vtable);
|
||||
FREE(self->error1);
|
||||
FREE(self->error2);
|
||||
}
|
||||
|
||||
void AttachmentLoader_dispose (AttachmentLoader* self) {
|
||||
VTABLE(AttachmentLoader, self) ->dispose(self);
|
||||
}
|
||||
|
||||
Attachment* AttachmentLoader_newAttachment (AttachmentLoader* self, Skin* skin, AttachmentType type, const char* name) {
|
||||
FREE(self->error1);
|
||||
FREE(self->error2);
|
||||
self->error1 = 0;
|
||||
self->error2 = 0;
|
||||
return VTABLE(AttachmentLoader, self) ->newAttachment(self, skin, type, name);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void _AttachmentLoader_setUnknownTypeError (AttachmentLoader* self, AttachmentType type) {
|
||||
char buffer[16];
|
||||
sprintf(buffer, "%d", type);
|
||||
_AttachmentLoader_setError(self, "Unknown attachment type: ", buffer);
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,49 @@
|
|||
/*******************************************************************************
|
||||
* 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_ATTACHMENTLOADER_H_
|
||||
#define SPINE_ATTACHMENTLOADER_H_
|
||||
|
||||
#include <spine/Attachment.h>
|
||||
#include <spine/Skin.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct AttachmentLoader AttachmentLoader;
|
||||
struct AttachmentLoader {
|
||||
const char* error1;
|
||||
const char* error2;
|
||||
|
||||
const void* const vtable;
|
||||
};
|
||||
|
||||
void AttachmentLoader_dispose (AttachmentLoader* self);
|
||||
|
||||
/* Returns 0 to not load an attachment. If 0 is returned and AttachmentLoader.error1 is set, an error occurred. */
|
||||
Attachment* AttachmentLoader_newAttachment (AttachmentLoader* self, Skin* skin, AttachmentType type, const char* name);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_ATTACHMENTLOADER_H_ */
|
|
@ -0,0 +1,93 @@
|
|||
/*******************************************************************************
|
||||
* 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/Bone.h>
|
||||
#include <math.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
static int yDown;
|
||||
|
||||
void Bone_setYDown (int value) {
|
||||
yDown = value;
|
||||
}
|
||||
|
||||
Bone* Bone_create (BoneData* data, Bone* parent) {
|
||||
Bone* self = NEW(Bone);
|
||||
CONST_CAST(BoneData*, self->data) = data;
|
||||
CONST_CAST(Bone*, self->parent) = parent;
|
||||
Bone_setToBindPose(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
void Bone_dispose (Bone* self) {
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
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* self, int flipX, int flipY) {
|
||||
if (self->parent) {
|
||||
CONST_CAST(float, self->worldX) = self->x * self->parent->m00 + self->y * self->parent->m01 + self->parent->worldX;
|
||||
CONST_CAST(float, self->worldY) = self->x * self->parent->m10 + self->y * self->parent->m11 + self->parent->worldY;
|
||||
CONST_CAST(float, self->worldScaleX) = self->parent->worldScaleX * self->scaleX;
|
||||
CONST_CAST(float, self->worldScaleY) = self->parent->worldScaleY * self->scaleY;
|
||||
CONST_CAST(float, self->worldRotation) = self->parent->worldRotation + self->rotation;
|
||||
} else {
|
||||
CONST_CAST(float, self->worldX) = self->x;
|
||||
CONST_CAST(float, self->worldY) = self->y;
|
||||
CONST_CAST(float, self->worldScaleX) = self->scaleX;
|
||||
CONST_CAST(float, self->worldScaleY) = self->scaleY;
|
||||
CONST_CAST(float, self->worldRotation) = self->rotation;
|
||||
}
|
||||
float radians = (float)(self->worldRotation * 3.1415926535897932385 / 180);
|
||||
float cosine = cosf(radians);
|
||||
float sine = sinf(radians);
|
||||
CONST_CAST(float, self->m00) = cosine * self->worldScaleX;
|
||||
CONST_CAST(float, self->m10) = sine * self->worldScaleX;
|
||||
CONST_CAST(float, self->m01) = -sine * self->worldScaleY;
|
||||
CONST_CAST(float, self->m11) = cosine * self->worldScaleY;
|
||||
if (flipX) {
|
||||
CONST_CAST(float, self->m00) = -self->m00;
|
||||
CONST_CAST(float, self->m01) = -self->m01;
|
||||
}
|
||||
if (flipY) {
|
||||
CONST_CAST(float, self->m10) = -self->m10;
|
||||
CONST_CAST(float, self->m11) = -self->m11;
|
||||
}
|
||||
if (yDown) {
|
||||
CONST_CAST(float, self->m10) = -self->m10;
|
||||
CONST_CAST(float, self->m11) = -self->m11;
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,59 @@
|
|||
/*******************************************************************************
|
||||
* 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_BONE_H_
|
||||
#define SPINE_BONE_H_
|
||||
|
||||
#include <spine/BoneData.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct Bone Bone;
|
||||
struct Bone {
|
||||
BoneData* const data;
|
||||
Bone* const parent;
|
||||
float x, y;
|
||||
float rotation;
|
||||
float scaleX, scaleY;
|
||||
|
||||
float const m00, m01, worldX; /* a b x */
|
||||
float const m10, m11, worldY; /* c d y */
|
||||
float const worldRotation;
|
||||
float const worldScaleX, worldScaleY;
|
||||
};
|
||||
|
||||
void Bone_setYDown (int/*bool*/yDown);
|
||||
|
||||
/* @param parent May be 0. */
|
||||
Bone* Bone_create (BoneData* data, Bone* parent);
|
||||
void Bone_dispose (Bone* self);
|
||||
|
||||
void Bone_setToBindPose (Bone* self);
|
||||
|
||||
void Bone_updateWorldTransform (Bone* self, int/*bool*/flipX, int/*bool*/flipY);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_BONE_H_ */
|
|
@ -0,0 +1,45 @@
|
|||
/*******************************************************************************
|
||||
* 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/BoneData.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
BoneData* BoneData_create (const char* name, BoneData* parent) {
|
||||
BoneData* self = NEW(BoneData);
|
||||
MALLOC_STR(self->name, name);
|
||||
CONST_CAST(BoneData*, self->parent) = parent;
|
||||
self->scaleX = 1;
|
||||
self->scaleY = 1;
|
||||
return self;
|
||||
}
|
||||
|
||||
void BoneData_dispose (BoneData* self) {
|
||||
FREE(self->name);
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,46 @@
|
|||
/*******************************************************************************
|
||||
* 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_BONEDATA_H_
|
||||
#define SPINE_BONEDATA_H_
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct BoneData BoneData;
|
||||
struct BoneData {
|
||||
const char* const name;
|
||||
BoneData* const parent;
|
||||
float length;
|
||||
float x, y;
|
||||
float rotation;
|
||||
float scaleX, scaleY;
|
||||
};
|
||||
|
||||
BoneData* BoneData_create (const char* name, BoneData* parent);
|
||||
void BoneData_dispose (BoneData* self);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_BONEDATA_H_ */
|
|
@ -0,0 +1,375 @@
|
|||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, dispose 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.
|
||||
*/
|
||||
|
||||
/* Json */
|
||||
/* JSON parser in C. */
|
||||
|
||||
#include "Json.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
static const char* ep;
|
||||
|
||||
const char* Json_getError (void) {
|
||||
return ep;
|
||||
}
|
||||
|
||||
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)
|
||||
if (*s1 == 0) return 0;
|
||||
return tolower(*(const unsigned char*)s1) - tolower(*(const unsigned char*)s2);
|
||||
}
|
||||
|
||||
/* Internal constructor. */
|
||||
static Json *Json_new (void) {
|
||||
return (Json*)CALLOC(Json, 1);
|
||||
}
|
||||
|
||||
/* Delete a Json structure. */
|
||||
void Json_dispose (Json *c) {
|
||||
Json *next;
|
||||
while (c) {
|
||||
next = c->next;
|
||||
if (c->child) Json_dispose(c->child);
|
||||
if (c->valuestring) FREE(c->valuestring);
|
||||
if (c->name) FREE(c->name);
|
||||
FREE(c);
|
||||
c = next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the input text to generate a number, and populate the result into item. */
|
||||
static const char* parse_number (Json *item, const char* num) {
|
||||
float n = 0, sign = 1, scale = 0;
|
||||
int subscale = 0, signsubscale = 1;
|
||||
|
||||
/* Could use sscanf for this? */
|
||||
if (*num == '-') sign = -1, num++; /* Has sign? */
|
||||
if (*num == '0') num++; /* is zero */
|
||||
if (*num >= '1' && *num <= '9') do
|
||||
n = (n * 10.0f) + (*num++ - '0');
|
||||
while (*num >= '0' && *num <= '9'); /* Number? */
|
||||
if (*num == '.' && num[1] >= '0' && num[1] <= '9') {
|
||||
num++;
|
||||
do
|
||||
n = (n * 10.0f) + (*num++ - '0'), scale--;
|
||||
while (*num >= '0' && *num <= '9');
|
||||
} /* Fractional part? */
|
||||
if (*num == 'e' || *num == 'E') /* Exponent? */
|
||||
{
|
||||
num++;
|
||||
if (*num == '+')
|
||||
num++;
|
||||
else if (*num == '-') signsubscale = -1, num++; /* With sign? */
|
||||
while (*num >= '0' && *num <= '9')
|
||||
subscale = (subscale * 10) + (*num++ - '0'); /* Number? */
|
||||
}
|
||||
|
||||
n = sign * n * pow(10.0f, (scale + subscale * signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
|
||||
|
||||
item->valuefloat = n;
|
||||
item->valueint = (int)n;
|
||||
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 (Json *item, const char* str) {
|
||||
const char* ptr = str + 1;
|
||||
char* ptr2;
|
||||
char* out;
|
||||
int len = 0;
|
||||
unsigned uc, uc2;
|
||||
if (*str != '\"') {
|
||||
ep = str;
|
||||
return 0;
|
||||
} /* not a string! */
|
||||
|
||||
while (*ptr != '\"' && *ptr && ++len)
|
||||
if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
|
||||
|
||||
out = (char*)malloc(len + 1); /* This is how long we need for the string, roughly. */
|
||||
if (!out) return 0;
|
||||
|
||||
ptr = str + 1;
|
||||
ptr2 = out;
|
||||
while (*ptr != '\"' && *ptr) {
|
||||
if (*ptr != '\\')
|
||||
*ptr2++ = *ptr++;
|
||||
else {
|
||||
ptr++;
|
||||
switch (*ptr) {
|
||||
case 'b':
|
||||
*ptr2++ = '\b';
|
||||
break;
|
||||
case 'f':
|
||||
*ptr2++ = '\f';
|
||||
break;
|
||||
case 'n':
|
||||
*ptr2++ = '\n';
|
||||
break;
|
||||
case 'r':
|
||||
*ptr2++ = '\r';
|
||||
break;
|
||||
case 't':
|
||||
*ptr2++ = '\t';
|
||||
break;
|
||||
case 'u': /* transcode utf16 to utf8. */
|
||||
sscanf(ptr + 1, "%4x", &uc);
|
||||
ptr += 4; /* get the unicode char. */
|
||||
|
||||
if ((uc >= 0xDC00 && uc <= 0xDFFF) || uc == 0) break; /* check for invalid. */
|
||||
|
||||
if (uc >= 0xD800 && uc <= 0xDBFF) /* UTF16 surrogate pairs. */
|
||||
{
|
||||
if (ptr[1] != '\\' || ptr[2] != 'u') break; /* missing second-half of surrogate. */
|
||||
sscanf(ptr + 3, "%4x", &uc2);
|
||||
ptr += 6;
|
||||
if (uc2 < 0xDC00 || uc2 > 0xDFFF) break; /* invalid second-half of surrogate. */
|
||||
uc = 0x10000 + (((uc & 0x3FF) << 10) | (uc2 & 0x3FF));
|
||||
}
|
||||
|
||||
len = 4;
|
||||
if (uc < 0x80)
|
||||
len = 1;
|
||||
else if (uc < 0x800)
|
||||
len = 2;
|
||||
else if (uc < 0x10000) len = 3;
|
||||
ptr2 += len;
|
||||
|
||||
switch (len) {
|
||||
case 4:
|
||||
*--ptr2 = ((uc | 0x80) & 0xBF);
|
||||
uc >>= 6;
|
||||
case 3:
|
||||
*--ptr2 = ((uc | 0x80) & 0xBF);
|
||||
uc >>= 6;
|
||||
case 2:
|
||||
*--ptr2 = ((uc | 0x80) & 0xBF);
|
||||
uc >>= 6;
|
||||
case 1:
|
||||
*--ptr2 = (uc | firstByteMark[len]);
|
||||
}
|
||||
ptr2 += len;
|
||||
break;
|
||||
default:
|
||||
*ptr2++ = *ptr;
|
||||
break;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
*ptr2 = 0;
|
||||
if (*ptr == '\"') ptr++;
|
||||
item->valuestring = out;
|
||||
item->type = Json_String;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Predeclare these prototypes. */
|
||||
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) {
|
||||
while (in && *in && (unsigned char)*in <= 32)
|
||||
in++;
|
||||
return in;
|
||||
}
|
||||
|
||||
/* Parse an object - create a new root, and populate. */
|
||||
Json *Json_create (const char* value) {
|
||||
const char* end = 0;
|
||||
Json *c = Json_new();
|
||||
ep = 0;
|
||||
if (!c) return 0; /* memory fail */
|
||||
|
||||
end = parse_value(c, skip(value));
|
||||
if (!end) {
|
||||
Json_dispose(c);
|
||||
return 0;
|
||||
} /* parse failure. ep is set. */
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Parser core - when encountering text, process appropriately. */
|
||||
static const char* parse_value (Json *item, const char* value) {
|
||||
if (!value) return 0; /* Fail on null. */
|
||||
if (!strncmp(value, "null", 4)) {
|
||||
item->type = Json_NULL;
|
||||
return value + 4;
|
||||
}
|
||||
if (!strncmp(value, "false", 5)) {
|
||||
item->type = Json_False;
|
||||
return value + 5;
|
||||
}
|
||||
if (!strncmp(value, "true", 4)) {
|
||||
item->type = Json_True;
|
||||
item->valueint = 1;
|
||||
return value + 4;
|
||||
}
|
||||
if (*value == '\"') {
|
||||
return parse_string(item, value);
|
||||
}
|
||||
if (*value == '-' || (*value >= '0' && *value <= '9')) {
|
||||
return parse_number(item, value);
|
||||
}
|
||||
if (*value == '[') {
|
||||
return parse_array(item, value);
|
||||
}
|
||||
if (*value == '{') {
|
||||
return parse_object(item, value);
|
||||
}
|
||||
|
||||
ep = value;
|
||||
return 0; /* failure. */
|
||||
}
|
||||
|
||||
/* Build an array from input text. */
|
||||
static const char* parse_array (Json *item, const char* value) {
|
||||
Json *child;
|
||||
if (*value != '[') {
|
||||
ep = value;
|
||||
return 0;
|
||||
} /* not an array! */
|
||||
|
||||
item->type = Json_Array;
|
||||
value = skip(value + 1);
|
||||
if (*value == ']') return value + 1; /* empty array. */
|
||||
|
||||
item->child = child = Json_new();
|
||||
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 == ',') {
|
||||
Json *new_item;
|
||||
if (!(new_item = Json_new())) return 0; /* memory fail */
|
||||
child->next = new_item;
|
||||
new_item->prev = child;
|
||||
child = new_item;
|
||||
value = skip(parse_value(child, skip(value + 1)));
|
||||
if (!value) return 0; /* memory fail */
|
||||
}
|
||||
|
||||
if (*value == ']') return value + 1; /* end of array */
|
||||
ep = value;
|
||||
return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Build an object from the text. */
|
||||
static const char* parse_object (Json *item, const char* value) {
|
||||
Json *child;
|
||||
if (*value != '{') {
|
||||
ep = value;
|
||||
return 0;
|
||||
} /* not an object! */
|
||||
|
||||
item->type = Json_Object;
|
||||
value = skip(value + 1);
|
||||
if (*value == '}') return value + 1; /* empty array. */
|
||||
|
||||
item->child = child = Json_new();
|
||||
if (!item->child) return 0;
|
||||
value = skip(parse_string(child, skip(value)));
|
||||
if (!value) return 0;
|
||||
child->name = child->valuestring;
|
||||
child->valuestring = 0;
|
||||
if (*value != ':') {
|
||||
ep = value;
|
||||
return 0;
|
||||
} /* fail! */
|
||||
value = skip(parse_value(child, skip(value + 1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
|
||||
while (*value == ',') {
|
||||
Json *new_item;
|
||||
if (!(new_item = Json_new())) return 0; /* memory fail */
|
||||
child->next = new_item;
|
||||
new_item->prev = child;
|
||||
child = new_item;
|
||||
value = skip(parse_string(child, skip(value + 1)));
|
||||
if (!value) return 0;
|
||||
child->name = child->valuestring;
|
||||
child->valuestring = 0;
|
||||
if (*value != ':') {
|
||||
ep = value;
|
||||
return 0;
|
||||
} /* fail! */
|
||||
value = skip(parse_value(child, skip(value + 1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
}
|
||||
|
||||
if (*value == '}') return value + 1; /* end of array */
|
||||
ep = value;
|
||||
return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Get Array size/item / object item. */
|
||||
int Json_getSize (Json *array) {
|
||||
Json *c = array->child;
|
||||
int i = 0;
|
||||
while (c)
|
||||
i++, c = c->next;
|
||||
return i;
|
||||
}
|
||||
|
||||
Json *Json_getItemAt (Json *array, int item) {
|
||||
Json *c = array->child;
|
||||
while (c && item > 0)
|
||||
item--, c = c->next;
|
||||
return c;
|
||||
}
|
||||
|
||||
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* Json_getString (Json* object, const char* name, const char* defaultValue) {
|
||||
object = Json_getItem(object, name);
|
||||
if (object) return object->valuestring;
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
float Json_getFloat (Json* value, const char* name, float defaultValue) {
|
||||
value = Json_getItem(value, name);
|
||||
return value ? value->valuefloat : defaultValue;
|
||||
}
|
||||
|
||||
int Json_getInt (Json* value, const char* name, int defaultValue) {
|
||||
value = Json_getItem(value, name);
|
||||
return value ? (int)value->valuefloat : defaultValue;
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, dispose 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_
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
/* 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. */
|
||||
Json* Json_create (const char* value);
|
||||
|
||||
/* Delete a Json entity and all subentities. */
|
||||
void Json_dispose (Json* json);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
int Json_getSize (Json* json);
|
||||
|
||||
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
|
||||
Json* Json_getItemAt (Json* json, int item);
|
||||
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
Json* Json_getItem (Json* json, const char* string);
|
||||
const char* Json_getString (Json* json, const char* name, const char* defaultValue);
|
||||
float Json_getFloat (Json* json, const char* name, float defaultValue);
|
||||
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. */
|
||||
const char* Json_getError (void);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_JSON_H_ */
|
|
@ -0,0 +1,94 @@
|
|||
/*******************************************************************************
|
||||
* 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/RegionAttachment.h>
|
||||
#include <math.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
RegionAttachment* RegionAttachment_create (const char* name) {
|
||||
RegionAttachment* self = NEW(RegionAttachment);
|
||||
self->scaleX = 1;
|
||||
self->scaleY = 1;
|
||||
_Attachment_init(SUPER(self), name, ATTACHMENT_REGION, _Attachment_deinit);
|
||||
return self;
|
||||
}
|
||||
|
||||
void RegionAttachment_updateOffset (RegionAttachment* self) {
|
||||
float localX2 = self->width / 2;
|
||||
float localY2 = self->height / 2;
|
||||
float localX = -localX2;
|
||||
float localY = -localY2;
|
||||
if (self->region->rotate) {
|
||||
localX += self->region->offsetX / self->region->originalWidth * self->height;
|
||||
localY += self->region->offsetY / self->region->originalHeight * self->width;
|
||||
localX2 -= (self->region->originalWidth - self->region->offsetX - self->region->height) / self->region->originalWidth * self->width;
|
||||
localY2 -= (self->region->originalHeight - self->region->offsetY - self->region->width) / self->region->originalHeight * self->height;
|
||||
} else {
|
||||
localX += self->region->offsetX / self->region->originalWidth * self->width;
|
||||
localY += self->region->offsetY / self->region->originalHeight * self->height;
|
||||
localX2 -= (self->region->originalWidth - self->region->offsetX - self->region->width) / self->region->originalWidth * self->width;
|
||||
localY2 -= (self->region->originalHeight - self->region->offsetY - self->region->height) / self->region->originalHeight * self->height;
|
||||
}
|
||||
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 + self->y;
|
||||
float localYSin = localY * sine;
|
||||
float localX2Cos = localX2 * cosine + self->x;
|
||||
float localX2Sin = localX2 * sine;
|
||||
float localY2Cos = localY2 * cosine + self->y;
|
||||
float localY2Sin = localY2 * sine;
|
||||
self->offset[VERTEX_X1] = localXCos - localYSin;
|
||||
self->offset[VERTEX_Y1] = localYCos + localXSin;
|
||||
self->offset[VERTEX_X2] = localXCos - localY2Sin;
|
||||
self->offset[VERTEX_Y2] = localY2Cos + localXSin;
|
||||
self->offset[VERTEX_X3] = localX2Cos - localY2Sin;
|
||||
self->offset[VERTEX_Y3] = localY2Cos + localX2Sin;
|
||||
self->offset[VERTEX_X4] = localX2Cos - localYSin;
|
||||
self->offset[VERTEX_Y4] = localYCos + localX2Sin;
|
||||
}
|
||||
|
||||
void RegionAttachment_updateVertices (RegionAttachment* self, Slot* slot) {
|
||||
float* offset = self->offset;
|
||||
Bone* bone = slot->bone;
|
||||
self->vertices[VERTEX_X1] = offset[VERTEX_X1] * bone->m00 + offset[VERTEX_Y1] * bone->m01 + bone->worldX;
|
||||
self->vertices[VERTEX_Y1] = offset[VERTEX_X1] * bone->m10 + offset[VERTEX_Y1] * bone->m11 + bone->worldY;
|
||||
self->vertices[VERTEX_X2] = offset[VERTEX_X2] * bone->m00 + offset[VERTEX_Y2] * bone->m01 + bone->worldX;
|
||||
self->vertices[VERTEX_Y2] = offset[VERTEX_X2] * bone->m10 + offset[VERTEX_Y2] * bone->m11 + bone->worldY;
|
||||
self->vertices[VERTEX_X3] = offset[VERTEX_X3] * bone->m00 + offset[VERTEX_Y3] * bone->m01 + bone->worldX;
|
||||
self->vertices[VERTEX_Y3] = offset[VERTEX_X3] * bone->m10 + offset[VERTEX_Y3] * bone->m11 + bone->worldY;
|
||||
self->vertices[VERTEX_X4] = offset[VERTEX_X4] * bone->m00 + offset[VERTEX_Y4] * bone->m01 + bone->worldX;
|
||||
self->vertices[VERTEX_Y4] = offset[VERTEX_X4] * bone->m10 + offset[VERTEX_Y4] * bone->m11 + bone->worldY;
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,56 @@
|
|||
/*******************************************************************************
|
||||
* 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/Attachment.h>
|
||||
#include <spine/Atlas.h>
|
||||
#include <spine/Slot.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef enum {
|
||||
VERTEX_X1 = 0, VERTEX_Y1, VERTEX_X2, VERTEX_Y2, VERTEX_X3, VERTEX_Y3, VERTEX_X4, VERTEX_Y4
|
||||
} VertexIndex;
|
||||
|
||||
typedef struct RegionAttachment RegionAttachment;
|
||||
struct RegionAttachment {
|
||||
Attachment super;
|
||||
float x, y, scaleX, scaleY, rotation, width, height;
|
||||
AtlasRegion* region;
|
||||
float offset[8];
|
||||
float vertices[8];
|
||||
float uvs[8];
|
||||
};
|
||||
|
||||
RegionAttachment* RegionAttachment_create (const char* name);
|
||||
|
||||
void RegionAttachment_updateOffset (RegionAttachment* self);
|
||||
void RegionAttachment_updateVertices (RegionAttachment* self, Slot* slot);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_REGIONATTACHMENT_H_ */
|
|
@ -0,0 +1,199 @@
|
|||
/*******************************************************************************
|
||||
* 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/Skeleton.h>
|
||||
#include <string.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
Skeleton* Skeleton_create (SkeletonData* data) {
|
||||
Skeleton* self = NEW(Skeleton);
|
||||
CONST_CAST(SkeletonData*, self->data) = data;
|
||||
|
||||
self->boneCount = self->data->boneCount;
|
||||
self->bones = MALLOC(Bone*, self->boneCount);
|
||||
int i, ii;
|
||||
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 < self->boneCount; ++ii) {
|
||||
if (data->bones[ii] == boneData->parent) {
|
||||
parent = self->bones[ii];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
self->bones[i] = Bone_create(boneData, parent);
|
||||
}
|
||||
CONST_CAST(Bone*, self->root) = self->bones[0];
|
||||
|
||||
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 < self->boneCount; ++ii) {
|
||||
if (data->bones[ii] == slotData->boneData) {
|
||||
bone = self->bones[ii];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
self->slots[i] = Slot_create(slotData, self, bone);
|
||||
}
|
||||
|
||||
self->drawOrder = MALLOC(Slot*, self->slotCount);
|
||||
memcpy(self->drawOrder, self->slots, sizeof(Slot*) * self->slotCount);
|
||||
|
||||
self->r = 1;
|
||||
self->g = 1;
|
||||
self->b = 1;
|
||||
self->a = 1;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void Skeleton_dispose (Skeleton* self) {
|
||||
int i;
|
||||
for (i = 0; i < self->boneCount; ++i)
|
||||
Bone_dispose(self->bones[i]);
|
||||
FREE(self->bones);
|
||||
|
||||
for (i = 0; i < self->slotCount; ++i)
|
||||
Slot_dispose(self->slots[i]);
|
||||
FREE(self->slots);
|
||||
|
||||
FREE(self->drawOrder);
|
||||
}
|
||||
|
||||
void Skeleton_updateWorldTransform (const Skeleton* self) {
|
||||
int i;
|
||||
for (i = 0; i < self->boneCount; ++i)
|
||||
Bone_updateWorldTransform(self->bones[i], self->flipX, self->flipY);
|
||||
}
|
||||
|
||||
void Skeleton_setToBindPose (const Skeleton* self) {
|
||||
Skeleton_setBonesToBindPose(self);
|
||||
Skeleton_setSlotsToBindPose(self);
|
||||
}
|
||||
|
||||
void Skeleton_setBonesToBindPose (const Skeleton* self) {
|
||||
int i;
|
||||
for (i = 0; i < self->boneCount; ++i)
|
||||
Bone_setToBindPose(self->bones[i]);
|
||||
}
|
||||
|
||||
void Skeleton_setSlotsToBindPose (const Skeleton* self) {
|
||||
int i;
|
||||
for (i = 0; i < self->slotCount; ++i)
|
||||
Slot_setToBindPose(self->slots[i]);
|
||||
}
|
||||
|
||||
Bone* Skeleton_findBone (const Skeleton* self, const char* boneName) {
|
||||
int i;
|
||||
for (i = 0; i < self->boneCount; ++i)
|
||||
if (strcmp(self->data->bones[i]->name, boneName) == 0) return self->bones[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Skeleton_findBoneIndex (const Skeleton* self, const char* boneName) {
|
||||
int i;
|
||||
for (i = 0; i < self->boneCount; ++i)
|
||||
if (strcmp(self->data->bones[i]->name, boneName) == 0) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Slot* Skeleton_findSlot (const Skeleton* self, const char* slotName) {
|
||||
int i;
|
||||
for (i = 0; i < self->slotCount; ++i)
|
||||
if (strcmp(self->data->slots[i]->name, slotName) == 0) return self->slots[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Skeleton_findSlotIndex (const Skeleton* self, const char* slotName) {
|
||||
int i;
|
||||
for (i = 0; i < self->slotCount; ++i)
|
||||
if (strcmp(self->data->slots[i]->name, slotName) == 0) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Skeleton_setSkinByName (Skeleton* self, const char* skinName) {
|
||||
if (!skinName) {
|
||||
Skeleton_setSkin(self, 0);
|
||||
return 1;
|
||||
}
|
||||
Skin *skin = SkeletonData_findSkin(self->data, skinName);
|
||||
if (!skin) return 0;
|
||||
Skeleton_setSkin(self, skin);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Skeleton_setSkin (Skeleton* self, Skin* newSkin) {
|
||||
if (self->skin && newSkin) Skin_attachAll(newSkin, self, self->skin);
|
||||
CONST_CAST(Skin*, self->skin) = newSkin;
|
||||
}
|
||||
|
||||
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* self, int slotIndex, const char* attachmentName) {
|
||||
if (slotIndex == -1) return 0;
|
||||
if (self->skin) {
|
||||
Attachment *attachment = Skin_getAttachment(self->skin, slotIndex, attachmentName);
|
||||
if (attachment) return attachment;
|
||||
}
|
||||
if (self->data->defaultSkin) {
|
||||
Attachment *attachment = Skin_getAttachment(self->data->defaultSkin, slotIndex, attachmentName);
|
||||
if (attachment) return attachment;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Skeleton_setAttachment (Skeleton* self, const char* slotName, const char* attachmentName) {
|
||||
int i;
|
||||
for (i = 0; i < self->slotCount; ++i) {
|
||||
Slot *slot = self->slots[i];
|
||||
if (strcmp(slot->data->name, slotName) == 0) {
|
||||
Attachment* attachment = Skeleton_getAttachmentForSlotIndex(self, i, attachmentName);
|
||||
if (!attachment) return 0;
|
||||
Slot_setAttachment(slot, attachment);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Skeleton_update (Skeleton* self, float deltaTime) {
|
||||
self->time += deltaTime;
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,91 @@
|
|||
/*******************************************************************************
|
||||
* 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/SkeletonData.h>
|
||||
#include <spine/Slot.h>
|
||||
#include <spine/Skin.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct Skeleton Skeleton;
|
||||
struct Skeleton {
|
||||
SkeletonData* const data;
|
||||
|
||||
int boneCount;
|
||||
Bone** bones;
|
||||
Bone* const root;
|
||||
|
||||
int slotCount;
|
||||
Slot** slots;
|
||||
Slot** drawOrder;
|
||||
|
||||
Skin* const skin;
|
||||
float r, g, b, a;
|
||||
float time;
|
||||
int/*bool*/flipX, flipY;
|
||||
};
|
||||
|
||||
Skeleton* Skeleton_create (SkeletonData* data);
|
||||
void Skeleton_dispose (Skeleton* self);
|
||||
|
||||
void Skeleton_updateWorldTransform (const Skeleton* self);
|
||||
|
||||
void Skeleton_setToBindPose (const Skeleton* self);
|
||||
void Skeleton_setBonesToBindPose (const Skeleton* self);
|
||||
void Skeleton_setSlotsToBindPose (const Skeleton* self);
|
||||
|
||||
/* Returns 0 if the bone was not found. */
|
||||
Bone* Skeleton_findBone (const Skeleton* self, const char* boneName);
|
||||
/* Returns -1 if the bone was not found. */
|
||||
int Skeleton_findBoneIndex (const Skeleton* self, const char* boneName);
|
||||
|
||||
/* Returns 0 if the slot was not found. */
|
||||
Slot* Skeleton_findSlot (const Skeleton* self, const char* slotName);
|
||||
/* Returns -1 if the slot was not found. */
|
||||
int Skeleton_findSlotIndex (const Skeleton* self, const char* slotName);
|
||||
|
||||
/* Sets the skin used to look up attachments not found in the SkeletonData defaultSkin. Attachments from the new skin are
|
||||
* attached if the corresponding attachment from the old skin was attached.
|
||||
* @param skin May be 0.*/
|
||||
void Skeleton_setSkin (Skeleton* self, Skin* skin);
|
||||
/* Returns 0 if the skin was not found. See Skeleton_setSkin.
|
||||
* @param skinName May be 0. */
|
||||
int Skeleton_setSkinByName (Skeleton* self, const char* skinName);
|
||||
|
||||
/* Returns 0 if the slot or attachment was not found. */
|
||||
Attachment* Skeleton_getAttachmentForSlotName (const Skeleton* self, const char* slotName, const char* attachmentName);
|
||||
/* Returns 0 if the slot or attachment was not found. */
|
||||
Attachment* Skeleton_getAttachmentForSlotIndex (const Skeleton* self, int slotIndex, const char* attachmentName);
|
||||
/* Returns 0 if the slot or attachment was not found. */
|
||||
int Skeleton_setAttachment (Skeleton* self, const char* slotName, const char* attachmentName);
|
||||
|
||||
void Skeleton_update (Skeleton* self, float deltaTime);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_SKELETON_H_*/
|
|
@ -0,0 +1,99 @@
|
|||
/*******************************************************************************
|
||||
* 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/SkeletonData.h>
|
||||
#include <string.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
SkeletonData* SkeletonData_create () {
|
||||
return NEW(SkeletonData);
|
||||
}
|
||||
|
||||
void SkeletonData_dispose (SkeletonData* self) {
|
||||
int i;
|
||||
for (i = 0; i < self->boneCount; ++i)
|
||||
BoneData_dispose(self->bones[i]);
|
||||
FREE(self->bones);
|
||||
|
||||
for (i = 0; i < self->slotCount; ++i)
|
||||
SlotData_dispose(self->slots[i]);
|
||||
FREE(self->slots);
|
||||
|
||||
for (i = 0; i < self->skinCount; ++i)
|
||||
Skin_dispose(self->skins[i]);
|
||||
FREE(self->skins);
|
||||
|
||||
for (i = 0; i < self->animationCount; ++i)
|
||||
Animation_dispose(self->animations[i]);
|
||||
FREE(self->animations);
|
||||
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
BoneData* SkeletonData_findBone (const SkeletonData* self, const char* boneName) {
|
||||
int 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* self, const char* boneName) {
|
||||
int 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* self, const char* slotName) {
|
||||
int 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* self, const char* slotName) {
|
||||
int 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* self, const char* skinName) {
|
||||
int i;
|
||||
for (i = 0; i < self->skinCount; ++i)
|
||||
if (strcmp(self->skins[i]->name, skinName) == 0) return self->skins[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
Animation* SkeletonData_findAnimation (const SkeletonData* self, const char* animationName) {
|
||||
int i;
|
||||
for (i = 0; i < self->animationCount; ++i)
|
||||
if (strcmp(self->animations[i]->name, animationName) == 0) return self->animations[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,66 @@
|
|||
/*******************************************************************************
|
||||
* 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_SKELETONDATA_H_
|
||||
#define SPINE_SKELETONDATA_H_
|
||||
|
||||
#include <spine/BoneData.h>
|
||||
#include <spine/SlotData.h>
|
||||
#include <spine/Skin.h>
|
||||
#include <spine/Animation.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct {
|
||||
int boneCount;
|
||||
BoneData** bones;
|
||||
|
||||
int slotCount;
|
||||
SlotData** slots;
|
||||
|
||||
int skinCount;
|
||||
Skin** skins;
|
||||
Skin* defaultSkin;
|
||||
|
||||
int animationCount;
|
||||
Animation** animations;
|
||||
} SkeletonData;
|
||||
|
||||
SkeletonData* SkeletonData_create ();
|
||||
void SkeletonData_dispose (SkeletonData* self);
|
||||
|
||||
BoneData* SkeletonData_findBone (const SkeletonData* self, const char* boneName);
|
||||
int SkeletonData_findBoneIndex (const SkeletonData* self, const char* boneName);
|
||||
|
||||
SlotData* SkeletonData_findSlot (const SkeletonData* self, const char* slotName);
|
||||
int SkeletonData_findSlotIndex (const SkeletonData* self, const char* slotName);
|
||||
|
||||
Skin* SkeletonData_findSkin (const SkeletonData* self, const char* skinName);
|
||||
|
||||
Animation* SkeletonData_findAnimation (const SkeletonData* self, const char* animationName);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_SKELETONDATA_H_ */
|
|
@ -0,0 +1,392 @@
|
|||
/*******************************************************************************
|
||||
* 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/SkeletonJson.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "Json.h"
|
||||
#include <spine/extension.h>
|
||||
#include <spine/RegionAttachment.h>
|
||||
#include <spine/AtlasAttachmentLoader.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct {
|
||||
SkeletonJson super;
|
||||
int ownsLoader;
|
||||
} _Internal;
|
||||
|
||||
SkeletonJson* SkeletonJson_createWithLoader (AttachmentLoader* attachmentLoader) {
|
||||
SkeletonJson* self = SUPER(NEW(_Internal));
|
||||
self->scale = 1;
|
||||
self->attachmentLoader = attachmentLoader;
|
||||
return self;
|
||||
}
|
||||
|
||||
SkeletonJson* SkeletonJson_create (Atlas* atlas) {
|
||||
AtlasAttachmentLoader* attachmentLoader = AtlasAttachmentLoader_create(atlas);
|
||||
SkeletonJson* self = SkeletonJson_createWithLoader(SUPER(attachmentLoader));
|
||||
SUB_CAST(_Internal, self) ->ownsLoader = 1;
|
||||
return self;
|
||||
}
|
||||
|
||||
void SkeletonJson_dispose (SkeletonJson* self) {
|
||||
if (SUB_CAST(_Internal, self) ->ownsLoader) AttachmentLoader_dispose(self->attachmentLoader);
|
||||
FREE(self->error);
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
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(self->error, message);
|
||||
if (root) Json_dispose(root);
|
||||
}
|
||||
|
||||
static float toColor (const char* value, int index) {
|
||||
if (strlen(value) != 8) return -1;
|
||||
value += index * 2;
|
||||
char digits[3];
|
||||
digits[0] = *value;
|
||||
digits[1] = *(value + 1);
|
||||
digits[2] = '\0';
|
||||
char* error;
|
||||
int color = strtoul(digits, &error, 16);
|
||||
if (*error != 0) return -1;
|
||||
return color / (float)255;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static Animation* _SkeletonJson_readAnimation (SkeletonJson* self, Json* root, SkeletonData *skeletonData) {
|
||||
Json* bones = Json_getItem(root, "bones");
|
||||
int boneCount = bones ? Json_getSize(bones) : 0;
|
||||
|
||||
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(root->name, timelineCount);
|
||||
animation->timelineCount = 0;
|
||||
skeletonData->animations[skeletonData->animationCount] = animation;
|
||||
skeletonData->animationCount++;
|
||||
|
||||
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(SUPER(timeline), iii, frame);
|
||||
}
|
||||
animation->timelines[animation->timelineCount++] = (Timeline*)timeline;
|
||||
float duration = timeline->frames[frameCount * 2 - 2];
|
||||
if (duration > animation->duration) animation->duration = duration;
|
||||
|
||||
} 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(SUPER(timeline), iii, frame);
|
||||
}
|
||||
animation->timelines[animation->timelineCount++] = (Timeline*)timeline;
|
||||
float duration = timeline->frames[frameCount * 3 - 3];
|
||||
if (duration > animation->duration) animation->duration = duration;
|
||||
} else {
|
||||
Animation_dispose(animation);
|
||||
_SkeletonJson_setError(self, 0, "Invalid timeline type for a bone: ", timelineType);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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(SUPER(timeline), iii, frame);
|
||||
}
|
||||
animation->timelines[animation->timelineCount++] = (Timeline*)timeline;
|
||||
float duration = timeline->frames[frameCount * 5 - 5];
|
||||
if (duration > animation->duration) animation->duration = duration;
|
||||
|
||||
} 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;
|
||||
float duration = timeline->frames[frameCount - 1];
|
||||
if (duration > animation->duration) animation->duration = duration;
|
||||
|
||||
} else {
|
||||
Animation_dispose(animation);
|
||||
_SkeletonJson_setError(self, 0, "Invalid timeline type for a slot: ", timelineType);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return animation;
|
||||
}
|
||||
|
||||
SkeletonData* SkeletonJson_readSkeletonDataFile (SkeletonJson* self, const char* path) {
|
||||
int length;
|
||||
const char* json = _Util_readFile(path, &length);
|
||||
if (!json) {
|
||||
_SkeletonJson_setError(self, 0, "Unable to read skeleton file: ", path);
|
||||
return 0;
|
||||
}
|
||||
SkeletonData* skeletonData = SkeletonJson_readSkeletonData(self, json);
|
||||
FREE(json);
|
||||
return skeletonData;
|
||||
}
|
||||
|
||||
SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* self, const char* json) {
|
||||
FREE(self->error);
|
||||
CONST_CAST(char*, self->error) = 0;
|
||||
|
||||
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;
|
||||
|
||||
Json* bones = Json_getItem(root, "bones");
|
||||
int boneCount = Json_getSize(bones);
|
||||
skeletonData->bones = MALLOC(BoneData*, boneCount);
|
||||
for (i = 0; i < boneCount; ++i) {
|
||||
Json* boneMap = Json_getItemAt(bones, i);
|
||||
|
||||
const char* boneName = Json_getString(boneMap, "name", 0);
|
||||
|
||||
BoneData* parent = 0;
|
||||
const char* parentName = Json_getString(boneMap, "parent", 0);
|
||||
if (parentName) {
|
||||
parent = SkeletonData_findBone(skeletonData, 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 = Json_getFloat(boneMap, "length", 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++;
|
||||
}
|
||||
|
||||
Json* slots = Json_getItem(root, "slots");
|
||||
if (slots) {
|
||||
int slotCount = Json_getSize(slots);
|
||||
skeletonData->slots = MALLOC(SlotData*, slotCount);
|
||||
for (i = 0; i < slotCount; ++i) {
|
||||
Json* slotMap = Json_getItemAt(slots, i);
|
||||
|
||||
const char* slotName = Json_getString(slotMap, "name", 0);
|
||||
|
||||
const char* boneName = Json_getString(slotMap, "bone", 0);
|
||||
BoneData* boneData = SkeletonData_findBone(skeletonData, 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 = Json_getString(slotMap, "color", 0);
|
||||
if (color) {
|
||||
slotData->r = toColor(color, 0);
|
||||
slotData->g = toColor(color, 1);
|
||||
slotData->b = toColor(color, 2);
|
||||
slotData->a = toColor(color, 3);
|
||||
}
|
||||
|
||||
Json *attachmentItem = Json_getItem(slotMap, "attachment");
|
||||
if (attachmentItem) SlotData_setAttachmentName(slotData, attachmentItem->valuestring);
|
||||
|
||||
skeletonData->slots[i] = slotData;
|
||||
skeletonData->slotCount++;
|
||||
}
|
||||
}
|
||||
|
||||
Json* skinsMap = Json_getItem(root, "skins");
|
||||
if (skinsMap) {
|
||||
int skinCount = Json_getSize(skinsMap);
|
||||
skeletonData->skins = MALLOC(Skin*, skinCount);
|
||||
for (i = 0; i < skinCount; ++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 = Json_getSize(slotMap);
|
||||
for (ii = 0; ii < slotNameCount; ++ii) {
|
||||
Json* attachmentsMap = Json_getItemAt(slotMap, ii);
|
||||
const char* slotName = attachmentsMap->name;
|
||||
int slotIndex = SkeletonData_findSlotIndex(skeletonData, slotName);
|
||||
|
||||
int attachmentCount = Json_getSize(attachmentsMap);
|
||||
for (iii = 0; iii < attachmentCount; ++iii) {
|
||||
Json* attachmentMap = Json_getItemAt(attachmentsMap, iii);
|
||||
const char* skinAttachmentName = attachmentMap->name;
|
||||
const char* attachmentName = Json_getString(attachmentMap, "name", skinAttachmentName);
|
||||
|
||||
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 {
|
||||
SkeletonData_dispose(skeletonData);
|
||||
_SkeletonJson_setError(self, root, "Unknown attachment type: ", typeString);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Attachment* attachment = AttachmentLoader_newAttachment(self->attachmentLoader, skin, type, attachmentName);
|
||||
if (!attachment) {
|
||||
if (self->attachmentLoader->error1) {
|
||||
SkeletonData_dispose(skeletonData);
|
||||
_SkeletonJson_setError(self, root, self->attachmentLoader->error1, self->attachmentLoader->error2);
|
||||
return 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attachment->type == ATTACHMENT_REGION || attachment->type == ATTACHMENT_REGION_SEQUENCE) {
|
||||
RegionAttachment* regionAttachment = (RegionAttachment*)attachment;
|
||||
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);
|
||||
}
|
||||
|
||||
Skin_addAttachment(skin, slotIndex, skinAttachmentName, attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Json* animations = Json_getItem(root, "animations");
|
||||
if (animations) {
|
||||
int animationCount = Json_getSize(animations);
|
||||
skeletonData->animations = MALLOC(Animation*, animationCount);
|
||||
for (i = 0; i < animationCount; ++i) {
|
||||
Json* animationMap = Json_getItemAt(animations, i);
|
||||
_SkeletonJson_readAnimation(self, animationMap, skeletonData);
|
||||
}
|
||||
}
|
||||
|
||||
Json_dispose(root);
|
||||
return skeletonData;
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,52 @@
|
|||
/*******************************************************************************
|
||||
* 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/Attachment.h>
|
||||
#include <spine/AttachmentLoader.h>
|
||||
#include <spine/SkeletonData.h>
|
||||
#include <spine/Atlas.h>
|
||||
#include <spine/Animation.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct {
|
||||
float scale;
|
||||
AttachmentLoader* attachmentLoader;
|
||||
const char* const error;
|
||||
} SkeletonJson;
|
||||
|
||||
SkeletonJson* SkeletonJson_createWithLoader (AttachmentLoader* attachmentLoader);
|
||||
SkeletonJson* SkeletonJson_create (Atlas* atlas);
|
||||
void SkeletonJson_dispose (SkeletonJson* self);
|
||||
|
||||
SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* self, const char* json);
|
||||
SkeletonData* SkeletonJson_readSkeletonDataFile (SkeletonJson* self, const char* path);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_SKELETONJSON_H_ */
|
|
@ -0,0 +1,105 @@
|
|||
/*******************************************************************************
|
||||
* 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/Skin.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct _Entry _Entry;
|
||||
struct _Entry {
|
||||
int slotIndex;
|
||||
const char* name;
|
||||
Attachment* attachment;
|
||||
_Entry* next;
|
||||
};
|
||||
|
||||
_Entry* _Entry_create (int slotIndex, const char* name, Attachment* attachment) {
|
||||
_Entry* self = NEW(_Entry);
|
||||
self->slotIndex = slotIndex;
|
||||
MALLOC_STR(self->name, name);
|
||||
self->attachment = attachment;
|
||||
return self;
|
||||
}
|
||||
|
||||
void _Entry_dispose (_Entry* self) {
|
||||
Attachment_dispose(self->attachment);
|
||||
FREE(self->name);
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct {
|
||||
Skin super;
|
||||
_Entry* entries;
|
||||
} _Internal;
|
||||
|
||||
Skin* Skin_create (const char* name) {
|
||||
Skin* self = SUPER(NEW(_Internal));
|
||||
MALLOC_STR(self->name, name);
|
||||
return self;
|
||||
}
|
||||
|
||||
void Skin_dispose (Skin* self) {
|
||||
_Entry* entry = SUB_CAST(_Internal, self)->entries;
|
||||
while (entry) {
|
||||
_Entry* nextEtry = entry->next;
|
||||
_Entry_dispose(entry);
|
||||
entry = nextEtry;
|
||||
}
|
||||
|
||||
FREE(self->name);
|
||||
FREE(self);
|
||||
}
|
||||
#include <stdio.h>
|
||||
void Skin_addAttachment (Skin* self, int slotIndex, const char* name, Attachment* attachment) {
|
||||
_Entry* newEntry = _Entry_create(slotIndex, name, attachment);
|
||||
newEntry->next = SUB_CAST(_Internal, self)->entries;
|
||||
SUB_CAST(_Internal, self)->entries = newEntry;
|
||||
}
|
||||
|
||||
Attachment* Skin_getAttachment (const Skin* self, int slotIndex, const char* name) {
|
||||
const _Entry* entry = SUB_CAST(_Internal, self) ->entries;
|
||||
while (entry) {
|
||||
if (entry->slotIndex == slotIndex && strcmp(entry->name, name) == 0) return entry->attachment;
|
||||
entry = entry->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Skin_attachAll (const Skin* self, Skeleton* skeleton, const Skin* oldSkin) {
|
||||
const _Entry *entry = SUB_CAST(_Internal, oldSkin) ->entries;
|
||||
while (entry) {
|
||||
Slot *slot = skeleton->slots[entry->slotIndex];
|
||||
if (slot->attachment == entry->attachment) {
|
||||
Attachment *attachment = Skin_getAttachment(self, entry->slotIndex, entry->name);
|
||||
if (attachment) Slot_setAttachment(slot, attachment);
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,52 @@
|
|||
/*******************************************************************************
|
||||
* 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_SKIN_H_
|
||||
#define SPINE_SKIN_H_
|
||||
|
||||
#include <spine/Attachment.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
struct Skeleton;
|
||||
|
||||
typedef struct {
|
||||
const char* const name;
|
||||
} Skin;
|
||||
|
||||
Skin* Skin_create (const char* name);
|
||||
void Skin_dispose (Skin* self);
|
||||
|
||||
/* The Skin owns the attachment. */
|
||||
void Skin_addAttachment (Skin* self, int slotIndex, const char* name, Attachment* attachment);
|
||||
/* Returns 0 if the attachment was not found. */
|
||||
Attachment* Skin_getAttachment (const Skin* self, int slotIndex, const char* name);
|
||||
|
||||
/** Attach each attachment in this skin if the corresponding attachment in oldSkin is currently attached. */
|
||||
void Skin_attachAll (const Skin* self, struct Skeleton* skeleton, const Skin* oldSkin);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_SKIN_H_ */
|
|
@ -0,0 +1,83 @@
|
|||
/*******************************************************************************
|
||||
* 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/Slot.h>
|
||||
#include <spine/extension.h>
|
||||
#include <spine/Skeleton.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct {
|
||||
Slot super;
|
||||
float attachmentTime;
|
||||
} _Internal;
|
||||
|
||||
Slot* Slot_create (SlotData* data, Skeleton* skeleton, Bone* bone) {
|
||||
Slot* self = SUPER(NEW(_Internal));
|
||||
CONST_CAST(SlotData*, self->data) = data;
|
||||
CONST_CAST(Skeleton*, self->skeleton) = skeleton;
|
||||
CONST_CAST(Bone*, self->bone) = bone;
|
||||
Slot_setToBindPose(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
void Slot_dispose (Slot* self) {
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
void Slot_setAttachment (Slot* self, Attachment* attachment) {
|
||||
CONST_CAST(Attachment*, self->attachment) = attachment;
|
||||
SUB_CAST(_Internal, self) ->attachmentTime = self->skeleton->time;
|
||||
}
|
||||
|
||||
void Slot_setAttachmentTime (Slot* self, float time) {
|
||||
SUB_CAST(_Internal, self) ->attachmentTime = self->skeleton->time - time;
|
||||
}
|
||||
|
||||
float Slot_getAttachmentTime (const Slot* self) {
|
||||
return self->skeleton->time - SUB_CAST(_Internal, self) ->attachmentTime;
|
||||
}
|
||||
|
||||
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 (self->data->attachmentName) {
|
||||
/* Find slot index. */
|
||||
int i;
|
||||
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(self, attachment);
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,58 @@
|
|||
/*******************************************************************************
|
||||
* 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_SLOT_H_
|
||||
#define SPINE_SLOT_H_
|
||||
|
||||
#include <spine/Bone.h>
|
||||
#include <spine/Attachment.h>
|
||||
#include <spine/SlotData.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
struct Skeleton;
|
||||
|
||||
typedef struct Slot {
|
||||
SlotData* const data;
|
||||
struct Skeleton* const skeleton;
|
||||
Bone* const bone;
|
||||
float r, g, b, a;
|
||||
Attachment* const attachment;
|
||||
} Slot;
|
||||
|
||||
Slot* Slot_create (SlotData* data, struct Skeleton* skeleton, Bone* bone);
|
||||
void Slot_dispose (Slot* self);
|
||||
|
||||
/* @param attachment May be 0 to clear the attachment for the slot. */
|
||||
void Slot_setAttachment (Slot* self, Attachment* attachment);
|
||||
|
||||
void Slot_setAttachmentTime (Slot* self, float time);
|
||||
float Slot_getAttachmentTime (const Slot* self);
|
||||
|
||||
void Slot_setToBindPose (Slot* self);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_SLOT_H_ */
|
|
@ -0,0 +1,56 @@
|
|||
/*******************************************************************************
|
||||
* 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/SlotData.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
SlotData* SlotData_create (const char* name, BoneData* boneData) {
|
||||
SlotData* self = NEW(SlotData);
|
||||
MALLOC_STR(self->name, name);
|
||||
CONST_CAST(BoneData*, self->boneData) = boneData;
|
||||
self->r = 1;
|
||||
self->g = 1;
|
||||
self->b = 1;
|
||||
self->a = 1;
|
||||
return self;
|
||||
}
|
||||
|
||||
void SlotData_dispose (SlotData* self) {
|
||||
FREE(self->name);
|
||||
FREE(self->attachmentName);
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
void SlotData_setAttachmentName (SlotData* self, const char* attachmentName) {
|
||||
FREE(self->attachmentName);
|
||||
if (attachmentName)
|
||||
MALLOC_STR(self->attachmentName, attachmentName);
|
||||
else
|
||||
CONST_CAST(char*, self->attachmentName) = 0;
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,48 @@
|
|||
/*******************************************************************************
|
||||
* 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_SLOTDATA_H_
|
||||
#define SPINE_SLOTDATA_H_
|
||||
|
||||
#include <spine/BoneData.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
typedef struct {
|
||||
const char* const name;
|
||||
const BoneData* const boneData;
|
||||
const char* const attachmentName;
|
||||
float r, g, b, a;
|
||||
} SlotData;
|
||||
|
||||
SlotData* SlotData_create (const char* name, BoneData* boneData);
|
||||
void SlotData_dispose (SlotData* self);
|
||||
|
||||
/* @param attachmentName May be 0 for no bind pose attachment. */
|
||||
void SlotData_setAttachmentName (SlotData* self, const char* attachmentName);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_SLOTDATA_H_ */
|
|
@ -0,0 +1,68 @@
|
|||
/*******************************************************************************
|
||||
* 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/extension.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
static void* (*mallocFunc) (size_t size) = malloc;
|
||||
static void (*freeFunc) (void* ptr) = free;
|
||||
|
||||
void* _malloc (size_t size) {
|
||||
return mallocFunc(size);
|
||||
}
|
||||
void* _calloc (size_t num, size_t size) {
|
||||
void* ptr = mallocFunc(size);
|
||||
if (ptr) memset(ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
void _free (void* ptr) {
|
||||
freeFunc(ptr);
|
||||
}
|
||||
|
||||
void _setMalloc (void* (*malloc) (size_t size)) {
|
||||
mallocFunc = malloc;
|
||||
}
|
||||
void _setFree (void (*free) (void* ptr)) {
|
||||
freeFunc = free;
|
||||
}
|
||||
|
||||
char* _readFile (const char* path, int* length) {
|
||||
FILE *file = fopen(path, "rb");
|
||||
if (!file) return 0;
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
*length = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
char* data = MALLOC(char, *length);
|
||||
fread(data, 1, *length, file);
|
||||
fclose(file);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,145 @@
|
|||
/*******************************************************************************
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
Implementation notes:
|
||||
|
||||
- An OOP style is used where each "class" is made up of a struct and a number of functions prefixed with the struct name.
|
||||
|
||||
- struct fields that are const are readonly. Either they are set in a create function and can never be changed, or they can only
|
||||
be changed by calling a function.
|
||||
|
||||
- Inheritance is done using a struct field named "super" as the first field, allowing the struct to be cast to its "super class".
|
||||
This works because a pointer to a struct is guaranteed to be a pointer to the first struct field.
|
||||
|
||||
- Classes intended for inheritance provide init/deinit functions which subclasses must call in their create/dispose functions.
|
||||
|
||||
- Polymorphism is done by a base class providing function pointers in its init function. The public API delegates to this
|
||||
function.
|
||||
|
||||
- Subclasses do not provide a dispose function, instead the base class' dispose function should be used, which will delegate to
|
||||
a dispose function.
|
||||
|
||||
- Classes not designed for inheritance cannot be extended. They may use an internal subclass to hide private data and don't
|
||||
expose function pointers.
|
||||
|
||||
- The public API hides implementation details such init/deinit functions. An internal API is exposed in extension.h to allow
|
||||
classes to be extended. Internal functions begin with underscore (_).
|
||||
|
||||
- OOP in C tends to lose type safety. Macros are provided in extension.h to give context for why a cast is being done.
|
||||
*/
|
||||
|
||||
#ifndef SPINE_EXTENSION_H_
|
||||
#define SPINE_EXTENSION_H_
|
||||
|
||||
/* All allocation uses these. */
|
||||
#define MALLOC(TYPE,COUNT) ((TYPE*)_malloc(sizeof(TYPE) * COUNT))
|
||||
#define CALLOC(TYPE,COUNT) ((TYPE*)_calloc(1, sizeof(TYPE) * COUNT))
|
||||
#define NEW(TYPE) CALLOC(TYPE,1)
|
||||
|
||||
/* Gets the direct super class. Type safe. */
|
||||
#define SUPER(VALUE) (&VALUE->super)
|
||||
|
||||
/* Cast to a super class. Not type safe, use with care. Prefer SUPER() where possible. */
|
||||
#define SUPER_CAST(TYPE,VALUE) ((TYPE*)VALUE)
|
||||
|
||||
/* Cast to a sub class. Not type safe, use with care. */
|
||||
#define SUB_CAST(TYPE,VALUE) ((TYPE*)VALUE)
|
||||
|
||||
/* Casts away const. Can be used as an lvalue. Not type safe, use with care. */
|
||||
#define CONST_CAST(TYPE,VALUE) (*(TYPE*)&VALUE)
|
||||
|
||||
/* Gets the vtable for the specified type. Not type safe, use with care. */
|
||||
#define VTABLE(TYPE,VALUE) ((_##TYPE##Vtable*)((TYPE*)VALUE)->vtable)
|
||||
|
||||
/* Frees memory. Can be used on const types. */
|
||||
#define FREE(VALUE) _free((void*)VALUE)
|
||||
|
||||
/* Allocates a new char[], assigns it to TO, and copies FROM to it. Can be used on const types. */
|
||||
#define MALLOC_STR(TO,FROM) strcpy(CONST_CAST(char*, TO) = (char*)malloc(strlen(FROM) + 1), FROM)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <spine/Skeleton.h>
|
||||
#include <spine/RegionAttachment.h>
|
||||
#include <spine/Animation.h>
|
||||
#include <spine/Atlas.h>
|
||||
#include <spine/AttachmentLoader.h>
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
/*
|
||||
* Functions that must be implemented:
|
||||
*/
|
||||
|
||||
void _AtlasPage_createTexture (AtlasPage* self, const char* path);
|
||||
void _AtlasPage_disposeTexture (AtlasPage* self);
|
||||
char* _Util_readFile (const char* path, int* length);
|
||||
|
||||
/*
|
||||
* Internal API available for extension:
|
||||
*/
|
||||
|
||||
void* _malloc (size_t size);
|
||||
void* _calloc (size_t num, size_t size);
|
||||
void _free (void* ptr);
|
||||
|
||||
void _setMalloc (void* (*_malloc) (size_t size));
|
||||
void _setFree (void (*_free) (void* ptr));
|
||||
|
||||
char* _readFile (const char* path, int* length);
|
||||
|
||||
/**/
|
||||
|
||||
void _AttachmentLoader_init (AttachmentLoader* self, //
|
||||
void (*dispose) (AttachmentLoader* self), //
|
||||
Attachment* (*newAttachment) (AttachmentLoader* self, Skin* skin, AttachmentType type, const char* name));
|
||||
void _AttachmentLoader_deinit (AttachmentLoader* self);
|
||||
void _AttachmentLoader_setError (AttachmentLoader* self, const char* error1, const char* error2);
|
||||
void _AttachmentLoader_setUnknownTypeError (AttachmentLoader* self, AttachmentType type);
|
||||
|
||||
/**/
|
||||
|
||||
void _Attachment_init (Attachment* self, const char* name, AttachmentType type, //
|
||||
void (*dispose) (Attachment* self));
|
||||
void _Attachment_deinit (Attachment* self);
|
||||
|
||||
/**/
|
||||
|
||||
void _Timeline_init (Timeline* self, //
|
||||
void (*dispose) (Timeline* self), //
|
||||
void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha));
|
||||
void _Timeline_deinit (Timeline* self);
|
||||
|
||||
/**/
|
||||
|
||||
void _CurveTimeline_init (CurveTimeline* self, int frameCount, //
|
||||
void (*dispose) (Timeline* self), //
|
||||
void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha));
|
||||
void _CurveTimeline_deinit (CurveTimeline* self);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_EXTENSION_H_ */
|
|
@ -0,0 +1,307 @@
|
|||
/*******************************************************************************
|
||||
* 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/spine-cocos2dx.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
USING_NS_CC;
|
||||
using std::min;
|
||||
using std::max;
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
void _AtlasPage_createTexture (AtlasPage* self, const char* path) {
|
||||
CCTexture2D* texture = CCTextureCache::sharedTextureCache()->addImage(path);
|
||||
CCTextureAtlas* textureAtlas = CCTextureAtlas::createWithTexture(texture, 4);
|
||||
textureAtlas->retain();
|
||||
self->texture = textureAtlas;
|
||||
|
||||
// Using getContentSize to make it supports the strategy of loading resources in cocos2d-x.
|
||||
|
||||
// self->width = texture->getPixelsWide();
|
||||
// self->height = texture->getPixelsHigh();
|
||||
|
||||
self->width = texture->getContentSize().width;
|
||||
self->height = texture->getContentSize().height;
|
||||
}
|
||||
|
||||
void _AtlasPage_disposeTexture (AtlasPage* self) {
|
||||
((CCTextureAtlas*)self->texture)->release();
|
||||
}
|
||||
|
||||
char* _Util_readFile (const char* path, int* length) {
|
||||
unsigned long size;
|
||||
char* data = reinterpret_cast<char*>(CCFileUtils::sharedFileUtils()->getFileData(path, "r", &size));
|
||||
*length = size;
|
||||
return data;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
void RegionAttachment_updateQuad (RegionAttachment* self, Slot* slot, ccV3F_C4B_T2F_Quad* quad) {
|
||||
RegionAttachment_updateVertices(self, slot);
|
||||
|
||||
GLubyte r = slot->skeleton->r * slot->r * 255;
|
||||
GLubyte g = slot->skeleton->g * slot->g * 255;
|
||||
GLubyte b = slot->skeleton->b * slot->b * 255;
|
||||
GLubyte a = slot->skeleton->a * slot->a * 255;
|
||||
quad->bl.colors.r = r;
|
||||
quad->bl.colors.g = g;
|
||||
quad->bl.colors.b = b;
|
||||
quad->bl.colors.a = a;
|
||||
quad->tl.colors.r = r;
|
||||
quad->tl.colors.g = g;
|
||||
quad->tl.colors.b = b;
|
||||
quad->tl.colors.a = a;
|
||||
quad->tr.colors.r = r;
|
||||
quad->tr.colors.g = g;
|
||||
quad->tr.colors.b = b;
|
||||
quad->tr.colors.a = a;
|
||||
quad->br.colors.r = r;
|
||||
quad->br.colors.g = g;
|
||||
quad->br.colors.b = b;
|
||||
quad->br.colors.a = a;
|
||||
|
||||
quad->bl.vertices.x = self->vertices[VERTEX_X1];
|
||||
quad->bl.vertices.y = self->vertices[VERTEX_Y1];
|
||||
quad->tl.vertices.x = self->vertices[VERTEX_X2];
|
||||
quad->tl.vertices.y = self->vertices[VERTEX_Y2];
|
||||
quad->tr.vertices.x = self->vertices[VERTEX_X3];
|
||||
quad->tr.vertices.y = self->vertices[VERTEX_Y3];
|
||||
quad->br.vertices.x = self->vertices[VERTEX_X4];
|
||||
quad->br.vertices.y = self->vertices[VERTEX_Y4];
|
||||
|
||||
if (self->region->rotate) {
|
||||
quad->tl.texCoords.u = self->region->u;
|
||||
quad->tl.texCoords.v = self->region->v2;
|
||||
quad->tr.texCoords.u = self->region->u;
|
||||
quad->tr.texCoords.v = self->region->v;
|
||||
quad->br.texCoords.u = self->region->u2;
|
||||
quad->br.texCoords.v = self->region->v;
|
||||
quad->bl.texCoords.u = self->region->u2;
|
||||
quad->bl.texCoords.v = self->region->v2;
|
||||
} else {
|
||||
quad->bl.texCoords.u = self->region->u;
|
||||
quad->bl.texCoords.v = self->region->v2;
|
||||
quad->tl.texCoords.u = self->region->u;
|
||||
quad->tl.texCoords.v = self->region->v;
|
||||
quad->tr.texCoords.u = self->region->u2;
|
||||
quad->tr.texCoords.v = self->region->v;
|
||||
quad->br.texCoords.u = self->region->u2;
|
||||
quad->br.texCoords.v = self->region->v2;
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
CCSkeleton* CCSkeleton::createWithFile (const char* skeletonDataFile, Atlas* atlas, float scale) {
|
||||
SkeletonJson* json = SkeletonJson_create(atlas);
|
||||
json->scale = scale;
|
||||
SkeletonData* skeletonData = SkeletonJson_readSkeletonDataFile(json, skeletonDataFile);
|
||||
SkeletonJson_dispose(json);
|
||||
CCSkeleton* node = skeletonData ? createWithData(skeletonData) : 0;
|
||||
node->ownsSkeleton = true;
|
||||
return node;
|
||||
}
|
||||
|
||||
CCSkeleton* CCSkeleton::createWithFile (const char* skeletonDataFile, const char* atlasFile, float scale) {
|
||||
Atlas* atlas = Atlas_readAtlasFile(atlasFile);
|
||||
if (!atlas) return 0;
|
||||
SkeletonJson* json = SkeletonJson_create(atlas);
|
||||
json->scale = scale;
|
||||
SkeletonData* skeletonData = SkeletonJson_readSkeletonDataFile(json, skeletonDataFile);
|
||||
SkeletonJson_dispose(json);
|
||||
if (!skeletonData) {
|
||||
Atlas_dispose(atlas);
|
||||
return 0;
|
||||
}
|
||||
CCSkeleton* node = createWithData(skeletonData);
|
||||
node->ownsSkeleton = true;
|
||||
node->atlas = atlas;
|
||||
return node;
|
||||
}
|
||||
|
||||
CCSkeleton* CCSkeleton::createWithData (SkeletonData* skeletonData, AnimationStateData* stateData) {
|
||||
CCSkeleton* node = new CCSkeleton(skeletonData, stateData);
|
||||
node->autorelease();
|
||||
return node;
|
||||
}
|
||||
|
||||
CCSkeleton::CCSkeleton (SkeletonData *skeletonData, AnimationStateData *stateData) :
|
||||
ownsSkeleton(false), ownsStateData(false), atlas(0),
|
||||
skeleton(0), state(0), debugSlots(false), debugBones(false) {
|
||||
CONST_CAST(Skeleton*, skeleton) = Skeleton_create(skeletonData);
|
||||
|
||||
if (!stateData) {
|
||||
stateData = AnimationStateData_create(skeletonData);
|
||||
ownsStateData = true;
|
||||
}
|
||||
CONST_CAST(AnimationState*, state) = AnimationState_create(stateData);
|
||||
|
||||
blendFunc.src = GL_ONE;
|
||||
blendFunc.dst = GL_ONE_MINUS_SRC_ALPHA;
|
||||
|
||||
timeScale = 1;
|
||||
|
||||
setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureColor));
|
||||
scheduleUpdate();
|
||||
}
|
||||
|
||||
CCSkeleton::~CCSkeleton () {
|
||||
if (ownsSkeleton) Skeleton_dispose(skeleton);
|
||||
if (ownsStateData) AnimationStateData_dispose(state->data);
|
||||
if (atlas) Atlas_dispose(atlas);
|
||||
AnimationState_dispose(state);
|
||||
}
|
||||
|
||||
void CCSkeleton::update (float deltaTime) {
|
||||
Skeleton_update(skeleton, deltaTime);
|
||||
AnimationState_update(state, deltaTime * timeScale);
|
||||
AnimationState_apply(state, skeleton);
|
||||
Skeleton_updateWorldTransform(skeleton);
|
||||
}
|
||||
|
||||
void CCSkeleton::draw () {
|
||||
CC_NODE_DRAW_SETUP();
|
||||
|
||||
ccGLBlendFunc(blendFunc.src, blendFunc.dst);
|
||||
ccColor3B color = getColor();
|
||||
skeleton->r = color.r / (float)255;
|
||||
skeleton->g = color.g / (float)255;
|
||||
skeleton->b = color.b / (float)255;
|
||||
skeleton->a = getOpacity() / (float)255;
|
||||
|
||||
CCTextureAtlas* textureAtlas = 0;
|
||||
ccV3F_C4B_T2F_Quad quad;
|
||||
quad.tl.vertices.z = 0;
|
||||
quad.tr.vertices.z = 0;
|
||||
quad.bl.vertices.z = 0;
|
||||
quad.br.vertices.z = 0;
|
||||
for (int i = 0, n = skeleton->slotCount; i < n; i++) {
|
||||
Slot* slot = skeleton->slots[i];
|
||||
if (!slot->attachment || slot->attachment->type != ATTACHMENT_REGION) continue;
|
||||
RegionAttachment* attachment = (RegionAttachment*)slot->attachment;
|
||||
CCTextureAtlas* regionTextureAtlas = (CCTextureAtlas*)attachment->region->page->texture;
|
||||
if (regionTextureAtlas != textureAtlas) {
|
||||
if (textureAtlas) {
|
||||
textureAtlas->drawQuads();
|
||||
textureAtlas->removeAllQuads();
|
||||
}
|
||||
}
|
||||
textureAtlas = regionTextureAtlas;
|
||||
if (textureAtlas->getCapacity() == textureAtlas->getTotalQuads() &&
|
||||
!textureAtlas->resizeCapacity(textureAtlas->getCapacity() * 2)) return;
|
||||
RegionAttachment_updateQuad(attachment, slot, &quad);
|
||||
textureAtlas->updateQuad(&quad, textureAtlas->getTotalQuads());
|
||||
}
|
||||
if (textureAtlas) {
|
||||
textureAtlas->drawQuads();
|
||||
textureAtlas->removeAllQuads();
|
||||
}
|
||||
|
||||
if (debugSlots) {
|
||||
// Slots.
|
||||
ccDrawColor4B(0, 0, 255, 255);
|
||||
glLineWidth(1);
|
||||
CCPoint points[4];
|
||||
ccV3F_C4B_T2F_Quad quad;
|
||||
for (int i = 0, n = skeleton->slotCount; i < n; i++) {
|
||||
Slot* slot = skeleton->slots[i];
|
||||
if (!slot->attachment || slot->attachment->type != ATTACHMENT_REGION) continue;
|
||||
RegionAttachment* attachment = (RegionAttachment*)slot->attachment;
|
||||
RegionAttachment_updateQuad(attachment, slot, &quad);
|
||||
points[0] = ccp(quad.bl.vertices.x, quad.bl.vertices.y);
|
||||
points[1] = ccp(quad.br.vertices.x, quad.br.vertices.y);
|
||||
points[2] = ccp(quad.tr.vertices.x, quad.tr.vertices.y);
|
||||
points[3] = ccp(quad.tl.vertices.x, quad.tl.vertices.y);
|
||||
ccDrawPoly(points, 4, true);
|
||||
}
|
||||
}
|
||||
if (debugBones) {
|
||||
// Bone lengths.
|
||||
glLineWidth(2);
|
||||
ccDrawColor4B(255, 0, 0, 255);
|
||||
for (int i = 0, n = skeleton->boneCount; i < n; i++) {
|
||||
Bone *bone = skeleton->bones[i];
|
||||
float x = bone->data->length * bone->m00 + bone->worldX;
|
||||
float y = bone->data->length * bone->m10 + bone->worldY;
|
||||
ccDrawLine(ccp(bone->worldX, bone->worldY), ccp(x, y));
|
||||
}
|
||||
// Bone origins.
|
||||
ccPointSize(4);
|
||||
ccDrawColor4B(0, 0, 255, 255); // Root bone is blue.
|
||||
for (int i = 0, n = skeleton->boneCount; i < n; i++) {
|
||||
Bone *bone = skeleton->bones[i];
|
||||
ccDrawPoint(ccp(bone->worldX, bone->worldY));
|
||||
if (i == 0) ccDrawColor4B(0, 255, 0, 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CCRect CCSkeleton::boundingBox () {
|
||||
float minX = FLT_MAX, minY = FLT_MAX, maxX = FLT_MIN, maxY = FLT_MIN;
|
||||
float scaleX = getScaleX();
|
||||
float scaleY = getScaleY();
|
||||
ccV3F_C4B_T2F_Quad quad;
|
||||
for (int i = 0; i < skeleton->slotCount; ++i) {
|
||||
Slot* slot = skeleton->slots[i];
|
||||
if (!slot->attachment || slot->attachment->type != ATTACHMENT_REGION) continue;
|
||||
RegionAttachment* attachment = (RegionAttachment*)slot->attachment;
|
||||
RegionAttachment_updateQuad(attachment, slot, &quad);
|
||||
minX = min(minX, quad.bl.vertices.x * scaleX);
|
||||
minY = min(minY, quad.bl.vertices.y * scaleY);
|
||||
maxX = max(maxX, quad.bl.vertices.x * scaleX);
|
||||
maxY = max(maxY, quad.bl.vertices.y * scaleY);
|
||||
minX = min(minX, quad.br.vertices.x * scaleX);
|
||||
minY = min(minY, quad.br.vertices.y * scaleY);
|
||||
maxX = max(maxX, quad.br.vertices.x * scaleX);
|
||||
maxY = max(maxY, quad.br.vertices.y * scaleY);
|
||||
minX = min(minX, quad.tl.vertices.x * scaleX);
|
||||
minY = min(minY, quad.tl.vertices.y * scaleY);
|
||||
maxX = max(maxX, quad.tl.vertices.x * scaleX);
|
||||
maxY = max(maxY, quad.tl.vertices.y * scaleY);
|
||||
minX = min(minX, quad.tr.vertices.x * scaleX);
|
||||
minY = min(minY, quad.tr.vertices.y * scaleY);
|
||||
maxX = max(maxX, quad.tr.vertices.x * scaleX);
|
||||
maxY = max(maxY, quad.tr.vertices.y * scaleY);
|
||||
}
|
||||
CCPoint position = getPosition();
|
||||
minX = position.x + minX;
|
||||
minY = position.y + minY;
|
||||
maxX = position.x + maxX;
|
||||
maxY = position.y + maxY;
|
||||
return CCRectMake(minX, minY, maxX - minX, maxY - minY);
|
||||
}
|
||||
|
||||
// CCBlendProtocol
|
||||
|
||||
ccBlendFunc CCSkeleton::getBlendFunc () {
|
||||
return blendFunc;
|
||||
}
|
||||
|
||||
void CCSkeleton::setBlendFunc (ccBlendFunc blendFunc) {
|
||||
this->blendFunc = blendFunc;
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
|
@ -0,0 +1,68 @@
|
|||
/*******************************************************************************
|
||||
* 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_COCOS2DX_H_
|
||||
#define SPINE_COCOS2DX_H_
|
||||
|
||||
#include <spine/spine.h>
|
||||
#include "cocos2d.h"
|
||||
|
||||
namespace cocos2d { namespace extension {
|
||||
|
||||
class CCSkeleton: public cocos2d::CCNodeRGBA, public cocos2d::CCBlendProtocol {
|
||||
private:
|
||||
bool ownsSkeleton;
|
||||
bool ownsStateData;
|
||||
Atlas* atlas;
|
||||
|
||||
public:
|
||||
Skeleton* const skeleton;
|
||||
AnimationState* const state;
|
||||
float timeScale;
|
||||
bool debugSlots;
|
||||
bool debugBones;
|
||||
|
||||
static CCSkeleton* createWithFile (const char* skeletonDataFile, Atlas* atlas, float scale = 1);
|
||||
static CCSkeleton* createWithFile (const char* skeletonDataFile, const char* atlasFile, float scale = 1);
|
||||
static CCSkeleton* createWithData (SkeletonData* skeletonData, AnimationStateData* stateData = 0);
|
||||
|
||||
CCSkeleton (SkeletonData* skeletonData, AnimationStateData* stateData = 0);
|
||||
virtual ~CCSkeleton ();
|
||||
|
||||
virtual void update (float deltaTime);
|
||||
virtual void draw ();
|
||||
virtual cocos2d::CCRect boundingBox ();
|
||||
|
||||
// CCBlendProtocol
|
||||
CC_PROPERTY(cocos2d::ccBlendFunc, blendFunc, BlendFunc);
|
||||
};
|
||||
|
||||
/**/
|
||||
|
||||
void RegionAttachment_updateQuad (RegionAttachment* self, Slot* slot, cocos2d::ccV3F_C4B_T2F_Quad* quad);
|
||||
|
||||
}} // namespace cocos2d { namespace extension {
|
||||
|
||||
#endif /* SPINE_COCOS2DX_H_ */
|
|
@ -0,0 +1,46 @@
|
|||
/*******************************************************************************
|
||||
* 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/Animation.h>
|
||||
#include <spine/AnimationState.h>
|
||||
#include <spine/AnimationStateData.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>
|
||||
#include <spine/Skeleton.h>
|
||||
#include <spine/SkeletonData.h>
|
||||
#include <spine/SkeletonJson.h>
|
||||
#include <spine/Skin.h>
|
||||
#include <spine/Slot.h>
|
||||
#include <spine/SlotData.h>
|
||||
|
||||
#endif /* SPINE_SPINE_H_ */
|
|
@ -0,0 +1,78 @@
|
|||
/*******************************************************************************
|
||||
* 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 "SpineTest.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string.h>
|
||||
|
||||
using namespace cocos2d;
|
||||
using namespace cocos2d::extension;
|
||||
using namespace std;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
// SpineTestScene
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
void SpineTestScene::runThisTest()
|
||||
{
|
||||
CCLayer* pLayer = SpineTestLayer::create();
|
||||
addChild(pLayer);
|
||||
|
||||
CCDirector::sharedDirector()->replaceScene(this);
|
||||
}
|
||||
|
||||
bool SpineTestLayer::init () {
|
||||
if (!CCLayer::init()) return false;
|
||||
|
||||
skeletonNode = CCSkeleton::createWithFile("spine/spineboy.json", "spine/spineboy.atlas");
|
||||
AnimationStateData_setMixByName(skeletonNode->state->data, "walk", "jump", 0.4f);
|
||||
AnimationStateData_setMixByName(skeletonNode->state->data, "jump", "walk", 0.4f);
|
||||
AnimationState_setAnimationByName(skeletonNode->state, "walk", true);
|
||||
skeletonNode->timeScale = 0.3f;
|
||||
skeletonNode->debugBones = true;
|
||||
|
||||
skeletonNode->runAction(CCRepeatForever::create(CCSequence::create(CCFadeOut::create(1),
|
||||
CCFadeIn::create(1),
|
||||
CCDelayTime::create(5),
|
||||
NULL)));
|
||||
|
||||
CCSize windowSize = CCDirector::sharedDirector()->getWinSize();
|
||||
skeletonNode->setPosition(ccp(windowSize.width / 2, 20));
|
||||
addChild(skeletonNode);
|
||||
|
||||
scheduleUpdate();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SpineTestLayer::update (float deltaTime) {
|
||||
if (skeletonNode->state->loop) {
|
||||
if (skeletonNode->state->time > 2) AnimationState_setAnimationByName(skeletonNode->state, "jump", false);
|
||||
} else {
|
||||
if (skeletonNode->state->time > 1) AnimationState_setAnimationByName(skeletonNode->state, "walk", true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*******************************************************************************
|
||||
* 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 _SPINETEST_H_
|
||||
#define _SPINETEST_H_
|
||||
|
||||
#include "cocos2d.h"
|
||||
#include "../testBasic.h"
|
||||
#include <spine/spine-cocos2dx.h>
|
||||
|
||||
class SpineTestScene : public TestScene
|
||||
{
|
||||
public:
|
||||
virtual void runThisTest();
|
||||
};
|
||||
|
||||
class SpineTestLayer: public cocos2d::CCLayer {
|
||||
private:
|
||||
cocos2d::extension::CCSkeleton* skeletonNode;
|
||||
|
||||
public:
|
||||
|
||||
virtual bool init ();
|
||||
virtual void update (float deltaTime);
|
||||
|
||||
CREATE_FUNC (SpineTestLayer);
|
||||
};
|
||||
|
||||
#endif // _EXAMPLELAYER_H_
|
|
@ -119,6 +119,9 @@ static TestScene* CreateTestScene(int nIdx)
|
|||
case TEST_FILEUTILS:
|
||||
pScene = new FileUtilsTestScene();
|
||||
break;
|
||||
case TEST_SPINE:
|
||||
pScene = new SpineTestScene();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "ChipmunkTest/ChipmunkTest.h"
|
||||
#endif
|
||||
#include "FileUtilsTest/FileUtilsTest.h"
|
||||
#include "SpineTest/SpineTest.h"
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -109,6 +110,7 @@ enum
|
|||
TEST_CLIPPINGNODE,
|
||||
#endif
|
||||
TEST_FILEUTILS,
|
||||
TEST_SPINE,
|
||||
TESTS_COUNT,
|
||||
};
|
||||
|
||||
|
@ -165,7 +167,8 @@ const std::string g_aTestNames[TESTS_COUNT] = {
|
|||
#if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE)
|
||||
"ClippingNodeTest",
|
||||
#endif
|
||||
"FileUtilsTest"
|
||||
"FileUtilsTest",
|
||||
"SpineTest"
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
c22eca8f608170bab4ceb0086e48999fb2e3d32b
|
|
@ -1 +1 @@
|
|||
7bd1abbd3c1270c95196be7965f911815e7ba4c4
|
||||
655a6ce855dabb133120b19537ed3879b2fc8194
|
Loading…
Reference in New Issue