C runtime works!

This commit is contained in:
NathanSweet 2013-03-30 17:52:19 +01:00
parent 9a0085c36b
commit 6765ec4235
9 changed files with 123 additions and 110 deletions

View File

@ -53,7 +53,7 @@ float CurveTimeline_getCurvePercent (CurveTimeline* timeline, int frameIndex, fl
typedef struct BaseTimeline { typedef struct BaseTimeline {
CurveTimeline super; CurveTimeline super;
int const frameCount; int const framesLength;
float* const frames; /* time, angle, ... for rotate. time, x, y, ... for translate and scale. */ float* const frames; /* time, angle, ... for rotate. time, x, y, ... for translate and scale. */
int boneIndex; int boneIndex;
} RotateTimeline; } RotateTimeline;
@ -82,7 +82,7 @@ void ScaleTimeline_setFrame (ScaleTimeline* timeline, int frameIndex, float time
typedef struct { typedef struct {
CurveTimeline super; CurveTimeline super;
int const frameCount; int const framesLength;
float* const frames; /* time, r, g, b, a, ... */ float* const frames; /* time, r, g, b, a, ... */
int slotIndex; int slotIndex;
} ColorTimeline; } ColorTimeline;
@ -95,7 +95,7 @@ void ColorTimeline_setFrame (ColorTimeline* timeline, int frameIndex, float time
typedef struct { typedef struct {
Timeline super; Timeline super;
int const frameCount; int const framesLength;
float* const frames; /* time, ... */ float* const frames; /* time, ... */
int slotIndex; int slotIndex;
const char** const attachmentNames; const char** const attachmentNames;

View File

@ -6,6 +6,8 @@ namespace spine {
extern "C" { extern "C" {
#endif #endif
struct Slot;
typedef enum { typedef enum {
ATTACHMENT_REGION, ATTACHMENT_REGION_SEQUENCE ATTACHMENT_REGION, ATTACHMENT_REGION_SEQUENCE
} AttachmentType; } AttachmentType;
@ -15,11 +17,14 @@ struct Attachment {
const char* const name; const char* const name;
int type; int type;
void (*_draw) (Attachment* attachment, struct Slot* slot);
void (*_dispose) (Attachment* attachment); void (*_dispose) (Attachment* attachment);
}; };
void Attachment_dispose (Attachment* attachment); void Attachment_dispose (Attachment* attachment);
void Attachment_draw (Attachment* attachment, struct Slot* slot);
#ifdef __cplusplus #ifdef __cplusplus
} }
} }

View File

@ -12,7 +12,7 @@ extern "C" {
struct Skeleton; struct Skeleton;
typedef struct { typedef struct Slot {
SlotData* const data; SlotData* const data;
struct Skeleton* const skeleton; struct Skeleton* const skeleton;
Bone* const bone; Bone* const bone;

View File

@ -165,8 +165,8 @@ struct BaseTimeline* _BaseTimeline_create (int frameCount, int frameSize) {
_CurveTimeline_init(&self->super, frameCount); _CurveTimeline_init(&self->super, frameCount);
((Timeline*)self)->_dispose = _BaseTimeline_dispose; ((Timeline*)self)->_dispose = _BaseTimeline_dispose;
CAST(int, self->frameCount) = frameCount; CAST(int, self->framesLength) = frameCount * frameSize;
CAST(float*, self->frames) = CALLOC(float, frameCount * frameSize) CAST(float*, self->frames) = CALLOC(float, self->framesLength)
return self; return self;
} }
@ -183,8 +183,8 @@ void _RotateTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float
Bone *bone = skeleton->bones[self->boneIndex]; Bone *bone = skeleton->bones[self->boneIndex];
if (time >= self->frames[self->frameCount - 2]) { /* Time is after last frame. */ if (time >= self->frames[self->framesLength - 2]) { /* Time is after last frame. */
float amount = bone->data->rotation + self->frames[self->frameCount - 1] - bone->rotation; float amount = bone->data->rotation + self->frames[self->framesLength - 1] - bone->rotation;
while (amount > 180) while (amount > 180)
amount -= 360; amount -= 360;
while (amount < -180) while (amount < -180)
@ -194,7 +194,7 @@ void _RotateTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float
} }
/* Interpolate between the last frame and the current frame. */ /* Interpolate between the last frame and the current frame. */
int frameIndex = binarySearch(self->frames, self->frameCount, time, 2); int frameIndex = binarySearch(self->frames, self->framesLength, time, 2);
float lastFrameValue = self->frames[frameIndex - 1]; float lastFrameValue = self->frames[frameIndex - 1];
float frameTime = self->frames[frameIndex]; float frameTime = self->frames[frameIndex];
float percent = 1 - (time - frameTime) / (self->frames[frameIndex + ROTATE_LAST_FRAME_TIME] - frameTime); float percent = 1 - (time - frameTime) / (self->frames[frameIndex + ROTATE_LAST_FRAME_TIME] - frameTime);
@ -238,14 +238,14 @@ void _TranslateTimeline_apply (const Timeline* timeline, Skeleton* skeleton, flo
Bone *bone = skeleton->bones[self->boneIndex]; Bone *bone = skeleton->bones[self->boneIndex];
if (time >= self->frames[self->frameCount - 3]) { /* Time is after last frame. */ if (time >= self->frames[self->framesLength - 3]) { /* Time is after last frame. */
bone->x += (bone->data->x + self->frames[self->frameCount - 2] - bone->x) * alpha; bone->x += (bone->data->x + self->frames[self->framesLength - 2] - bone->x) * alpha;
bone->y += (bone->data->y + self->frames[self->frameCount - 1] - bone->y) * alpha; bone->y += (bone->data->y + self->frames[self->framesLength - 1] - bone->y) * alpha;
return; return;
} }
/* Interpolate between the last frame and the current frame. */ /* Interpolate between the last frame and the current frame. */
int frameIndex = binarySearch(self->frames, self->frameCount, time, 3); int frameIndex = binarySearch(self->frames, self->framesLength, time, 3);
float lastFrameX = self->frames[frameIndex - 2]; float lastFrameX = self->frames[frameIndex - 2];
float lastFrameY = self->frames[frameIndex - 1]; float lastFrameY = self->frames[frameIndex - 1];
float frameTime = self->frames[frameIndex]; float frameTime = self->frames[frameIndex];
@ -279,14 +279,14 @@ void _ScaleTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float t
if (time < self->frames[0]) return; /* Time is before first frame. */ if (time < self->frames[0]) return; /* Time is before first frame. */
Bone *bone = skeleton->bones[self->boneIndex]; Bone *bone = skeleton->bones[self->boneIndex];
if (time >= self->frames[self->frameCount - 3]) { /* Time is after last frame. */ if (time >= self->frames[self->framesLength - 3]) { /* Time is after last frame. */
bone->scaleX += (bone->data->scaleX - 1 + self->frames[self->frameCount - 2] - bone->scaleX) * alpha; bone->scaleX += (bone->data->scaleX - 1 + self->frames[self->framesLength - 2] - bone->scaleX) * alpha;
bone->scaleY += (bone->data->scaleY - 1 + self->frames[self->frameCount - 1] - bone->scaleY) * alpha; bone->scaleY += (bone->data->scaleY - 1 + self->frames[self->framesLength - 1] - bone->scaleY) * alpha;
return; return;
} }
/* Interpolate between the last frame and the current frame. */ /* Interpolate between the last frame and the current frame. */
int frameIndex = binarySearch(self->frames, self->frameCount, time, 3); int frameIndex = binarySearch(self->frames, self->framesLength, time, 3);
float lastFrameX = self->frames[frameIndex - 2]; float lastFrameX = self->frames[frameIndex - 2];
float lastFrameY = self->frames[frameIndex - 1]; float lastFrameY = self->frames[frameIndex - 1];
float frameTime = self->frames[frameIndex]; float frameTime = self->frames[frameIndex];
@ -324,8 +324,8 @@ void _ColorTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float t
Slot *slot = skeleton->slots[self->slotIndex]; Slot *slot = skeleton->slots[self->slotIndex];
if (time >= self->frames[self->frameCount - 5]) { /* Time is after last frame. */ if (time >= self->frames[self->framesLength - 5]) { /* Time is after last frame. */
int i = self->frameCount - 1; int i = self->framesLength - 1;
slot->r = self->frames[i - 3]; slot->r = self->frames[i - 3];
slot->g = self->frames[i - 2]; slot->g = self->frames[i - 2];
slot->b = self->frames[i - 1]; slot->b = self->frames[i - 1];
@ -334,7 +334,7 @@ void _ColorTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float t
} }
/* Interpolate between the last frame and the current frame. */ /* Interpolate between the last frame and the current frame. */
int frameIndex = binarySearch(self->frames, self->frameCount, time, 5); int frameIndex = binarySearch(self->frames, self->framesLength, time, 5);
float lastFrameR = self->frames[frameIndex - 4]; float lastFrameR = self->frames[frameIndex - 4];
float lastFrameG = self->frames[frameIndex - 3]; float lastFrameG = self->frames[frameIndex - 3];
float lastFrameB = self->frames[frameIndex - 2]; float lastFrameB = self->frames[frameIndex - 2];
@ -383,10 +383,10 @@ void _AttachmentTimeline_apply (const Timeline* timeline, Skeleton* skeleton, fl
if (time < self->frames[0]) return; /* Time is before first frame. */ if (time < self->frames[0]) return; /* Time is before first frame. */
int frameIndex; int frameIndex;
if (time >= self->frames[self->frameCount - 1]) /* Time is after last frame. */ if (time >= self->frames[self->framesLength - 1]) /* Time is after last frame. */
frameIndex = self->frameCount - 1; frameIndex = self->framesLength - 1;
else else
frameIndex = binarySearch(self->frames, self->frameCount, time, 1) - 1; frameIndex = binarySearch(self->frames, self->framesLength, time, 1) - 1;
const char* attachmentName = self->attachmentNames[frameIndex]; const char* attachmentName = self->attachmentNames[frameIndex];
Slot_setAttachment(skeleton->slots[self->slotIndex], Slot_setAttachment(skeleton->slots[self->slotIndex],
@ -398,7 +398,7 @@ void _AttachmentTimeline_dispose (Timeline* timeline) {
AttachmentTimeline* self = (AttachmentTimeline*)timeline; AttachmentTimeline* self = (AttachmentTimeline*)timeline;
int i; int i;
for (i = 0; i < self->frameCount; ++i) for (i = 0; i < self->framesLength; ++i)
FREE(self->attachmentNames[i]) FREE(self->attachmentNames[i])
FREE(self->attachmentNames) FREE(self->attachmentNames)
@ -412,7 +412,7 @@ AttachmentTimeline* AttachmentTimeline_create (int frameCount) {
((Timeline*)self)->_apply = _AttachmentTimeline_apply; ((Timeline*)self)->_apply = _AttachmentTimeline_apply;
CAST(char**, self->attachmentNames) = CALLOC(char*, frameCount) CAST(char**, self->attachmentNames) = CALLOC(char*, frameCount)
CAST(int, self->frameCount) = frameCount; CAST(int, self->framesLength) = frameCount;
CAST(float*, self->frames) = CALLOC(float, frameCount) CAST(float*, self->frames) = CALLOC(float, frameCount)
return self; return self;

View File

@ -1,5 +1,6 @@
#include <spine/Attachment.h> #include <spine/Attachment.h>
#include <spine/util.h> #include <spine/util.h>
#include <spine/Slot.h>
void _Attachment_init (Attachment* self, const char* name, int type) { void _Attachment_init (Attachment* self, const char* name, int type) {
MALLOC_STR(self->name, name); MALLOC_STR(self->name, name);
@ -14,3 +15,7 @@ void _Attachment_deinit (Attachment* self) {
void Attachment_dispose (Attachment* self) { void Attachment_dispose (Attachment* self) {
self->_dispose(self); self->_dispose(self);
} }
void Attachment_draw (Attachment* self, Slot* slot) {
self->_draw(self, slot);
}

View File

@ -57,25 +57,25 @@ typedef struct Json {
} Json; } Json;
/* Supply a block of JSON, and this returns a Json object you can interrogate. Call Json_dispose when finished. */ /* Supply a block of JSON, and this returns a Json object you can interrogate. Call Json_dispose when finished. */
extern Json* Json_create (const char* value); Json* Json_create (const char* value);
/* Delete a Json entity and all subentities. */ /* Delete a Json entity and all subentities. */
extern void Json_dispose (Json* json); void Json_dispose (Json* json);
/* Returns the number of items in an array (or object). */ /* Returns the number of items in an array (or object). */
extern int Json_getSize (Json* json); int Json_getSize (Json* json);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ /* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
extern Json* Json_getItemAt (Json* json, int item); Json* Json_getItemAt (Json* json, int item);
/* Get item "string" from object. Case insensitive. */ /* Get item "string" from object. Case insensitive. */
extern Json* Json_getItem (Json* json, const char* string); Json* Json_getItem (Json* json, const char* string);
extern const char* Json_getString (Json* json, const char* name, const char* defaultValue); const char* Json_getString (Json* json, const char* name, const char* defaultValue);
extern float Json_getFloat (Json* json, const char* name, float defaultValue); float Json_getFloat (Json* json, const char* name, float defaultValue);
extern int Json_getInt (Json* json, const char* name, int 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. */ /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when Json_create() returns 0. 0 when Json_create() succeeds. */
extern const char* Json_getError (void); const char* Json_getError (void);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -41,6 +41,11 @@ void _Skeleton_init (Skeleton* self, SkeletonData* data) {
self->drawOrder = MALLOC(Slot*, self->slotCount) self->drawOrder = MALLOC(Slot*, self->slotCount)
memcpy(self->drawOrder, self->slots, sizeof(Slot*) * self->slotCount); memcpy(self->drawOrder, self->slots, sizeof(Slot*) * self->slotCount);
self->r = 1;
self->g = 1;
self->b = 1;
self->a = 1;
} }
void _Skeleton_deinit (Skeleton* self) { void _Skeleton_deinit (Skeleton* self) {

View File

@ -31,46 +31,41 @@ using namespace std;
using namespace spine; using namespace spine;
int main () { int main () {
Atlas* atlas = Atlas_readAtlasFile("../data/spineboy.atlas");
SkeletonJson* json = SkeletonJson_create(atlas);
SkeletonData *skeletonData = SkeletonJson_readSkeletonDataFile(json, "../data/spineboy-skeleton.json");
Animation* animation = SkeletonJson_readAnimationFile(json, "../data/spineboy-walk.json", skeletonData);
SkeletonJson_dispose(json);
try { Skeleton* skeleton = Skeleton_create(skeletonData);
Atlas* atlas = Atlas_readAtlasFile("../data/spineboy.atlas"); skeleton->flipX = false;
SkeletonJson* json = SkeletonJson_create(atlas); skeleton->flipY = false;
SkeletonData *skeletonData = SkeletonJson_readSkeletonDataFile(json, "../data/spineboy-skeleton.json"); Skeleton_setToBindPose(skeleton);
Animation* animation = SkeletonJson_readAnimationFile(json, "../data/spineboy-walk.json", skeletonData); Skeleton_getRootBone(skeleton)->x = 320;
SkeletonJson_dispose(json); Skeleton_getRootBone(skeleton)->y = 420;
Skeleton_updateWorldTransform(skeleton);
Skeleton* skeleton = Skeleton_create(skeletonData); sf::RenderWindow window(sf::VideoMode(640, 480), "Spine SFML");
skeleton->flipX = false; window.setFramerateLimit(60);
skeleton->flipY = false; sf::Event event;
Skeleton_setToBindPose(skeleton); sf::Clock deltaClock;
Skeleton_getRootBone(skeleton)->x = 320; float animationTime = 0;
Skeleton_getRootBone(skeleton)->y = 420; while (window.isOpen()) {
while (window.pollEvent(event))
if (event.type == sf::Event::Closed) window.close();
window.clear();
window.draw(Skeleton_getDrawable(skeleton));
window.display();
float delta = deltaClock.getElapsedTime().asSeconds();
deltaClock.restart();
animationTime += delta;
Animation_apply(animation, skeleton, animationTime, true);
Skeleton_updateWorldTransform(skeleton); Skeleton_updateWorldTransform(skeleton);
sf::RenderWindow window(sf::VideoMode(640, 480), "Spine SFML");
window.setFramerateLimit(60);
sf::Event event;
sf::Clock deltaClock;
float animationTime = 0;
while (window.isOpen()) {
while (window.pollEvent(event))
if (event.type == sf::Event::Closed) window.close();
window.clear();
window.draw(Skeleton_getDrawable(skeleton));
window.display();
float delta = deltaClock.getElapsedTime().asSeconds();
deltaClock.restart();
animationTime += delta;
Animation_apply(animation, skeleton, animationTime, true);
Skeleton_updateWorldTransform(skeleton);
}
Skeleton_dispose(skeleton);
SkeletonData_dispose(skeletonData);
Atlas_dispose(atlas);
} catch (exception &ex) {
cout << ex.what() << endl << flush;
} }
Skeleton_dispose(skeleton);
SkeletonData_dispose(skeletonData);
Atlas_dispose(atlas);
} }

View File

@ -49,6 +49,8 @@ void _SfmlSkeleton_dispose (Skeleton* skeleton) {
} }
Skeleton* Skeleton_create (SkeletonData* data) { Skeleton* Skeleton_create (SkeletonData* data) {
Bone_setYDown(1);
SfmlSkeleton* self = CALLOC(SfmlSkeleton, 1) SfmlSkeleton* self = CALLOC(SfmlSkeleton, 1)
_Skeleton_init(&self->super, data); _Skeleton_init(&self->super, data);
self->super._dispose = _SfmlSkeleton_dispose; self->super._dispose = _SfmlSkeleton_dispose;
@ -63,15 +65,14 @@ SkeletonDrawable& Skeleton_getDrawable (const Skeleton* self) {
return *((SfmlSkeleton*)self)->drawable; return *((SfmlSkeleton*)self)->drawable;
} }
SkeletonDrawable::SkeletonDrawable (Skeleton* self) { SkeletonDrawable::SkeletonDrawable (Skeleton* self) :
skeleton = (SfmlSkeleton*)self; skeleton((SfmlSkeleton*)self) {
} }
void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const { void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
skeleton->vertexArray->clear(); skeleton->vertexArray->clear();
for (int i = 0; i < skeleton->super.slotCount; ++i) for (int i = 0; i < skeleton->super.slotCount; ++i)
if (skeleton->super.slots[i]->attachment) ; //skeleton->slots[i]->attachment->draw(slots[i]); if (skeleton->super.slots[i]->attachment) Attachment_draw(skeleton->super.slots[i]->attachment, skeleton->super.slots[i]);
// BOZO - Draw the slots!
states.texture = skeleton->texture; states.texture = skeleton->texture;
target.draw(*skeleton->vertexArray, states); target.draw(*skeleton->vertexArray, states);
} }
@ -83,40 +84,8 @@ void _SfmlRegionAttachment_dispose (Attachment* self) {
FREE(self) FREE(self)
} }
RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) { void _SfmlRegionAttachment_draw (Attachment* attachment, Slot* slot) {
SfmlRegionAttachment* self = CALLOC(SfmlRegionAttachment, 1) SfmlRegionAttachment* self = (SfmlRegionAttachment*)attachment;
_RegionAttachment_init(&self->super, name);
self->super.super._dispose = _SfmlRegionAttachment_dispose;
self->texture = ((SfmlAtlasPage*)region->page)->texture;
int u = region->x;
int u2 = u + region->width;
int v = region->y;
int v2 = v + region->height;
if (region->rotate) {
self->vertices[1].texCoords.x = u;
self->vertices[1].texCoords.y = v2;
self->vertices[2].texCoords.x = u;
self->vertices[2].texCoords.y = v;
self->vertices[3].texCoords.x = u2;
self->vertices[3].texCoords.y = v;
self->vertices[0].texCoords.x = u2;
self->vertices[0].texCoords.y = v2;
} else {
self->vertices[0].texCoords.x = u;
self->vertices[0].texCoords.y = v2;
self->vertices[1].texCoords.x = u;
self->vertices[1].texCoords.y = v;
self->vertices[2].texCoords.x = u2;
self->vertices[2].texCoords.y = v;
self->vertices[3].texCoords.x = u2;
self->vertices[3].texCoords.y = v2;
}
return &self->super;
}
void _RegionAttachment_draw (SfmlRegionAttachment* self, Slot* slot) {
SfmlSkeleton* skeleton = (SfmlSkeleton*)slot->skeleton; SfmlSkeleton* skeleton = (SfmlSkeleton*)slot->skeleton;
Uint8 r = skeleton->super.r * slot->r * 255; Uint8 r = skeleton->super.r * slot->r * 255;
Uint8 g = skeleton->super.g * slot->g * 255; Uint8 g = skeleton->super.g * slot->g * 255;
@ -159,4 +128,38 @@ void _RegionAttachment_draw (SfmlRegionAttachment* self, Slot* slot) {
skeleton->vertexArray->append(vertices[3]); skeleton->vertexArray->append(vertices[3]);
} }
RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) {
SfmlRegionAttachment* self = CALLOC(SfmlRegionAttachment, 1)
_RegionAttachment_init(&self->super, name);
self->super.super._dispose = _SfmlRegionAttachment_dispose;
self->super.super._draw = _SfmlRegionAttachment_draw;
self->texture = ((SfmlAtlasPage*)region->page)->texture;
int u = region->x;
int u2 = u + region->width;
int v = region->y;
int v2 = v + region->height;
if (region->rotate) {
self->vertices[1].texCoords.x = u;
self->vertices[1].texCoords.y = v2;
self->vertices[2].texCoords.x = u;
self->vertices[2].texCoords.y = v;
self->vertices[3].texCoords.x = u2;
self->vertices[3].texCoords.y = v;
self->vertices[0].texCoords.x = u2;
self->vertices[0].texCoords.y = v2;
} else {
self->vertices[0].texCoords.x = u;
self->vertices[0].texCoords.y = v2;
self->vertices[1].texCoords.x = u;
self->vertices[1].texCoords.y = v;
self->vertices[2].texCoords.x = u2;
self->vertices[2].texCoords.y = v;
self->vertices[3].texCoords.x = u2;
self->vertices[3].texCoords.y = v2;
}
return &self->super;
}
} }