diff --git a/spine-cpp/spine-cpp/include/spine/BoneData.h b/spine-cpp/spine-cpp/include/spine/BoneData.h index 1a7fcc2e9..25530985e 100644 --- a/spine-cpp/spine-cpp/include/spine/BoneData.h +++ b/spine-cpp/spine-cpp/include/spine/BoneData.h @@ -39,6 +39,7 @@ namespace Spine { class BoneData { + friend class SkeletonBinary; friend class AnimationState; friend class RotateTimeline; diff --git a/spine-cpp/spine-cpp/include/spine/Extension.h b/spine-cpp/spine-cpp/include/spine/Extension.h index e58f44991..3595d365f 100644 --- a/spine-cpp/spine-cpp/include/spine/Extension.h +++ b/spine-cpp/spine-cpp/include/spine/Extension.h @@ -37,6 +37,7 @@ /* All allocation uses these. */ #define MALLOC(TYPE,COUNT) ((TYPE*)SPINE_EXTENSION->spineAlloc(sizeof(TYPE) * (COUNT), __FILE__, __LINE__)) +#define CALLOC(TYPE,COUNT) ((TYPE*)SPINE_EXTENSION->spineCalloc(COUNT, sizeof(TYPE), __FILE__, __LINE__)) #define NEW(TYPE) ((TYPE*)SPINE_EXTENSION->spineAlloc(sizeof(TYPE), __FILE__, __LINE__)) #define REALLOC(PTR,TYPE,COUNT) ((TYPE*)SPINE_EXTENSION->spineRealloc(PTR, sizeof(TYPE) * (COUNT), __FILE__, __LINE__)) @@ -60,6 +61,8 @@ namespace Spine /// Implement this function to use your own memory allocator virtual void* spineAlloc(size_t size, const char* file, int line) = 0; + virtual void* spineCalloc(size_t num, size_t size, const char* file, int line) = 0; + virtual void* spineRealloc(void* ptr, size_t size, const char* file, int line) = 0; /// If you provide a spineAllocFunc, you should also provide a spineFreeFunc @@ -71,7 +74,7 @@ namespace Spine SpineExtension(); private: - static SpineExtension* _spineExtension; + static SpineExtension* _instance; }; class DefaultSpineExtension : public SpineExtension @@ -83,6 +86,8 @@ namespace Spine virtual void* spineAlloc(size_t size, const char* file, int line); + virtual void* spineCalloc(size_t num, size_t size, const char* file, int line); + virtual void* spineRealloc(void* ptr, size_t size, const char* file, int line); virtual void spineFree(void* mem); diff --git a/spine-cpp/spine-cpp/include/spine/LinkedMesh.h b/spine-cpp/spine-cpp/include/spine/LinkedMesh.h new file mode 100644 index 000000000..38482821e --- /dev/null +++ b/spine-cpp/spine-cpp/include/spine/LinkedMesh.h @@ -0,0 +1,53 @@ +/****************************************************************************** + * Spine Runtimes Software License v2.5 + * + * Copyright (c) 2013-2016, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable, and + * non-transferable license to use, install, execute, and perform the Spine + * Runtimes software and derivative works solely for personal or internal + * use. Without the written permission of Esoteric Software (see Section 2 of + * the Spine Software License Agreement), you may not (a) modify, translate, + * adapt, or develop new applications using the Spine Runtimes or otherwise + * create derivative works or improvements of the Spine Runtimes or (b) remove, + * delete, alter, or obscure any trademarks or any copyright, trademark, patent, + * or other intellectual property or proprietary rights notices on or in the + * Software, including any copy thereof. Redistributions in binary or source + * form must include this license and terms. + * + * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF + * USE, DATA, OR PROFITS) 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_LinkedMesh_h +#define Spine_LinkedMesh_h + +#include + +namespace Spine +{ + class MeshAttachment; + + class LinkedMesh + { + public: + LinkedMesh(MeshAttachment* mesh, std::string skin, int slotIndex, std::string parent); + + private: + MeshAttachment* _mesh; + std::string _skin; + int _slotIndex; + std::string _parent; + }; +} + +#endif /* Spine_LinkedMesh_h */ diff --git a/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h b/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h index cbb6b01c1..29d727ac8 100644 --- a/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h +++ b/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h @@ -31,9 +31,86 @@ #ifndef Spine_SkeletonBinary_h #define Spine_SkeletonBinary_h +#include +#include + +#include + namespace Spine { - // TODO + class SkeletonData; + class Atlas; + class AttachmentLoader; + class LinkedMesh; + + class SkeletonBinary + { + public: + static const int BONE_ROTATE; + static const int BONE_TRANSLATE; + static const int BONE_SCALE; + static const int BONE_SHEAR; + + static const int SLOT_ATTACHMENT; + static const int SLOT_COLOR; + static const int SLOT_TWO_COLOR; + + static const int PATH_POSITION; + static const int PATH_SPACING; + static const int PATH_MIX; + + static const int CURVE_LINEAR; + static const int CURVE_STEPPED; + static const int CURVE_BEZIER; + + static const TransformMode TRANSFORM_MODE_VALUES[5]; + + SkeletonBinary(Vector& atlasArray); + + SkeletonBinary(AttachmentLoader* attachmentLoader); + + ~SkeletonBinary(); + + SkeletonData* readSkeletonData(const unsigned char* binary, const int length); + + SkeletonData* readSkeletonDataFile(const char* path); + + private: + class Vertices + { + public: + Vector _bones; + Vector _vertices; + }; + + struct DataInput + { + const unsigned char* cursor; + const unsigned char* end; + }; + + AttachmentLoader* _attachmentLoader; + Vector _linkedMeshes; + std::string _error; + float _scale; + const bool _ownsLoader; + + void setError(const char* value1, const char* value2); + + char* readString(DataInput* input); + + float readFloat(DataInput* input); + + static unsigned char readByte(DataInput* input); + + static signed char readSByte(DataInput* input); + + static int readBoolean(DataInput* input); + + static int readInt(DataInput* input); + + static int readVarint(DataInput* input, bool optimizePositive); + }; } #endif /* Spine_SkeletonBinary_h */ diff --git a/spine-cpp/spine-cpp/include/spine/SkeletonData.h b/spine-cpp/spine-cpp/include/spine/SkeletonData.h index 44e467edc..96b4584cc 100644 --- a/spine-cpp/spine-cpp/include/spine/SkeletonData.h +++ b/spine-cpp/spine-cpp/include/spine/SkeletonData.h @@ -49,11 +49,15 @@ namespace Spine /// Stores the setup pose and all of the stateless data for a skeleton. class SkeletonData { + friend class SkeletonBinary; + friend class SkeletonJson; friend class Skeleton; public: SkeletonData(); + ~SkeletonData(); + /// Finds a bone by comparing each bone's name. /// It is more efficient to cache the results of this method than to call it multiple times. /// @return May be NULL. diff --git a/spine-cpp/spine-cpp/include/spine/SkeletonJson.h b/spine-cpp/spine-cpp/include/spine/SkeletonJson.h index 1ee1568b5..87139437d 100644 --- a/spine-cpp/spine-cpp/include/spine/SkeletonJson.h +++ b/spine-cpp/spine-cpp/include/spine/SkeletonJson.h @@ -31,9 +31,34 @@ #ifndef Spine_SkeletonJson_h #define Spine_SkeletonJson_h +#include + namespace Spine { - // TODO + class SkeletonData; + class Atlas; + class AttachmentLoader; + class LinkedMesh; + + class SkeletonJson + { + public: + SkeletonJson(Vector& atlasArray); + + SkeletonJson(AttachmentLoader* attachmentLoader); + + ~SkeletonJson(); + + SkeletonData* readSkeletonData(const char* json); + + SkeletonData* readSkeletonDataFile(const char* path); + + private: + AttachmentLoader* _attachmentLoader; + Vector _linkedMeshes; + float _scale; + const bool _ownsLoader; + }; } #endif /* Spine_SkeletonJson_h */ diff --git a/spine-cpp/spine-cpp/src/spine/AnimationState.cpp b/spine-cpp/spine-cpp/src/spine/AnimationState.cpp index bcac04dcb..760e99efb 100644 --- a/spine-cpp/spine-cpp/src/spine/AnimationState.cpp +++ b/spine-cpp/spine-cpp/src/spine/AnimationState.cpp @@ -352,6 +352,7 @@ namespace Spine AnimationState::AnimationState(AnimationStateData& data) : _data(data), _queue(EventQueue::newEventQueue(*this, _trackEntryPool)), + _animationsChanged(false), _onAnimationEventFunc(dummyOnAnimationEventFunc), _timeScale(1) { diff --git a/spine-cpp/spine-cpp/src/spine/Extension.cpp b/spine-cpp/spine-cpp/src/spine/Extension.cpp index 757d44cbe..81c667104 100644 --- a/spine-cpp/spine-cpp/src/spine/Extension.cpp +++ b/spine-cpp/spine-cpp/src/spine/Extension.cpp @@ -35,20 +35,20 @@ namespace Spine { - SpineExtension* SpineExtension::_spineExtension = NULL; + SpineExtension* SpineExtension::_instance = NULL; void SpineExtension::setInstance(SpineExtension* inValue) { - assert(!_spineExtension); + assert(!_instance); - _spineExtension = inValue; + _instance = inValue; } SpineExtension* SpineExtension::getInstance() { - assert(_spineExtension); + assert(_instance); - return _spineExtension; + return _instance; } SpineExtension::~SpineExtension() @@ -94,6 +94,17 @@ namespace Spine return malloc(size); } + void* DefaultSpineExtension::spineCalloc(size_t num, size_t size, const char* file, int line) + { + void* ptr = spineAlloc(num * size, file, line); + if (ptr) + { + memset(ptr, 0, num * size); + } + + return ptr; + } + void* DefaultSpineExtension::spineRealloc(void* ptr, size_t size, const char* file, int line) { return realloc(ptr, size); diff --git a/spine-cpp/spine-cpp/src/spine/LinkedMesh.cpp b/spine-cpp/spine-cpp/src/spine/LinkedMesh.cpp new file mode 100644 index 000000000..a1c25db11 --- /dev/null +++ b/spine-cpp/spine-cpp/src/spine/LinkedMesh.cpp @@ -0,0 +1,45 @@ +/****************************************************************************** +* Spine Runtimes Software License v2.5 +* +* Copyright (c) 2013-2016, Esoteric Software +* All rights reserved. +* +* You are granted a perpetual, non-exclusive, non-sublicensable, and +* non-transferable license to use, install, execute, and perform the Spine +* Runtimes software and derivative works solely for personal or internal +* use. Without the written permission of Esoteric Software (see Section 2 of +* the Spine Software License Agreement), you may not (a) modify, translate, +* adapt, or develop new applications using the Spine Runtimes or otherwise +* create derivative works or improvements of the Spine Runtimes or (b) remove, +* delete, alter, or obscure any trademarks or any copyright, trademark, patent, +* or other intellectual property or proprietary rights notices on or in the +* Software, including any copy thereof. Redistributions in binary or source +* form must include this license and terms. +* +* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF +* USE, DATA, OR PROFITS) 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 + +#include + +namespace Spine +{ + LinkedMesh::LinkedMesh(MeshAttachment* mesh, std::string skin, int slotIndex, std::string parent) : + _mesh(mesh), + _skin(skin), + _slotIndex(slotIndex), + _parent(parent) + { + // Empty + } +} diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp index bb4d2ccfe..ed84c76bc 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp @@ -28,7 +28,456 @@ * POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +#include + +#include +#include +#include +#include + +#include +#include +#include + namespace Spine { - // TODO + const int SkeletonBinary::BONE_ROTATE = 0; + const int SkeletonBinary::BONE_TRANSLATE = 1; + const int SkeletonBinary::BONE_SCALE = 2; + const int SkeletonBinary::BONE_SHEAR = 3; + + const int SkeletonBinary::SLOT_ATTACHMENT = 0; + const int SkeletonBinary::SLOT_COLOR = 1; + const int SkeletonBinary::SLOT_TWO_COLOR = 2; + + const int SkeletonBinary::PATH_POSITION = 0; + const int SkeletonBinary::PATH_SPACING = 1; + const int SkeletonBinary::PATH_MIX = 2; + + const int SkeletonBinary::CURVE_LINEAR = 0; + const int SkeletonBinary::CURVE_STEPPED = 1; + const int SkeletonBinary::CURVE_BEZIER = 2; + + const TransformMode SkeletonBinary::TRANSFORM_MODE_VALUES[5] = { + TransformMode_Normal, + TransformMode_OnlyTranslation, + TransformMode_NoRotationOrReflection, + TransformMode_NoScale, + TransformMode_NoScaleOrReflection + }; + + SkeletonBinary::SkeletonBinary(Vector& atlasArray) : _attachmentLoader(NEW(AtlasAttachmentLoader)), _error(), _scale(1), _ownsLoader(true) + { + new (_attachmentLoader) AtlasAttachmentLoader(atlasArray); + } + + SkeletonBinary::SkeletonBinary(AttachmentLoader* attachmentLoader) : _attachmentLoader(attachmentLoader), _error(), _scale(1), _ownsLoader(false) + { + assert(_attachmentLoader != NULL); + } + + SkeletonBinary::~SkeletonBinary() + { + ContainerUtil::cleanUpVectorOfPointers(_linkedMeshes); + + if (_ownsLoader) + { + DESTROY(AttachmentLoader, _attachmentLoader); + } + } + + SkeletonData* SkeletonBinary::readSkeletonData(const unsigned char* binary, const int length) + { + int i, ii, nonessential; + SkeletonData* skeletonData; + + DataInput* input = CALLOC(DataInput, 1); + input->cursor = binary; + input->end = binary + length; + + _linkedMeshes.clear(); + + skeletonData = NEW(SkeletonData); + new (skeletonData) SkeletonData(); + + char* skeletonData_hash = readString(input); + skeletonData->_hash = std::string(skeletonData_hash); + FREE(skeletonData_hash); + + char* skeletonData_version = readString(input); + skeletonData->_version = std::string(skeletonData_version); + FREE(skeletonData_version); + + skeletonData->_width = readFloat(input); + skeletonData->_height = readFloat(input); + + nonessential = readBoolean(input); + + if (nonessential) + { + /* Skip images path & fps */ + readFloat(input); + FREE(readString(input)); + } + + /* Bones. */ + int bonesCount = readVarint(input, 1); + skeletonData->_bones.reserve(bonesCount); + for (i = 0; i < bonesCount; ++i) + { + BoneData* data; + int mode; + const char* name = readString(input); + BoneData* parent = i == 0 ? 0 : skeletonData->_bones[readVarint(input, 1)]; + + data = NEW(BoneData); + new (data) BoneData(i, std::string(name), parent); + + FREE(name); + + data->_rotation = readFloat(input); + data->_x = readFloat(input) * _scale; + data->_y = readFloat(input) * _scale; + data->_scaleX = readFloat(input); + data->_scaleY = readFloat(input); + data->_shearX = readFloat(input); + data->_shearY = readFloat(input); + data->_length = readFloat(input) * _scale; + + mode = readVarint(input, 1); + switch (mode) + { + case 0: + data->_transformMode = TransformMode_Normal; + break; + case 1: + data->_transformMode = TransformMode_OnlyTranslation; + break; + case 2: + data->_transformMode = TransformMode_NoRotationOrReflection; + break; + case 3: + data->_transformMode = TransformMode_NoScale; + break; + case 4: + data->_transformMode = TransformMode_NoScaleOrReflection; + break; + } + + if (nonessential) + { + /* Skip bone color. */ + readInt(input); + } + + skeletonData->_bones.push_back(data); + } + + /* Slots. */ +// skeletonData->slotsCount = readVarint(input, 1); +// skeletonData->slots = MALLOC(spSlotData*, skeletonData->slotsCount); +// for (i = 0; i < skeletonData->slotsCount; ++i) +// { +// int r, g, b, a; +// const char* slotName = readString(input); +// spBoneData* boneData = skeletonData->bones[readVarint(input, 1)]; +// /* TODO Avoid copying of slotName */ +// spSlotData* slotData = spSlotData_create(i, slotName, boneData); +// FREE(slotName); +// readColor(input, &slotData->color.r, &slotData->color.g, &slotData->color.b, &slotData->color.a); +// r = readByte(input); +// g = readByte(input); +// b = readByte(input); +// a = readByte(input); +// if (!(r == 0xff && g == 0xff && b == 0xff && a == 0xff)) +// { +// slotData->darkColor = spColor_create(); +// spColor_setFromFloats(slotData->darkColor, r / 255.0f, g / 255.0f, b / 255.0f, 1); +// } +// slotData->attachmentName = readString(input); +// slotData->blendMode = (spBlendMode)readVarint(input, 1); +// skeletonData->slots[i] = slotData; +// } +// +// /* IK constraints. */ +// skeletonData->ikConstraintsCount = readVarint(input, 1); +// skeletonData->ikConstraints = MALLOC(spIkConstraintData*, skeletonData->ikConstraintsCount); +// for (i = 0; i < skeletonData->ikConstraintsCount; ++i) +// { +// const char* name = readString(input); +// /* TODO Avoid copying of name */ +// spIkConstraintData* data = spIkConstraintData_create(name); +// data->order = readVarint(input, 1); +// FREE(name); +// data->bonesCount = readVarint(input, 1); +// data->bones = MALLOC(spBoneData*, data->bonesCount); +// for (ii = 0; ii < data->bonesCount; ++ii) +// data->bones[ii] = skeletonData->bones[readVarint(input, 1)]; +// data->target = skeletonData->bones[readVarint(input, 1)]; +// data->mix = readFloat(input); +// data->bendDirection = readSByte(input); +// skeletonData->ikConstraints[i] = data; +// } +// +// /* Transform constraints. */ +// skeletonData->transformConstraintsCount = readVarint(input, 1); +// skeletonData->transformConstraints = MALLOC(spTransformConstraintData*, skeletonData->transformConstraintsCount); +// for (i = 0; i < skeletonData->transformConstraintsCount; ++i) +// { +// const char* name = readString(input); +// /* TODO Avoid copying of name */ +// spTransformConstraintData* data = spTransformConstraintData_create(name); +// data->order = readVarint(input, 1); +// FREE(name); +// data->bonesCount = readVarint(input, 1); +// CONST_CAST(spBoneData**, data->bones) = MALLOC(spBoneData*, data->bonesCount); +// for (ii = 0; ii < data->bonesCount; ++ii) +// { +// data->bones[ii] = skeletonData->bones[readVarint(input, 1)]; +// } +// data->target = skeletonData->bones[readVarint(input, 1)]; +// data->local = readBoolean(input); +// data->relative = readBoolean(input); +// data->offsetRotation = readFloat(input); +// data->offsetX = readFloat(input) * _scale; +// data->offsetY = readFloat(input) * _scale; +// data->offsetScaleX = readFloat(input); +// data->offsetScaleY = readFloat(input); +// data->offsetShearY = readFloat(input); +// data->rotateMix = readFloat(input); +// data->translateMix = readFloat(input); +// data->scaleMix = readFloat(input); +// data->shearMix = readFloat(input); +// skeletonData->transformConstraints[i] = data; +// } +// +// /* Path constraints */ +// skeletonData->pathConstraintsCount = readVarint(input, 1); +// skeletonData->pathConstraints = MALLOC(spPathConstraintData*, skeletonData->pathConstraintsCount); +// for (i = 0; i < skeletonData->pathConstraintsCount; ++i) +// { +// const char* name = readString(input); +// /* TODO Avoid copying of name */ +// spPathConstraintData* data = spPathConstraintData_create(name); +// data->order = readVarint(input, 1); +// FREE(name); +// data->bonesCount = readVarint(input, 1); +// CONST_CAST(spBoneData**, data->bones) = MALLOC(spBoneData*, data->bonesCount); +// for (ii = 0; ii < data->bonesCount; ++ii) +// { +// data->bones[ii] = skeletonData->bones[readVarint(input, 1)]; +// } +// data->target = skeletonData->slots[readVarint(input, 1)]; +// data->positionMode = (spPositionMode)readVarint(input, 1); +// data->spacingMode = (spSpacingMode)readVarint(input, 1); +// data->rotateMode = (spRotateMode)readVarint(input, 1); +// data->offsetRotation = readFloat(input); +// data->position = readFloat(input); +// if (data->positionMode == SP_POSITION_MODE_FIXED) data->position *= _scale; +// data->spacing = readFloat(input); +// if (data->spacingMode == SP_SPACING_MODE_LENGTH || data->spacingMode == SP_SPACING_MODE_FIXED) data->spacing *= _scale; +// data->rotateMix = readFloat(input); +// data->translateMix = readFloat(input); +// skeletonData->pathConstraints[i] = data; +// } +// +// /* Default skin. */ +// skeletonData->defaultSkin = spSkeletonBinary_readSkin(self, input, "default", skeletonData, nonessential); +// skeletonData->skinsCount = readVarint(input, 1); +// +// if (skeletonData->defaultSkin) +// { +// ++skeletonData->skinsCount; +// } +// +// skeletonData->skins = MALLOC(spSkin*, skeletonData->skinsCount); +// +// if (skeletonData->defaultSkin) +// { +// skeletonData->skins[0] = skeletonData->defaultSkin; +// } +// +// /* Skins. */ +// for (i = skeletonData->defaultSkin ? 1 : 0; i < skeletonData->skinsCount; ++i) +// { +// const char* skinName = readString(input); +// /* TODO Avoid copying of skinName */ +// skeletonData->skins[i] = spSkeletonBinary_readSkin(self, input, skinName, skeletonData, nonessential); +// FREE(skinName); +// } +// +// /* Linked meshes. */ +// for (i = 0; i < internal->linkedMeshCount; ++i) +// { +// _spLinkedMesh* linkedMesh = internal->linkedMeshes + i; +// spSkin* skin = !linkedMesh->skin ? skeletonData->defaultSkin : spSkeletonData_findSkin(skeletonData, linkedMesh->skin); +// spAttachment* parent; +// if (!skin) +// { +// FREE(input); +// spSkeletonData_dispose(skeletonData); +// _spSkeletonBinary_setError(self, "Skin not found: ", linkedMesh->skin); +// return 0; +// } +// parent = spSkin_getAttachment(skin, linkedMesh->slotIndex, linkedMesh->parent); +// if (!parent) +// { +// FREE(input); +// spSkeletonData_dispose(skeletonData); +// _spSkeletonBinary_setError(self, "Parent mesh not found: ", linkedMesh->parent); +// return 0; +// } +// spMeshAttachment_setParentMesh(linkedMesh->mesh, SUB_CAST(spMeshAttachment, parent)); +// spMeshAttachment_updateUVs(linkedMesh->mesh); +// spAttachmentLoader_configureAttachment(self->attachmentLoader, SUPER(SUPER(linkedMesh->mesh))); +// } +// +// /* Events. */ +// skeletonData->eventsCount = readVarint(input, 1); +// skeletonData->events = MALLOC(spEventData*, skeletonData->eventsCount); +// for (i = 0; i < skeletonData->eventsCount; ++i) +// { +// const char* name = readString(input); +// /* TODO Avoid copying of skinName */ +// spEventData* eventData = spEventData_create(name); +// FREE(name); +// eventData->intValue = readVarint(input, 0); +// eventData->floatValue = readFloat(input); +// eventData->stringValue = readString(input); +// skeletonData->events[i] = eventData; +// } +// +// /* Animations. */ +// skeletonData->animationsCount = readVarint(input, 1); +// skeletonData->animations = MALLOC(spAnimation*, skeletonData->animationsCount); +// for (i = 0; i < skeletonData->animationsCount; ++i) +// { +// const char* name = readString(input); +// spAnimation* animation = _spSkeletonBinary_readAnimation(self, name, input, skeletonData); +// FREE(name); +// if (!animation) +// { +// FREE(input); +// spSkeletonData_dispose(skeletonData); +// return 0; +// } +// skeletonData->animations[i] = animation; +// } + + FREE(input); + + return skeletonData; + } + + SkeletonData* SkeletonBinary::readSkeletonDataFile(const char* path) + { + int length; + SkeletonData* skeletonData; + const char* binary = SPINE_EXTENSION->spineReadFile(path, &length); + if (length == 0 || !binary) + { + setError("Unable to read skeleton file: ", path); + return 0; + } + skeletonData = readSkeletonData((unsigned char*)binary, length); + FREE(binary); + return skeletonData; + } + + void SkeletonBinary::setError(const char* value1, const char* value2) + { + char message[256]; + int length; + strcpy(message, value1); + length = (int)strlen(value1); + if (value2) + { + strncat(message + length, value2, 255 - length); + } + + _error = std::string(message); + } + + char* SkeletonBinary::readString(DataInput* input) + { + int length = readVarint(input, 1); + char* string; + if (length == 0) { + return 0; + } + string = MALLOC(char, length); + memcpy(string, input->cursor, length - 1); + input->cursor += length - 1; + string[length - 1] = '\0'; + return string; + } + + float SkeletonBinary::readFloat(DataInput* input) + { + union + { + int intValue; + float floatValue; + } intToFloat; + + intToFloat.intValue = readInt(input); + + return intToFloat.floatValue; + } + + unsigned char SkeletonBinary::readByte(DataInput* input) + { + return *input->cursor++; + } + + signed char SkeletonBinary::readSByte(DataInput* input) + { + return (signed char)readByte(input); + } + + int SkeletonBinary::readBoolean(DataInput* input) + { + return readByte(input) != 0; + } + + int SkeletonBinary::readInt(DataInput* input) + { + int result = readByte(input); + result <<= 8; + result |= readByte(input); + result <<= 8; + result |= readByte(input); + result <<= 8; + result |= readByte(input); + return result; + } + + int SkeletonBinary::readVarint(DataInput* input, bool optimizePositive) + { + unsigned char b = readByte(input); + int value = b & 0x7F; + if (b & 0x80) + { + b = readByte(input); + value |= (b & 0x7F) << 7; + if (b & 0x80) + { + b = readByte(input); + value |= (b & 0x7F) << 14; + if (b & 0x80) + { + b = readByte(input); + value |= (b & 0x7F) << 21; + if (b & 0x80) value |= (readByte(input) & 0x7F) << 28; + } + } + } + + if (!optimizePositive) + { + value = (((unsigned int)value >> 1) ^ -(value & 1)); + } + + return value; + } } diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonData.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonData.cpp index 3a3367743..4678f658b 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonData.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonData.cpp @@ -58,6 +58,21 @@ namespace Spine // Empty } + SkeletonData::~SkeletonData() + { + ContainerUtil::cleanUpVectorOfPointers(_bones); + ContainerUtil::cleanUpVectorOfPointers(_slots); + ContainerUtil::cleanUpVectorOfPointers(_skins); + + delete _defaultSkin; + + ContainerUtil::cleanUpVectorOfPointers(_events); + ContainerUtil::cleanUpVectorOfPointers(_animations); + ContainerUtil::cleanUpVectorOfPointers(_ikConstraints); + ContainerUtil::cleanUpVectorOfPointers(_transformConstraints); + ContainerUtil::cleanUpVectorOfPointers(_pathConstraints); + } + BoneData* SkeletonData::findBone(std::string boneName) { return ContainerUtil::findWithName(_bones, boneName); diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp index bb4d2ccfe..482b7cbb5 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp @@ -28,7 +28,44 @@ * POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +#include + +#include +#include +#include + +#include +#include + namespace Spine { - // TODO + SkeletonJson::SkeletonJson(Vector& atlasArray) : _attachmentLoader(NEW(AtlasAttachmentLoader)), _scale(1), _ownsLoader(true) + { + new (_attachmentLoader) AtlasAttachmentLoader(atlasArray); + } + + SkeletonJson::SkeletonJson(AttachmentLoader* attachmentLoader) : _attachmentLoader(attachmentLoader), _scale(1), _ownsLoader(false) + { + assert(_attachmentLoader != NULL); + } + + SkeletonJson::~SkeletonJson() + { + ContainerUtil::cleanUpVectorOfPointers(_linkedMeshes); + + if (_ownsLoader) + { + DESTROY(AttachmentLoader, _attachmentLoader); + } + } + + SkeletonData* SkeletonJson::readSkeletonData(const char* json) + { + return NULL; + } + + SkeletonData* SkeletonJson::readSkeletonDataFile(const char* path) + { + return NULL; + } }