From 387b0afb80a775970c48099042be769e50258440 Mon Sep 17 00:00:00 2001 From: badlogic Date: Mon, 28 Nov 2016 16:00:46 +0100 Subject: [PATCH 1/3] [c] Added spine-c-tests (thanks @jpoag), fixed up CMake build --- CMakeLists.txt | 4 +- spine-c/CMakeLists.txt | 6 +- spine-c/README.md | 4 +- spine-c/spine-c-unit-tests/CMakeLists.txt | 58 ++ spine-c/spine-c-unit-tests/README.md | 67 +++ spine-c/spine-c-unit-tests/main.cpp | 77 +++ spine-c/spine-c-unit-tests/memory/KMemory.cpp | 303 +++++++++++ spine-c/spine-c-unit-tests/memory/KMemory.h | 189 +++++++ spine-c/spine-c-unit-tests/memory/KString.cpp | 185 +++++++ spine-c/spine-c-unit-tests/memory/KString.h | 19 + .../minicppunit/MiniCppUnit.cxx | 279 ++++++++++ .../minicppunit/MiniCppUnit.hxx | 504 ++++++++++++++++++ .../spine-c-unit-tests/teamcity/README.txt | 30 ++ .../teamcity/teamcity_cppunit.cpp | 82 +++ .../teamcity/teamcity_cppunit.h | 83 +++ .../teamcity/teamcity_messages.cpp | 174 ++++++ .../teamcity/teamcity_messages.h | 59 ++ .../tests/CPP_InterfaceTestFixture.cpp | 48 ++ .../tests/CPP_InterfaceTestFixture.h | 47 ++ .../tests/C_InterfaceTestFixture.cpp | 123 +++++ .../tests/C_InterfaceTestFixture.h | 33 ++ .../tests/EmptyTestFixture.cpp | 25 + .../tests/EmptyTestFixture.h | 26 + .../tests/MemoryTestFixture.cpp | 182 +++++++ .../tests/MemoryTestFixture.h | 44 ++ .../tests/SpineEventMonitor.cpp | 163 ++++++ .../tests/SpineEventMonitor.h | 122 +++++ .../CPP_InterfaceTestFixture.cpp | 26 + .../CPP_InterfaceTestFixture.h | 30 ++ .../TestFixtureGenerator/_TestFixture.cpp | 26 + .../tests/TestFixtureGenerator/_TestFixture.h | 30 ++ .../tests/TestFixtureGenerator/fnr.exe | Bin 0 -> 185200 bytes .../TestFixtureGenerator/makeFixture.bat | 17 + .../spine-c-unit-tests/tests/TestOptions.h | 32 ++ .../{ => spine-c}/include/spine/Animation.h | 0 .../include/spine/AnimationState.h | 0 .../include/spine/AnimationStateData.h | 0 spine-c/{ => spine-c}/include/spine/Atlas.h | 0 .../include/spine/AtlasAttachmentLoader.h | 0 .../{ => spine-c}/include/spine/Attachment.h | 0 .../include/spine/AttachmentLoader.h | 0 spine-c/{ => spine-c}/include/spine/Bone.h | 0 .../{ => spine-c}/include/spine/BoneData.h | 0 .../include/spine/BoundingBoxAttachment.h | 0 spine-c/{ => spine-c}/include/spine/Event.h | 0 .../{ => spine-c}/include/spine/EventData.h | 0 .../include/spine/IkConstraint.h | 0 .../include/spine/IkConstraintData.h | 0 .../include/spine/MeshAttachment.h | 0 .../include/spine/PathAttachment.h | 0 .../include/spine/PathConstraint.h | 0 .../include/spine/PathConstraintData.h | 0 .../include/spine/RegionAttachment.h | 0 .../{ => spine-c}/include/spine/Skeleton.h | 0 .../include/spine/SkeletonBinary.h | 0 .../include/spine/SkeletonBounds.h | 0 .../include/spine/SkeletonData.h | 0 .../include/spine/SkeletonJson.h | 0 spine-c/{ => spine-c}/include/spine/Skin.h | 0 spine-c/{ => spine-c}/include/spine/Slot.h | 0 .../{ => spine-c}/include/spine/SlotData.h | 0 .../include/spine/TransformConstraint.h | 0 .../include/spine/TransformConstraintData.h | 0 .../include/spine/VertexAttachment.h | 0 .../{ => spine-c}/include/spine/extension.h | 0 spine-c/{ => spine-c}/include/spine/spine.h | 0 spine-c/{ => spine-c}/src/spine/Animation.c | 0 .../{ => spine-c}/src/spine/AnimationState.c | 0 .../src/spine/AnimationStateData.c | 0 spine-c/{ => spine-c}/src/spine/Atlas.c | 0 .../src/spine/AtlasAttachmentLoader.c | 0 spine-c/{ => spine-c}/src/spine/Attachment.c | 0 .../src/spine/AttachmentLoader.c | 0 spine-c/{ => spine-c}/src/spine/Bone.c | 0 spine-c/{ => spine-c}/src/spine/BoneData.c | 0 .../src/spine/BoundingBoxAttachment.c | 0 spine-c/{ => spine-c}/src/spine/Event.c | 0 spine-c/{ => spine-c}/src/spine/EventData.c | 0 .../{ => spine-c}/src/spine/IkConstraint.c | 0 .../src/spine/IkConstraintData.c | 0 spine-c/{ => spine-c}/src/spine/Json.c | 0 spine-c/{ => spine-c}/src/spine/Json.h | 0 .../{ => spine-c}/src/spine/MeshAttachment.c | 0 .../{ => spine-c}/src/spine/PathAttachment.c | 0 .../{ => spine-c}/src/spine/PathConstraint.c | 0 .../src/spine/PathConstraintData.c | 0 .../src/spine/RegionAttachment.c | 0 spine-c/{ => spine-c}/src/spine/Skeleton.c | 0 .../{ => spine-c}/src/spine/SkeletonBinary.c | 0 .../{ => spine-c}/src/spine/SkeletonBounds.c | 0 .../{ => spine-c}/src/spine/SkeletonData.c | 0 .../{ => spine-c}/src/spine/SkeletonJson.c | 0 spine-c/{ => spine-c}/src/spine/Skin.c | 0 spine-c/{ => spine-c}/src/spine/Slot.c | 0 spine-c/{ => spine-c}/src/spine/SlotData.c | 0 .../src/spine/TransformConstraint.c | 0 .../src/spine/TransformConstraintData.c | 0 .../src/spine/VertexAttachment.c | 0 spine-c/{ => spine-c}/src/spine/extension.c | 0 spine-c/{ => spine-c}/src/spine/kvec.h | 0 spine-cocos2d-objc/README.md | 4 +- spine-cocos2dx/README.md | 4 +- spine-sfml/README.md | 4 +- 103 files changed, 3097 insertions(+), 12 deletions(-) create mode 100755 spine-c/spine-c-unit-tests/CMakeLists.txt create mode 100755 spine-c/spine-c-unit-tests/README.md create mode 100755 spine-c/spine-c-unit-tests/main.cpp create mode 100755 spine-c/spine-c-unit-tests/memory/KMemory.cpp create mode 100755 spine-c/spine-c-unit-tests/memory/KMemory.h create mode 100755 spine-c/spine-c-unit-tests/memory/KString.cpp create mode 100755 spine-c/spine-c-unit-tests/memory/KString.h create mode 100755 spine-c/spine-c-unit-tests/minicppunit/MiniCppUnit.cxx create mode 100755 spine-c/spine-c-unit-tests/minicppunit/MiniCppUnit.hxx create mode 100755 spine-c/spine-c-unit-tests/teamcity/README.txt create mode 100755 spine-c/spine-c-unit-tests/teamcity/teamcity_cppunit.cpp create mode 100755 spine-c/spine-c-unit-tests/teamcity/teamcity_cppunit.h create mode 100755 spine-c/spine-c-unit-tests/teamcity/teamcity_messages.cpp create mode 100755 spine-c/spine-c-unit-tests/teamcity/teamcity_messages.h create mode 100755 spine-c/spine-c-unit-tests/tests/CPP_InterfaceTestFixture.cpp create mode 100755 spine-c/spine-c-unit-tests/tests/CPP_InterfaceTestFixture.h create mode 100755 spine-c/spine-c-unit-tests/tests/C_InterfaceTestFixture.cpp create mode 100755 spine-c/spine-c-unit-tests/tests/C_InterfaceTestFixture.h create mode 100755 spine-c/spine-c-unit-tests/tests/EmptyTestFixture.cpp create mode 100755 spine-c/spine-c-unit-tests/tests/EmptyTestFixture.h create mode 100755 spine-c/spine-c-unit-tests/tests/MemoryTestFixture.cpp create mode 100755 spine-c/spine-c-unit-tests/tests/MemoryTestFixture.h create mode 100755 spine-c/spine-c-unit-tests/tests/SpineEventMonitor.cpp create mode 100755 spine-c/spine-c-unit-tests/tests/SpineEventMonitor.h create mode 100755 spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.cpp create mode 100755 spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.h create mode 100755 spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/_TestFixture.cpp create mode 100755 spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/_TestFixture.h create mode 100755 spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/fnr.exe create mode 100755 spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/makeFixture.bat create mode 100755 spine-c/spine-c-unit-tests/tests/TestOptions.h rename spine-c/{ => spine-c}/include/spine/Animation.h (100%) rename spine-c/{ => spine-c}/include/spine/AnimationState.h (100%) rename spine-c/{ => spine-c}/include/spine/AnimationStateData.h (100%) rename spine-c/{ => spine-c}/include/spine/Atlas.h (100%) rename spine-c/{ => spine-c}/include/spine/AtlasAttachmentLoader.h (100%) rename spine-c/{ => spine-c}/include/spine/Attachment.h (100%) rename spine-c/{ => spine-c}/include/spine/AttachmentLoader.h (100%) rename spine-c/{ => spine-c}/include/spine/Bone.h (100%) rename spine-c/{ => spine-c}/include/spine/BoneData.h (100%) rename spine-c/{ => spine-c}/include/spine/BoundingBoxAttachment.h (100%) rename spine-c/{ => spine-c}/include/spine/Event.h (100%) rename spine-c/{ => spine-c}/include/spine/EventData.h (100%) rename spine-c/{ => spine-c}/include/spine/IkConstraint.h (100%) rename spine-c/{ => spine-c}/include/spine/IkConstraintData.h (100%) rename spine-c/{ => spine-c}/include/spine/MeshAttachment.h (100%) rename spine-c/{ => spine-c}/include/spine/PathAttachment.h (100%) rename spine-c/{ => spine-c}/include/spine/PathConstraint.h (100%) rename spine-c/{ => spine-c}/include/spine/PathConstraintData.h (100%) rename spine-c/{ => spine-c}/include/spine/RegionAttachment.h (100%) rename spine-c/{ => spine-c}/include/spine/Skeleton.h (100%) rename spine-c/{ => spine-c}/include/spine/SkeletonBinary.h (100%) rename spine-c/{ => spine-c}/include/spine/SkeletonBounds.h (100%) rename spine-c/{ => spine-c}/include/spine/SkeletonData.h (100%) rename spine-c/{ => spine-c}/include/spine/SkeletonJson.h (100%) rename spine-c/{ => spine-c}/include/spine/Skin.h (100%) rename spine-c/{ => spine-c}/include/spine/Slot.h (100%) rename spine-c/{ => spine-c}/include/spine/SlotData.h (100%) rename spine-c/{ => spine-c}/include/spine/TransformConstraint.h (100%) rename spine-c/{ => spine-c}/include/spine/TransformConstraintData.h (100%) rename spine-c/{ => spine-c}/include/spine/VertexAttachment.h (100%) rename spine-c/{ => spine-c}/include/spine/extension.h (100%) rename spine-c/{ => spine-c}/include/spine/spine.h (100%) rename spine-c/{ => spine-c}/src/spine/Animation.c (100%) rename spine-c/{ => spine-c}/src/spine/AnimationState.c (100%) rename spine-c/{ => spine-c}/src/spine/AnimationStateData.c (100%) rename spine-c/{ => spine-c}/src/spine/Atlas.c (100%) rename spine-c/{ => spine-c}/src/spine/AtlasAttachmentLoader.c (100%) rename spine-c/{ => spine-c}/src/spine/Attachment.c (100%) rename spine-c/{ => spine-c}/src/spine/AttachmentLoader.c (100%) rename spine-c/{ => spine-c}/src/spine/Bone.c (100%) rename spine-c/{ => spine-c}/src/spine/BoneData.c (100%) rename spine-c/{ => spine-c}/src/spine/BoundingBoxAttachment.c (100%) rename spine-c/{ => spine-c}/src/spine/Event.c (100%) rename spine-c/{ => spine-c}/src/spine/EventData.c (100%) rename spine-c/{ => spine-c}/src/spine/IkConstraint.c (100%) rename spine-c/{ => spine-c}/src/spine/IkConstraintData.c (100%) rename spine-c/{ => spine-c}/src/spine/Json.c (100%) rename spine-c/{ => spine-c}/src/spine/Json.h (100%) rename spine-c/{ => spine-c}/src/spine/MeshAttachment.c (100%) rename spine-c/{ => spine-c}/src/spine/PathAttachment.c (100%) rename spine-c/{ => spine-c}/src/spine/PathConstraint.c (100%) rename spine-c/{ => spine-c}/src/spine/PathConstraintData.c (100%) rename spine-c/{ => spine-c}/src/spine/RegionAttachment.c (100%) rename spine-c/{ => spine-c}/src/spine/Skeleton.c (100%) rename spine-c/{ => spine-c}/src/spine/SkeletonBinary.c (100%) rename spine-c/{ => spine-c}/src/spine/SkeletonBounds.c (100%) rename spine-c/{ => spine-c}/src/spine/SkeletonData.c (100%) rename spine-c/{ => spine-c}/src/spine/SkeletonJson.c (100%) rename spine-c/{ => spine-c}/src/spine/Skin.c (100%) rename spine-c/{ => spine-c}/src/spine/Slot.c (100%) rename spine-c/{ => spine-c}/src/spine/SlotData.c (100%) rename spine-c/{ => spine-c}/src/spine/TransformConstraint.c (100%) rename spine-c/{ => spine-c}/src/spine/TransformConstraintData.c (100%) rename spine-c/{ => spine-c}/src/spine/VertexAttachment.c (100%) rename spine-c/{ => spine-c}/src/spine/extension.c (100%) rename spine-c/{ => spine-c}/src/spine/kvec.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index cd2bf60f7..40d6e03b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,4 +20,6 @@ endif() if((${SPINE_COCOS2D_X}) OR (${CMAKE_CURRENT_BINARY_DIR} MATCHES "spine-cocos2dx")) add_subdirectory(spine-cocos2dx) -endif() \ No newline at end of file +endif() + +add_subdirectory(spine-c/spine-c-unit-tests) \ No newline at end of file diff --git a/spine-c/CMakeLists.txt b/spine-c/CMakeLists.txt index 6c42403a8..009835099 100644 --- a/spine-c/CMakeLists.txt +++ b/spine-c/CMakeLists.txt @@ -1,9 +1,9 @@ include_directories(include) -file(GLOB INCLUDES "include/**/*.h") -file(GLOB SOURCES "src/**/*.c" "src/**/*.cpp") +file(GLOB INCLUDES "spine-c/include/**/*.h") +file(GLOB SOURCES "spine-c/src/**/*.c" "spine-c/src/**/*.cpp") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -std=c89 -pedantic") add_library(spine-c STATIC ${SOURCES} ${INCLUDES}) -target_include_directories(spine-c PUBLIC include) +target_include_directories(spine-c PUBLIC spine-c/include) install(TARGETS spine-c DESTINATION dist/lib) install(FILES ${INCLUDES} DESTINATION dist/include) \ No newline at end of file diff --git a/spine-c/README.md b/spine-c/README.md index 03c1b810f..2f07dc517 100644 --- a/spine-c/README.md +++ b/spine-c/README.md @@ -21,7 +21,7 @@ spine-c supports all Spine features. 1. Download the Spine Runtimes source using [git](https://help.github.com/articles/set-up-git) or by downloading it [as a zip](https://github.com/EsotericSoftware/spine-runtimes/archive/master.zip). 1. Open the `spine-c.sln` Visual C++ 2010 Express project file. For other IDEs, you will need to create a new project and import the source. -Alternatively, the contents of the `spine-c/src` and `spine-c/include` directories can be copied into your project. Be sure your header search is configured to find the contents of the `spine-c/include` directory. Note that the includes use `spine/Xxx.h`, so the `spine` directory cannot be omitted when copying the files. +Alternatively, the contents of the `spine-c/spine-c/src` and `spine-c/spine-c/include` directories can be copied into your project. Be sure your header search is configured to find the contents of the `spine-c/spine-c/include` directory. Note that the includes use `spine/Xxx.h`, so the `spine` directory cannot be omitted when copying the files. If `SPINE_SHORT_NAMES` is defined, the `sp` prefix for all structs and functions is optional. Only use this if the spine-c names won't cause a conflict. @@ -39,7 +39,7 @@ For example, `AtlasAttachmentLoader` is typically used to load attachments when [spine-sfml](https://github.com/EsotericSoftware/spine-runtimes/blob/master/spine-sfml/src/spine/spine-sfml.cpp#L39) serves as a simple example of extending spine-c. -spine-c uses an OOP style of programming where each "class" is made up of a struct and a number of functions prefixed with the struct name. More detals about how this works are available in [extension.h](https://github.com/EsotericSoftware/spine-runtimes/blob/master/spine-c/include/spine/extension.h#L2). This mechanism allows you to provide your own implementations for `spAttachmentLoader`, `spAttachment` and `spTimeline`, if necessary. +spine-c uses an OOP style of programming where each "class" is made up of a struct and a number of functions prefixed with the struct name. More detals about how this works are available in [extension.h](https://github.com/EsotericSoftware/spine-runtimes/blob/master/spine-c/spine-c/include/spine/extension.h#L2). This mechanism allows you to provide your own implementations for `spAttachmentLoader`, `spAttachment` and `spTimeline`, if necessary. ## Runtimes extending spine-c diff --git a/spine-c/spine-c-unit-tests/CMakeLists.txt b/spine-c/spine-c-unit-tests/CMakeLists.txt new file mode 100755 index 000000000..a89be3f26 --- /dev/null +++ b/spine-c/spine-c-unit-tests/CMakeLists.txt @@ -0,0 +1,58 @@ +cmake_minimum_required(VERSION 2.8.9) +project(spine_unit_test) + +set(CMAKE_INSTALL_PREFIX "./") +set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS -DKANJI_MEMTRACE -DUSE_CPP11_MUTEX") + +######################################################### +# set includes +######################################################### +include_directories(teamcity minicppunit tests memory) + +######################################################### +# Add Sources +######################################################### +set(MINICPP_SRC + minicppunit/MiniCppUnit.cxx +) + +set(TEAMCITY_SRC + teamcity/teamcity_cppunit.cpp + teamcity/teamcity_messages.cpp +) + +set(TEST_SRC + tests/SpineEventMonitor.cpp + tests/EmptyTestFixture.cpp + tests/C_InterfaceTestFixture.cpp + tests/CPP_InterfaceTestFixture.cpp + tests/MemoryTestFixture.cpp +) + +set(MEMLEAK_SRC + memory/KMemory.cpp + memory/KString.cpp +) + +######################################################### +# setup main project +######################################################### +add_executable(spine_unit_test main.cpp ${MINICPP_SRC} ${TEAMCITY_SRC} ${TEST_SRC} ${MEMLEAK_SRC}) +target_link_libraries(spine_unit_test spine-c) + + +######################################################### +# copy resources to build output directory +######################################################### +add_custom_command(TARGET spine_unit_test PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_CURRENT_LIST_DIR}/../../examples/spineboy/export $/testdata/spineboy) + +add_custom_command(TARGET spine_unit_test PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_CURRENT_LIST_DIR}/../../examples/raptor/export $/testdata/raptor) + +add_custom_command(TARGET spine_unit_test PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_CURRENT_LIST_DIR}/../../examples/goblins/export $/testdata/goblins) \ No newline at end of file diff --git a/spine-c/spine-c-unit-tests/README.md b/spine-c/spine-c-unit-tests/README.md new file mode 100755 index 000000000..825d7e1df --- /dev/null +++ b/spine-c/spine-c-unit-tests/README.md @@ -0,0 +1,67 @@ +# spine-c-unit-tests + +The spine-c-unit-tests project is to test the [Spine](http://esotericsoftware.com) skeletal animation system. It does not perform rendering. It is primarily used for regression testing and leak detection. It is designed to be run from a Continuous Integration server and to passively verify changes automatically on check-in. + +## Mini CPP Unit Testing +[MiniCppUnit](https://sourceforge.net/p/minicppunit/wiki/Home/) is a minimal unit testing framework similar to JUnit. It is used here to avoid large dependancies. + +Tests are sorted into Suites, Fixtures and Cases. There is one suite, it contains many fixtures and each fixture contains test cases. To turn off a fixture, edit "TestOptions.h". To turn off specific test cases, comment out the TEST_CASE() line in the fixture's header. + +## Memory Leak Detection +This project includes a very minimal memory leak detector. It is based roughly on the leak detector in the [Popcap Framework](https://sourceforge.net/projects/popcapframework/?source=directory), but has been modified over the years. + +## Continuous Integration +The test runner includes the ability to format output messages to signal a CI server. An example interface for [Teamcity](https://www.jetbrains.com/teamcity/) is included. To implement for another server, determine the wireformat for the messages and duplicate/edit the teamcity_messages class. [Teamcity Wire Format](https://confluence.jetbrains.com/display/TCD10/Build+Script+Interaction+with+TeamCity) + +### Trigger +Your CI server should trigger on VCS check-in. + +### CMake Build Step +The first build step for the CI server should be to run CMake on the 'spine-c-unit-tests' folder. Follow the usage directions below. + +### Compile Build Step +This build step should not execute if the previous step did not successfully complete. +Depending on the test agent build environment, you should build the output solution or project from the cmake step. Debug is fine. + +### Test Runner Build Step +This build step should not execute if the previous step did not successfully complete. +Again, depending on the test agent build environment, you should have produced an executable. Run this executable. + + +## Usage +Make sure [CMake](https://cmake.org/download/) is installed. + +Create a 'build' directory in the 'spine-c-unit-tests' folder. Then switch to that folder and execute cmake: + +mkdir build +cd build +cmake .. + +### Win32 build +msbuild spine_unit_test.sln /t:spine_unit_test /p:Configuration="Debug" /p:Platform="Win32" + + +## Licensing +This Spine Runtime may only be used for personal or internal use, typically to evaluate Spine before purchasing. If you would like to incorporate a Spine Runtime into your applications, distribute software containing a Spine Runtime, or modify a Spine Runtime, then you will need a valid [Spine license](https://esotericsoftware.com/spine-purchase). Please see the [Spine Runtimes Software License](https://github.com/EsotericSoftware/spine-runtimes/blob/master/LICENSE) for detailed information. + +The Spine Runtimes are developed with the intent to be used with data exported from Spine. By purchasing Spine, `Section 2` of the [Spine Software License](https://esotericsoftware.com/files/license.txt) grants the right to create and distribute derivative works of the Spine Runtimes. + +original "walk"": 330 +second "walk": 0d0 + +queue interrupt for original walk +queue start for second walk +drain interrupt and start + +0d0 is interrupted +0d0 is ended + +"run": 0c0 + 0d0 is interrupted + second walk becomes mixingFrom of run + 0c0 is started + + queue is drained + + first walk: 6f0 + second walk: 9c0 diff --git a/spine-c/spine-c-unit-tests/main.cpp b/spine-c/spine-c-unit-tests/main.cpp new file mode 100755 index 000000000..d83376bb8 --- /dev/null +++ b/spine-c/spine-c-unit-tests/main.cpp @@ -0,0 +1,77 @@ +// SexyKanjiTestSuite.cpp : Defines the entry point for the console application. +// + +#include "MiniCppUnit.hxx" + +#ifdef WIN32 +#include +#else +#include +#endif // WIN32 + +#include +#include "KString.h" + +#include "spine/extension.h" +#include "spine/spine.h" + +#include "KMemory.h" // last include + +void RegisterMemoryLeakDetector() +{ + // Register our malloc and free functions to track memory leaks + #ifdef KANJI_MEMTRACE + _setDebugMalloc(_kanjimalloc); + #endif + _setMalloc(_kanjimalloc); + _setFree(_kanjifree); +} + +int main(int argc, char* argv[]) +{ + RegisterMemoryLeakDetector(); + + // Start Timing + time_t start_time, end_time; + time(&start_time); + + + /* Set working directory to current location for opening test data */ +#ifdef WIN32 + _chdir( GetFileDir(argv[0], false).c_str() ); +#else + chdir(GetFileDir(argv[0], false).c_str()); +#endif + + // Run Test Suite + if(JetBrains::underTeamcity()) gTeamCityListener.startSuite("Spine-C Test Suite"); + int ret_val = TestFixtureFactory::theInstance().runTests() ? 0 : -1; + if(JetBrains::underTeamcity()) gTeamCityListener.endSuite("Spine-C Test Suite"); + + // End Timing + time(&end_time); + double secs = difftime(end_time,start_time); + printf("\n\n%i minutes and %i seconds of your life taken from you by these tests.\n", ((int)secs) / 60, ((int)secs) % 60); + + spAnimationState_disposeStatics(); // Fix for #775 + + return ret_val; +} + + + +extern "C" { // probably unnecessary + + void _spAtlasPage_createTexture(spAtlasPage* self, const char* path) { + self->rendererObject = nullptr; + self->width = 2048; + self->height = 2048; + } + + void _spAtlasPage_disposeTexture(spAtlasPage* self) { + } + + char* _spUtil_readFile(const char* path, int* length) { + return _readFile(path, length); + } +} \ No newline at end of file diff --git a/spine-c/spine-c-unit-tests/memory/KMemory.cpp b/spine-c/spine-c-unit-tests/memory/KMemory.cpp new file mode 100755 index 000000000..ec91465a2 --- /dev/null +++ b/spine-c/spine-c-unit-tests/memory/KMemory.cpp @@ -0,0 +1,303 @@ +#include +#include +#include +#include +#include + +#include "KString.h" + +#include "KMemory.h" // last include + +/////////////////////////////////////////////////////////////////////////////// +// +// KANJI_DUMP_LEAKED_MEM will print out the memory block that was leaked. +// This is helpful when leaked objects have string identifiers. +// +/////////////////////////////////////////////////////////////////////////////// +//#define KANJI_DUMP_LEAKED_MEM + + +/////////////////////////////////////////////////////////////////////////////// +// +// KANJI_TRACK_MEM_USAGE will print out all memory allocations. +// +/////////////////////////////////////////////////////////////////////////////// +//#define KANJI_TRACK_MEM_USAGE + + + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// Our memory system is thread-safe, but instead of linking massive libraries, +// we attempt to use C++11 std::mutex. +#ifdef USE_CPP11_MUTEX +#include +typedef std::recursive_mutex KSysLock; // rentrant +struct KAutoLock { + KAutoLock(KSysLock& lock) :mLock(lock) { mLock.lock(); } // acquire + ~KAutoLock() { mLock.unlock(); } // release + + KSysLock& mLock; +}; +#else // Fallback to unsafe. don't spawn threads +typedef int KSysLock; +struct KAutoLock { + KAutoLock(KSysLock) {} // acquire + ~KAutoLock() {} // release +}; +#endif + + + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +struct KANJI_ALLOC_INFO +{ + size_t size; + std::string file; + int line; +}; +static bool showLeaks = false; +class KAllocMap : public std::map +{ +public: + KSysLock crit; + static bool allocMapValid; + +public: + KAllocMap() { allocMapValid = true; } + ~KAllocMap() + { + if (showLeaks) + KMemoryDumpUnfreed(); + + allocMapValid = false; + } +}; +bool KAllocMap::allocMapValid = false; +static KAllocMap allocMap; // once this static object destructs, it dumps unfreed memory + + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +#ifdef KANJI_TRACK_MEM_USAGE +void KMemoryDumpUsage(); // forward declaration +class KAllocStat +{ +public: + typedef std::map allocCount; // [size] = count + typedef std::map, allocCount> allocInfo; // [file, line] = allocCount + + allocInfo memInfo; + static bool allocMapValid; + +public: + + KAllocStat() + { + allocMapValid = true; + } + ~KAllocStat() + { + if (showLeaks) + KMemoryDumpUsage(); + + allocMapValid = false; + } + void addTrack(const char* fname, int lnum, int asize) + { + allocCount& info = memInfo[std::pair(fname, lnum)]; + info[asize]++; + } +}; +bool KAllocStat::allocMapValid = false; +static KAllocStat allocStat; +#endif // KANJI_TRACK_MEM_USAGE + + + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +extern void KMemoryAddTrack( void* addr, size_t asize, const char* fname, int lnum ) +{ + if (!KAllocMap::allocMapValid || asize == 0) + return; + + KAutoLock aCrit(allocMap.crit); + showLeaks = true; + + KANJI_ALLOC_INFO& info = allocMap[addr]; + info.file = fname; + info.line = lnum; + info.size = asize; + +#ifdef KANJI_TRACK_MEM_USAGE + if (KAllocStat::allocMapValid) + allocStat.addTrack(fname, lnum, asize); +#endif +}; + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +void KMemoryRemoveTrack(void* addr) +{ + if (!KAllocMap::allocMapValid) + return; + + KAutoLock aCrit(allocMap.crit); + KAllocMap::iterator anItr = allocMap.find(addr); + if (anItr != allocMap.end()) + allocMap.erase(anItr); +}; + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +void KMemoryDumpUnfreed() +{ + if (!KAllocMap::allocMapValid) + return; + + KAutoLock aCrit(allocMap.crit); // prevent modification of the map while iterating + + size_t totalSize = 0; + char buf[8192]; + + FILE* f = fopen("mem_leaks.txt", "wt"); + if (!f) + return; + + time_t aTime = time(NULL); + sprintf(buf, "Memory Leak Report for %s\n", asctime(localtime(&aTime))); + fprintf(f, "%s", buf); + KOutputDebug(DEBUGLVL, "\n"); + KOutputDebug(INFOLVL, buf); + for(KAllocMap::iterator i = allocMap.begin(); i != allocMap.end(); ++i) + { + sprintf(buf, "%s(%d) : Leak %u byte%s @0x%08X\n", i->second.file.c_str(), i->second.line, i->second.size, i->second.size > 1 ? "s" : "", (size_t)i->first); + KOutputDebug(ERRORLVL, buf); + fprintf(f, "%s", buf); + +#ifdef KANJI_DUMP_LEAKED_MEM + unsigned char* data = (unsigned char*)i->first; + int count = 0; + char hex_dump[1024]; + char ascii_dump[1024]; + + for (int index = 0; index < i->second.size; index++) + { + unsigned char _c = *data; + + if (count == 0) + sprintf(hex_dump, "\t%02X ", _c); + else + sprintf(hex_dump, "%s%02X ", hex_dump, _c); // technically, this is undefined behavior + + if ((_c < 32) || (_c > 126)) + _c = '.'; + + if (count == 7) + sprintf(ascii_dump, "%s%c ", ascii_dump, _c); + else + sprintf(ascii_dump, "%s%c", count == 0 ? "\t" : ascii_dump, _c); // technically, this is undefined behavior + + + if (++count == 16) + { + count = 0; + sprintf(buf, "%s\t%s\n", hex_dump, ascii_dump); + fprintf(f, buf); + + memset((void*)hex_dump, 0, 1024); + memset((void*)ascii_dump, 0, 1024); + } + + data++; + } + + if (count != 0) + { + fprintf(f, hex_dump); + for (int index = 0; index < 16 - count; index++) + fprintf(f, "\t"); + + fprintf(f, ascii_dump); + + for (int index = 0; index < 16 - count; index++) + fprintf(f, "."); + } + + count = 0; + fprintf(f, "\n\n"); + memset((void*)hex_dump, 0, 1024); + memset((void*)ascii_dump, 0, 1024); + +#endif // KANJI_DUMP_LEAKED_MEM + + totalSize += i->second.size; + } + + ErrorLevel lvl = (totalSize > 0) ? ERRORLVL : INFOLVL; + + sprintf(buf, "-----------------------------------------------------------\n"); + fprintf(f, "%s", buf); + KOutputDebug(lvl, buf); + sprintf(buf, "Total Unfreed: %u bytes (%luKB)\n\n", totalSize, totalSize / 1024); + KOutputDebug(lvl, buf); + fprintf(f, "%s", buf); + fclose(f); +} + +#ifdef KANJI_TRACK_MEM_USAGE +void KMemoryDumpUsage() +{ + if (!KAllocStat::allocMapValid) + return; + + char buf[8192]; + FILE* f = fopen("mem_usage.txt", "wt"); + + time_t aTime = time(NULL); + sprintf(buf, "Memory Usage Report for %s\n", asctime(localtime(&aTime))); + if (f) fprintf(f, "%s", buf); + KOutputDebug("\n"); + KOutputDebug(buf); + + for(KAllocStat::allocInfo::iterator i = allocStat.memInfo.begin(); i != allocStat.memInfo.end(); ++i) + { + int aBytesTotal = 0; + int aCallsTotal = 0; + for (KAllocStat::allocCount::iterator index = i->second.begin(); index != i->second.end(); ++index) + { + aBytesTotal += index->first; + aCallsTotal += index->second; + sprintf(buf, "%s(%d) : %d bytes (%d %s)\n", i->first.first.c_str(), i->first.second, index->first, index->second, index->second == 1 ? "call" : "calls"); + if (f) fprintf(f, "%s", buf); + KOutputDebug(buf); + } + + if (i->second.size() > 1) + { + sprintf(buf, " %s(%d) : %d KB total (%d calls)\n", i->first.first.c_str(), i->first.second, aBytesTotal / 1024, aCallsTotal); + if (f) fprintf(f, "%s", buf); + KOutputDebug(buf); + } + } + if (f) fclose(f); +} +#endif // KANJI_TRACK_MEM_USAGE + +size_t KMemoryAllocated() +{ + if (!KAllocMap::allocMapValid) + return 0; + + KAutoLock aCrit(allocMap.crit); + + size_t size = 0; + for(auto i = allocMap.begin(); i != allocMap.end(); ++i) + { + KANJI_ALLOC_INFO& info = i->second; + size += info.size; + } + return size; +} \ No newline at end of file diff --git a/spine-c/spine-c-unit-tests/memory/KMemory.h b/spine-c/spine-c-unit-tests/memory/KMemory.h new file mode 100755 index 000000000..470a5db7d --- /dev/null +++ b/spine-c/spine-c-unit-tests/memory/KMemory.h @@ -0,0 +1,189 @@ +#ifndef __KANJIMEMORY_H__ +#define __KANJIMEMORY_H__ + +#include +#include + +#if defined(_DEBUG) && !defined(KANJI_MEMTRACE) +#define KANJI_MEMTRACE +#endif + +#ifdef WIN32 +#pragma warning(disable : 4595) +#endif + +////////////////////////////////////////////////////////////////////////// +// HOW TO USE THIS FILE +// +// In the desired .CPP file (NOT header file), AFTER ALL of your +// #include declarations, do a #include "KMemory.h" or whatever you renamed +// this file to. It's very important that you do it only in the .cpp and +// after every other include file, otherwise it won't compile. The memory leaks +// will appear in a file called mem_leaks.txt and they will also be printed out +// in the output window when the program exits. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SAFE_DELETE +#define SAFE_DELETE(pPtr) { if(pPtr) delete pPtr; pPtr = 0; } +#endif + +#ifndef SCOPED_AUTO_SAFE_DELETE +template +class ScopedAutoDeletePointerHelper +{ +public: + ScopedAutoDeletePointerHelper(T pPtr) : _pPtr(pPtr) {} + ~ScopedAutoDeletePointerHelper() { SAFE_DELETE(_pPtr); } + + T _pPtr; +}; +#define SCOPED_AUTO_SAFE_DELETE(p) ScopedAutoDeletePointerHelper anAutoDelete##p(p); +#endif + +#ifndef SAFE_DELETE_ARRAY +#define SAFE_DELETE_ARRAY(pPtr) { if(pPtr) delete [] pPtr; pPtr = 0; } +#endif + +extern void KMemoryDumpUnfreed(); +extern size_t KMemoryAllocated(); + +#ifdef WIN32 +#define KMEM_CALLTYPE __cdecl +#else +#define KMEM_CALLTYPE +#endif + +#ifdef __APPLE__ +#define KMEM_THROWSPEC throw(std::bad_alloc) +#define KMEM_THROWS_BADALLOC +#include +#else +#define KMEM_THROWSPEC +#endif + +#if defined(KANJI_MEMTRACE) + +///////////////////////////////////////////// +// DO NOT CALL THESE TWO METHODS DIRECTLY // +///////////////////////////////////////////// + +extern void KMemoryAddTrack(void* addr, size_t asize, const char* fname, int lnum); +extern void KMemoryRemoveTrack(void* addr); + +//Replacement for the standard malloc/free, records size of allocation and the file/line number it was on +inline void* _kanjimalloc (size_t size, const char* file, int line) +{ + void* ptr = (void*)malloc(size); + KMemoryAddTrack(ptr, size, file, line); + return(ptr); +} + +inline void* _kanjimalloc (size_t size) +{ + return _kanjimalloc(size, "", 0); +} + +inline void _kanjifree (void* ptr) +{ + KMemoryRemoveTrack(ptr); + free(ptr); +} + +inline void* _kanjirealloc (void* ptr, size_t size, const char* file, int line) +{ + void* ptr2 = (void*)realloc(ptr, size); + if (ptr2) + { + KMemoryRemoveTrack(ptr); + KMemoryAddTrack(ptr2, size, file, line); + } + return ptr2; +} + +inline void* _kanjirealloc (void* ptr, size_t size) +{ + return _kanjirealloc(ptr, size, "", 0); +} + +#define kanjimalloc(size) _kanjimalloc((size), __FILE__, __LINE__) +#define kanjifree _kanjifree +#define kanjirealloc(ptr, size) _kanjirealloc(ptr, size, __FILE__, __LINE__) + +//Replacement for the standard "new" operator, records size of allocation and the file/line number it was on +inline void* KMEM_CALLTYPE operator new(size_t size, const char* file, int line) +{ + void* ptr = (void*)malloc(size); + KMemoryAddTrack(ptr, size, file, line); + return(ptr); +} + +//Same as above, but for arrays +inline void* KMEM_CALLTYPE operator new[](size_t size, const char* file, int line) +{ + void* ptr = (void*)malloc(size); + KMemoryAddTrack(ptr, size, file, line); + return(ptr); +} + + +// These single argument new operators allow vc6 apps to compile without errors +inline void* KMEM_CALLTYPE operator new(size_t size) KMEM_THROWSPEC +{ + void* ptr = (void*)malloc(size); +#ifdef KMEM_THROWS_BADALLOC + if(!ptr) throw std::bad_alloc(); +#endif + return(ptr); +} + +inline void* KMEM_CALLTYPE operator new[](size_t size) KMEM_THROWSPEC +{ + void* ptr = (void*)malloc(size); +#ifdef KMEM_THROWS_BADALLOC + if(!ptr) throw std::bad_alloc(); +#endif // KMEM_THROWS_BADALLOC + return(ptr); +} + + +//custom delete operators +inline void KMEM_CALLTYPE operator delete(void* p) throw() +{ + KMemoryRemoveTrack(p); + free(p); +} + +inline void KMEM_CALLTYPE operator delete[](void* p) throw() +{ + KMemoryRemoveTrack(p); + free(p); +} + +//needed in case in the constructor of the class we're newing, it throws an exception +inline void KMEM_CALLTYPE operator delete(void* pMem, const char* file, int line) +{ + free(pMem); +} + +inline void KMEM_CALLTYPE operator delete[](void* pMem, const char* file, int line) +{ + free(pMem); +} + +#define KDEBUG_NEW new(__FILE__, __LINE__) +#define new KDEBUG_NEW + +#else // KANJI_MEMTRACE NOT DEFINED + +#define kanjimalloc malloc +#define kanjifree free +#define kanjirealloc realloc + +inline void* _kanjimalloc(size_t size) { return malloc(size); } +inline void _kanjifree(void* ptr) { free(ptr); } +inline void* _kanjirealloc(void* ptr, size_t size) { return realloc(ptr, size); } + +#endif // KANJI_MEMTRACE + +#endif // __KANJIMEMORY_H__ \ No newline at end of file diff --git a/spine-c/spine-c-unit-tests/memory/KString.cpp b/spine-c/spine-c-unit-tests/memory/KString.cpp new file mode 100755 index 000000000..bd7aef664 --- /dev/null +++ b/spine-c/spine-c-unit-tests/memory/KString.cpp @@ -0,0 +1,185 @@ +#include "KString.h" +#include + +#include "MiniCppUnit.hxx" + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// String Helper + +static std::string vasprintf(const char* fmt, va_list argv) +{ + std::string result; + va_list argv_copy; // vsnprintf modifies argv, need copy +#ifndef va_copy + argv_copy = argv; +#else + va_copy(argv_copy, argv); +#endif + + int len = vsnprintf(NULL, 0, fmt, argv_copy); + if (len > 0 && len < 255) + { + // cover 90% of all calls + char str[256] = { 0 }; + int len2 = vsnprintf(str, 255, fmt, argv); + result = str; + } + else if (len > 0) + { + char* str = static_cast(alloca(len + 1)); // alloca on stack, space for null-termination + int len2 = vsnprintf(str, len + 1, fmt, argv); + result = str; + } + return result; +} + + +static void reportWarning(const std::string& warnStr) +{ + if (JetBrains::underTeamcity()) + gTeamCityListener.messages.messageWarning(warnStr); + else + fprintf(stderr, "%s", warnStr.c_str()); +} + +static void reportError(const std::string& errorStr) +{ + if (JetBrains::underTeamcity()) + gTeamCityListener.messages.messageError(errorStr); + else + fprintf(stderr, "%s", errorStr.c_str()); +} + +static void reportInfo(const std::string& infoStr) +{ + if (JetBrains::underTeamcity()) + gTeamCityListener.messages.messageNormal(infoStr); + else + fprintf(stderr, "%s", infoStr.c_str()); +} + +static void reportDebug(const std::string& debugStr) +{ + fprintf(stderr, "%s", debugStr.c_str()); +} + +static void report(ErrorLevel level, const std::string& Str) +{ + switch (level) { + case WARNLVL: reportWarning(Str); break; + case ERRORLVL: reportError(Str); break; + case INFOLVL: reportInfo(Str); break; + case DEBUGLVL: reportDebug(Str); break; + } +} + +void KOutputDebug(ErrorLevel lvl, const char* fmt ...) +{ + va_list argList; + va_start(argList, fmt); + std::string str = vasprintf(fmt, argList); + va_end(argList); + + report(lvl, str); +} + +#define K_MAX(a,b) ((a>b) ? a : b) + +std::string GetFileName(const std::string& thePath, bool noExtension) +{ + int aLastSlash = K_MAX((int)thePath.rfind('\\'), (int)thePath.rfind('/')); + + if (noExtension) + { + int aLastDot = (int)thePath.rfind('.'); + if (aLastDot > aLastSlash) + return thePath.substr(aLastSlash + 1, aLastDot - aLastSlash - 1); + } + + if (aLastSlash == -1) + return thePath; + else + return thePath.substr(aLastSlash + 1); +} + +std::string GetFileDir(const std::string& thePath, bool withSlash) +{ + int aLastSlash = K_MAX((int)thePath.rfind(('\\')), (int)thePath.rfind(('/'))); + + if (aLastSlash == -1) + return (""); + else + { + if (withSlash) + return thePath.substr(0, aLastSlash + 1); + else + return thePath.substr(0, aLastSlash); + } +} + +std::string GetFileExt(const std::string& thePath) +{ + std::string::size_type idx = thePath.find_last_of('.'); + + if (idx != std::string::npos) + return thePath.substr(idx + 1); + + return (""); +} + +/** + * g_ascii_strcasecmp: + * @s1: string to compare with @s2. + * @s2: string to compare with @s1. + * + * Compare two strings, ignoring the case of ASCII characters. + * + * Unlike the BSD strcasecmp() function, this only recognizes standard + * ASCII letters and ignores the locale, treating all non-ASCII + * bytes as if they are not letters. + * + * This function should be used only on strings that are known to be + * in encodings where the bytes corresponding to ASCII letters always + * represent themselves. This includes UTF-8 and the ISO-8859-* + * charsets, but not for instance double-byte encodings like the + * Windows Codepage 932, where the trailing bytes of double-byte + * characters include all ASCII letters. If you compare two CP932 + * strings using this function, you will get false matches. + * + * Return value: an integer less than, equal to, or greater than + * zero if @s1 is found, respectively, to be less than, + * to match, or to be greater than @s2. + **/ +static int g_ascii_compare_caseless(const char* s1, const char* s2) +{ +#define TOUPPER(c) (((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 'A' : (c)) +#define TOLOWER(c) (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c)) +#define g_return_val_if_fail(expr,val) { if (!(expr)) return (val); } + + int c1, c2; + + g_return_val_if_fail(s1 != NULL, 0); + g_return_val_if_fail(s2 != NULL, 0); + + while (*s1 && *s2) + { + c1 = (int)(unsigned char)TOLOWER(*s1); + c2 = (int)(unsigned char)TOLOWER(*s2); + if (c1 != c2) + return (c1 - c2); + s1++; s2++; + } + + return (((int)(unsigned char)* s1) - ((int)(unsigned char)* s2)); + +#undef g_return_val_if_fail +#undef TOUPPER +#undef TOLOWER +} + + +int CompareNoCase(const std::string & str1, const std::string & str2) +{ + return g_ascii_compare_caseless(str1.c_str(), str2.c_str()); +} diff --git a/spine-c/spine-c-unit-tests/memory/KString.h b/spine-c/spine-c-unit-tests/memory/KString.h new file mode 100755 index 000000000..32a27cb44 --- /dev/null +++ b/spine-c/spine-c-unit-tests/memory/KString.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +// Error reporting with levels similar to Android and are automatically forwarded to Continuous integration server +enum ErrorLevel { + WARNLVL, + ERRORLVL, + INFOLVL, + DEBUGLVL +}; + +extern void KOutputDebug(ErrorLevel lvl, const char* fmt ...); + +extern std::string GetFileName(const std::string& thePath, bool noExtension); +extern std::string GetFileDir(const std::string& thePath, bool withSlash); +extern std::string GetFileExt(const std::string& thePath); + +extern int CompareNoCase(const std::string& str1, const std::string& str2); diff --git a/spine-c/spine-c-unit-tests/minicppunit/MiniCppUnit.cxx b/spine-c/spine-c-unit-tests/minicppunit/MiniCppUnit.cxx new file mode 100755 index 000000000..f14e790fb --- /dev/null +++ b/spine-c/spine-c-unit-tests/minicppunit/MiniCppUnit.cxx @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2003-2004 Pau Arumí & David García + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "MiniCppUnit.hxx" + +JetBrains::TeamcityProgressListener gTeamCityListener; +bool gUseTeamCity = false; + +#include +#include +#include + +#define MIN(a,b) ((a < b) ? a : b) +#define MAX(a,b) ((a > b) ? a : b) + +TestsListener::TestsListener() : _currentTestName(0) +{ + _executed=_failed=_exceptions=0; + gUseTeamCity = JetBrains::underTeamcity(); +} + +TestsListener& TestsListener::theInstance() +{ + static TestsListener instancia; + return instancia; +} + +std::stringstream& TestsListener::errorsLog() +{ + if (_currentTestName) + { + _log << "\n" << errmsgTag_nameOfTest() << (*_currentTestName) << "\n"; + } + return _log; +} + +std::string TestsListener::logString() +{ + std::string aRetornar = _log.str(); + _log.str(""); + return aRetornar; +} +void TestsListener::currentTestName( std::string& name) +{ + _currentTestName = &name; + + if(gUseTeamCity)gTeamCityListener.startTest(name); +} +void TestsListener::testHasRun() // started +{ + std::cout << "."; + theInstance()._executed++; +} + +void TestsListener::testHasPassed() // finished without errors +{ + if(gUseTeamCity) + gTeamCityListener.endTest(*(theInstance()._currentTestName)); +} + +void TestsListener::testHasFailed(const char* reason, const char* file, int line) +{ + if(gUseTeamCity) + { + gTeamCityListener.addFailure(JetBrains::TestFailure(*(theInstance()._currentTestName), "", JetBrains::SourceLine(file, line), reason)); + gTeamCityListener.endTest(*(theInstance()._currentTestName)); + } + + std::cout << "F"; + theInstance()._failed++; + throw TestFailedException(); +} +void TestsListener::testHasThrown() +{ + if(gUseTeamCity) + { + gTeamCityListener.addFailure(JetBrains::TestFailure(*(theInstance()._currentTestName), "", JetBrains::SourceLine(), "Exception")); + gTeamCityListener.endTest(*(theInstance()._currentTestName)); + } + std::cout << "E"; + theInstance()._exceptions++; +} +std::string TestsListener::summary() +{ + std::ostringstream os; + os << "\nSummary:\n" + << Assert::bold() << "\tExecuted Tests: " + << _executed << Assert::normal() << std::endl + << Assert::green() << "\tPassed Tests: " + << (_executed-_failed-_exceptions) + << Assert::normal() << std::endl; + if (_failed > 0) + { + os << Assert::red() << "\tFailed Tests: " + << _failed << Assert::normal() << std::endl; + } + if (_exceptions > 0) + { + os << Assert::yellow() << "\tUnexpected exceptions: " + << _exceptions << Assert::normal() << std::endl; + } + os << std::endl; + return os.str(); +} +bool TestsListener::allTestsPassed() +{ + return !theInstance()._exceptions && !theInstance()._failed; +} + + + +void Assert::assertTrue(char* strExpression, bool expression, + const char* file, int linia) +{ + if (!expression) + { + TestsListener::theInstance().errorsLog() << "\n" + << errmsgTag_testFailedIn() << file + << errmsgTag_inLine() << linia << "\n" + << errmsgTag_failedExpression() + << bold() << strExpression << normal() << "\n"; + TestsListener::theInstance().testHasFailed(strExpression, file, linia); + } +} + +void Assert::assertTrueMissatge(char* strExpression, bool expression, + const char* missatge, const char* file, int linia) +{ + if (!expression) + { + TestsListener::theInstance().errorsLog() << "\n" + << errmsgTag_testFailedIn() << file + << errmsgTag_inLine() << linia << "\n" + << errmsgTag_failedExpression() + << bold() << strExpression << "\n" + << missatge<< normal() << "\n"; + TestsListener::theInstance().testHasFailed(strExpression, file, linia); + } +} + + + +void Assert::assertEquals( const char * expected, const char * result, + const char* file, int linia ) +{ + assertEquals(std::string(expected), std::string(result), + file, linia); + +} +void Assert::assertEquals( const bool& expected, const bool& result, + const char* file, int linia ) +{ + assertEquals( + (expected?"true":"false"), + (result?"true":"false"), + file, linia); +} + +// floating point numbers comparisons taken +// from c/c++ users journal. dec 04 pag 10 +bool isNaN(double x) +{ + bool b1 = (x < 0.0); + bool b2 = (x >= 0.0); + return !(b1 || b2); +} + +double scaledEpsilon(const double& expected, const double& fuzzyEpsilon ) +{ + const double aa = fabs(expected)+1; + return (std::isinf(aa))? fuzzyEpsilon: fuzzyEpsilon * aa; +} +bool fuzzyEquals(double expected, double result, double fuzzyEpsilon) +{ + return (expected==result) || ( fabs(expected-result) <= scaledEpsilon(expected, fuzzyEpsilon) ); +} +void Assert::assertEquals( const double& expected, const double& result, + const char* file, int linia ) +{ + const double fuzzyEpsilon = 0.000001; + assertEqualsEpsilon( expected, result, fuzzyEpsilon, file, linia ); +} + +void Assert::assertEquals( const float& expected, const float& result, + const char* file, int linia ) +{ + assertEquals((double)expected, (double)result, file, linia); +} +void Assert::assertEquals( const long double& expected, const long double& result, + const char* file, int linia ) +{ + assertEquals((double)expected, (double)result, file, linia); +} +void Assert::assertEqualsEpsilon( const double& expected, const double& result, const double& epsilon, + const char* file, int linia ) +{ + if (isNaN(expected) && isNaN(result) ) return; + if (!isNaN(expected) && !isNaN(result) && fuzzyEquals(expected, result, epsilon) ) return; + + std::stringstream anError; + anError + << errmsgTag_testFailedIn() << file + << errmsgTag_inLine() << linia << "\n" + << errmsgTag_expected() + << bold() << expected << normal() << " " + << errmsgTag_butWas() + << bold() << result << normal() << "\n"; + + TestsListener::theInstance().errorsLog() << anError.str(); + + TestsListener::theInstance().testHasFailed(anError.str().c_str(), file, linia); +} + +int Assert::notEqualIndex( const std::string & one, const std::string & other ) +{ + int end = MIN(one.length(), other.length()); + for ( int index = 0; index < end; index++ ) + if (one[index] != other[index] ) + return index; + return end; +} + + +/** + * we overload the assert with string doing colored diffs + * + * MS Visual6 doesn't allow string by reference :-( + */ +void Assert::assertEquals( const std::string expected, const std::string result, + const char* file, int linia ) +{ + if(expected == result) + return; + + int indexDiferent = notEqualIndex(expected, result); + + std::stringstream anError; + anError + << file << ", linia: " << linia << "\n" + << errmsgTag_expected() << "\n" << blue() + << expected.substr(0,indexDiferent) + << green() << expected.substr(indexDiferent) + << normal() << "\n" + << errmsgTag_butWas() << blue() << "\n" + << result.substr(0,indexDiferent) + << red() << result.substr(indexDiferent) + << normal() << std::endl; + + TestsListener::theInstance().errorsLog() << anError.str(); + + TestsListener::theInstance().testHasFailed(anError.str().c_str(), file, linia); +} +void Assert::fail(const char* motiu, const char* file, int linia) +{ + TestsListener::theInstance().errorsLog() << + file << errmsgTag_inLine() << linia << "\n" << + "Reason: " << motiu << "\n"; + + TestsListener::theInstance().testHasFailed(motiu, file, linia); +} + + diff --git a/spine-c/spine-c-unit-tests/minicppunit/MiniCppUnit.hxx b/spine-c/spine-c-unit-tests/minicppunit/MiniCppUnit.hxx new file mode 100755 index 000000000..b19cbbb57 --- /dev/null +++ b/spine-c/spine-c-unit-tests/minicppunit/MiniCppUnit.hxx @@ -0,0 +1,504 @@ +/* + * Copyright (c) 2003-2004 Pau Arum� & David Garc�a + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef MiniCppUnit_hxx +#define MiniCppUnit_hxx + +/** + * @mainpage + * miniCppUnit + * (C) 2003-2006 Pau Arumi & David Garcia + * + * @version 2.5 2006-03-14 + * - MS Visual compatibility: SConstruct ccflags, usage example, #ifdefs + * @version 2.4 2006-03-14 + * - exit test case after first failure + * - double and float comparison with fuzzy equals (using scalable epsilon) + * - have into account not a numbers + * - new ASSERT_EQUALS_EPSILON macro + * - more colors, and disabled when comiled in MS Visual + * - removed catalan location. + * - UsageExample.cxx now uses all macros and features + * @version 2.3 2006-02-13 added usage example and SConstruct + * @version 2.2 2004-11-28 code in english and tests suites + * @version 2.1 2004-11-04 char* especialization + * @version 2.0 2004-10-26 TestsFactory + * @version 1.0 2003-10-28 initial + * + * Example of use: + * + * @code + * #include "MiniCppUnit.hxx" + * class MyTests : public TestFixture + * { + * public: + * TEST_FIXTURE( MyTests ) + * { + * CAS_DE_TEST( testAddition ); + * // etc + * } + * void testAddition() + * { + * ASSERT_EQUALS( 4, 1+1+2 ); + * } + * // etc + * }; + * + * REGISTER_FIXTURE( MyTests ); + * @endcode + * @code + * int main() + * { + * return TestFixtureFactory::theInstance().runTests() ? 0 : -1; + * } + * @endcode + * Good things: + * + * - it's a tiny framework made up of two or three src files. + * => no need to install as a library + * - object oriented and makes use of several GoF patterns + * - very simple usage. Just needs to learn very few C macros + * - string asserts are simpler to use than cppunit + * - string asserts are enhanced with coloured diffs + * - concrete test classes are totally decoupled via static factory + * => no src file have to include them all. + * - it have test suite hierarchies + * - compatible with non-standard compliant VisualC6 + * (though not necessary good ;) + */ + +#include +#include +#include +#include + +#if _MSC_VER < 1300 +/** necesary for Visual 6 which don't define std::min */ +namespace std +{ + template T min(const T& a, const T& b) { return a < b ? a: b; } +} +#endif + +#include "../teamcity/teamcity_cppunit.h" + +extern JetBrains::TeamcityProgressListener gTeamCityListener; + +/** + * A singleton class. + * Receives tests results and stores messages to the test log + * for later listing. + * It's a singleton for an easy global access from the 'Asserts' + * methods but it is probably asking for a refactoring in order to limit + * access only to TestFixtures + */ +class TestsListener +{ +public: + /** accessor to the global (static) singleton instance */ + static TestsListener& theInstance(); + std::stringstream& errorsLog(); + std::string logString(); + void currentTestName( std::string& name); + static void testHasRun(); + static void testHasPassed(); + static void testHasFailed(const char* reason, const char* file, int line); + static void testHasThrown(); + /** the human readable summary of run tests*/ + std::string summary(); + /** returns wheather all run tests have passed */ + static bool allTestsPassed(); + +private: + static const char* errmsgTag_nameOfTest() { return "Test failed: "; } + + /** constructor private: force the singleton to be wellbehaved ! */ + TestsListener(); + + std::string* _currentTestName; + std::stringstream _log; + unsigned _executed; + unsigned _failed; + unsigned _exceptions; +}; + +class TestFailedException +{ +}; + +/** + * Abstract class with interface that allows run a test. That is runTest + * and name. It is implemented by TestFixture and TestCase + * + * It does the 'Component' role in the 'Composite' patten + **/ +class Test +{ +public: + virtual ~Test(){} + /** run the test: exercice the code and check results*/ + virtual void runTest() = 0; + /** the test human-readable name */ + virtual std::string name() const = 0; +}; + + +/** + * This class is just a placeholder for all assert functions --as static methods. + * It is meant for being used just by the assert macros + */ +class Assert +{ + static const char * errmsgTag_testFailedIn() { return "Test failed in "; } + static const char * errmsgTag_inLine() { return ", line: "; }; + static const char * errmsgTag_failedExpression() { return "Failed expression: "; } + static const char * errmsgTag_expected() { return "Expected: "; } + static const char * errmsgTag_butWas() { return "But was: "; } + +public: +#ifdef _MSC_VER + static const char * blue() { return ""; } + static const char * green() { return ""; } + static const char * red() { return ""; } + static const char * normal() { return ""; } + static const char * bold() { return ""; } + static const char * yellow() { return ""; } +#else + static const char * blue() { return "\033[36;1m"; } + static const char * green() { return "\033[32;1m"; } + static const char * red() { return "\033[31;1m"; } + static const char * normal() { return "\033[0m"; } + static const char * bold() { return "\033[" "1m"; } + static const char * yellow() { return "\033[93;1m"; } +#endif + template + static void assertEquals( const AType& expected, const AType& result, + const char* file="", int linia=0 ) + { + if(expected != result) + { + std::stringstream anError; + + anError + << file << ", linia: " << linia << "\n" + << errmsgTag_expected() << " " << expected << " " + << errmsgTag_butWas() << " " << result << "\n"; + + TestsListener::theInstance().errorsLog() << anError; + + TestsListener::theInstance().testHasFailed(anError.str().c_str(), file, linia); + } + } + + static void assertTrue(char* strExpression, bool expression, + const char* file="", int linia=0); + + static void assertTrueMissatge(char* strExpression, bool expression, + const char* missatge, const char* file="", int linia=0); + + static void assertEquals( const char * expected, const char * result, + const char* file="", int linia=0 ); + + static void assertEquals( const bool& expected, const bool& result, + const char* file="", int linia=0 ); + + static void assertEquals( const double& expected, const double& result, + const char* file="", int linia=0 ); + + static void assertEquals( const float& expected, const float& result, + const char* file="", int linia=0 ); + + static void assertEquals( const long double& expected, const long double& result, + const char* file="", int linia=0 ); + + static void assertEqualsEpsilon( const double& expected, const double& result, const double& epsilon, + const char* file="", int linia=0 ); + + static int notEqualIndex( const std::string & one, const std::string & other ); + + /** + * we overload the assert with string doing colored diffs + * + * MS Visual6 doesn't allow string by reference :-( + */ + static void assertEquals( const std::string expected, const std::string result, + const char* file="", int linia=0 ); + + static void fail(const char* motiu, const char* file="", int linia=0); + + +}; + +/** + * A TestFixture is a class that contain TestCases --which corresponds to + * ConcreteTestFixture methods-- common objects uder tests, and setUp and + * tearDown methods which are automatically executed before and after each + * test case. + * + * Is the base class of ConcreteFixtures implemented by the framework user + * + * It does the 'Composite' role in the 'Composite' GoF pattern. + * Its composite children are TestCases, which wrapps the test methods. + * + * It is a template class parametrized by ConcreteTestFixture so that it can + * instantiate TestCase objects templatized with this same parameter: it needs the + * concrete class type for calling its non-static methods. + */ +template +class TestFixture : public Test +{ +protected: + + typedef ConcreteTestFixture ConcreteFixture; + typedef void(ConcreteTestFixture::*TestCaseMethod)(); + + /** + * Wrapper for the test methods of concrete TestFixtures. + * + * Makes the 'Leave' role in the 'Composite' GoF pattern because can't be + * be a composition of other tests. + * + * It's also a case of 'Command' pattern because it encapsules in an object + * certain functionality whose execution depends on some deferred entity. + */ + class TestCase : public Test + { + public: + TestCase(ConcreteFixture* parent, TestCaseMethod method, const std::string & name) : + _parent(parent), + _testCaseMethod(method), + _name(name) + { + } + /** calls TestFixture method. setUp and tearDown methods are called by + * its parent TestFixture (in its runTest method). + * it is robust to unexpected exceptions (throw) */ + void runTest() + { + TestsListener::theInstance().testHasRun(); + TestsListener::theInstance().currentTestName(_name); + try + { + (_parent->*_testCaseMethod)(); + TestsListener::theInstance().testHasPassed(); + } + catch( std::exception& error ) + { + TestsListener::theInstance().testHasThrown(); + TestsListener::theInstance().errorsLog() + << "std::exception catched by MiniCppUnit: \n" + << "what() : " + << Assert::yellow() << error.what() + << Assert::normal() << "\n"; + } + catch ( TestFailedException& ) //just for skiping current test case + { + // the assert() calls testHasFailed() + } + catch(...) + { + TestsListener::theInstance().testHasThrown(); + TestsListener::theInstance().errorsLog() + << "non standard exception catched by MiniCppUnit.\n"; + } + } + + /** the TestFixture method hame */ + std::string name() const + { + return _name; + } + + private: + ConcreteFixture* _parent; + TestCaseMethod _testCaseMethod; + std::string _name; + }; + //------------- end of class TestCase ---------------------------- + +private: + + typedef std::list TestCases; + TestCases _testCases; + std::string _name; + + void testsList() const + { + std::cout << "\n+ " << name() << "\n"; + for( TestCases::const_iterator it=_testCases.begin(); + it!=_testCases.end(); it++ ) + std::cout << " - "<< (*it)->name() << "\n"; + } + + +public: + virtual void setUp() {} + virtual void tearDown() {} + + std::string name() const + { + return _name; + }; + + TestFixture(const std::string& name="A text fixture") : _name(name) + { + } + + void afegeixCasDeTest(ConcreteFixture* parent, TestCaseMethod method, const char* name) + { + TestCase* casDeTest = new TestCase(parent, method, _name + "::" + name); + _testCases.push_back( casDeTest ); + } + /** calls each test after setUp and tearDown TestFixture methods */ + void runTest() + { + testsList(); + TestCases::iterator it; + for( it=_testCases.begin(); it!=_testCases.end(); it++) + { + setUp(); + (*it)->runTest(); + tearDown(); + } + } + /** TestCase that wrapps TestFixture methods are dynamically created and owned by + * the TestFixture. So here we clean it up*/ + virtual ~TestFixture() + { + TestCases::iterator it; + for( it =_testCases.begin(); it!=_testCases.end(); it++) + delete (*it); + } +}; + + +/** + * This class is aimed to hold a creator method for each concrete TestFixture + */ +class TestFixtureFactory +{ +private: + /** Well behaved singleton: + * Don't allow instantiation apart from theInstance(), so private ctr.*/ + TestFixtureFactory() + { + } + typedef Test* (*FixtureCreator)(); + std::list _creators; +public: + /** Accessor to the (static) singleton instance */ + static TestFixtureFactory& theInstance() + { + static TestFixtureFactory theFactory; + return theFactory; + } + bool runTests() + { + std::list::iterator it; + for(it=_creators.begin(); it!=_creators.end(); it++) + { + FixtureCreator creator = *it; + Test* test = creator(); + test->runTest(); + delete test; + } + std::string errors = TestsListener::theInstance().logString(); + if (errors!="") std::cout << "\n\nError Details:\n" << errors; + std::cout << TestsListener::theInstance().summary(); + + return TestsListener::theInstance().allTestsPassed(); + } + void addFixtureCreator(FixtureCreator creator) + { + _creators.push_back( creator ); + } + +}; + +/** + * Macro a usar despr�s de cada classe de test + */ +#define REGISTER_FIXTURE( ConcreteTestFixture ) \ +\ +Test* Creador##ConcreteTestFixture() { return new ConcreteTestFixture; } \ +\ +class Registrador##ConcreteTestFixture \ +{ \ +public: \ + Registrador##ConcreteTestFixture() \ + { \ + TestFixtureFactory::theInstance().addFixtureCreator( \ + Creador##ConcreteTestFixture); \ + } \ +}; \ +static Registrador##ConcreteTestFixture estatic##ConcreteTestFixture; + + +/** + * Assert macros to use in test methods. An assert is a test condition + * we want to check. + */ +#define ASSERT_EQUALS( expected, result) \ + Assert::assertEquals( expected, result, __FILE__, __LINE__ ); + +#define ASSERT_EQUALS_EPSILON( expected, result, epsilon) \ + Assert::assertEqualsEpsilon( expected, result, epsilon, __FILE__, __LINE__ ); + +#define ASSERT( exp ) \ + Assert::assertTrue(#exp, exp, __FILE__, __LINE__); + +#define ASSERT_MESSAGE( exp, message ) \ + Assert::assertTrueMissatge(#exp, exp, message, __FILE__, __LINE__); + +#define FAIL( why ) \ + Assert::fail(#why, __FILE__, __LINE__); + +/** + * Macros that allows to write the constructor of the concrete TestFixture. + * What the constructor does is agregate a wrapper for each test case (method) + * As easy to write as this: + * + * @code + * class MyTests : public TestFixture + * { + * public: + * TEST_FIXTURE( MyTests ) + * { + * TEST_CASE( test ); + * // etc + * } + * void test() + * { + * ASSERT_EQUALS( 4, 1+1+2 ); + * } + * @endcode + */ + +#define TEST_FIXTURE( ConcreteFixture ) \ + ConcreteFixture() : TestFixture( #ConcreteFixture ) + +#define TEST_CASE( methodName ) \ + afegeixCasDeTest( this, &ConcreteFixture::methodName, #methodName ); + + + + + +#endif // MiniCppUnit_hxx diff --git a/spine-c/spine-c-unit-tests/teamcity/README.txt b/spine-c/spine-c-unit-tests/teamcity/README.txt new file mode 100755 index 000000000..04f7914b9 --- /dev/null +++ b/spine-c/spine-c-unit-tests/teamcity/README.txt @@ -0,0 +1,30 @@ +CppUnit listener for TeamCity +----------------------------- + +To report your tests result to TeamCity server +include teamcity_messages.* teamcity_cppunit.* +to your project and modify "main" function +as shown in example.cpp +(around JetBrains::underTeamcity and JetBrains::TeamcityProgressListener) + +Technical details +----------------- + +Reporting implemented by writing TeamCity service messages to stdout. + +See +http://www.jetbrains.net/confluence/display/TCD3/Build+Script+Interaction+with+TeamCity +for more details. + +Contact information +------------------- + +Mail to teamcity-feedback@jetbrains.com or see other options at + +http://www.jetbrains.com/support/teamcity + +License +------- + +Apache, version 2.0 +http://www.apache.org/licenses/LICENSE-2.0 diff --git a/spine-c/spine-c-unit-tests/teamcity/teamcity_cppunit.cpp b/spine-c/spine-c-unit-tests/teamcity/teamcity_cppunit.cpp new file mode 100755 index 000000000..86f163b9c --- /dev/null +++ b/spine-c/spine-c-unit-tests/teamcity/teamcity_cppunit.cpp @@ -0,0 +1,82 @@ +/* Copyright 2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Revision: 88625 $ +*/ + +#include + +#include "teamcity_cppunit.h" + +using namespace std; + +namespace JetBrains { + +TeamcityProgressListener::TeamcityProgressListener() +{ + flowid = getFlowIdFromEnvironment(); +} + +TeamcityProgressListener::TeamcityProgressListener(const std::string& _flowid) +{ + flowid = _flowid; +} + +void TeamcityProgressListener::startTest(const std::string& test) { + messages.testStarted(test, flowid); +} + +static string sourceLine2string(const SourceLine &sline) { + stringstream ss; + + ss << sline.fileName << ":" << sline.lineNumber; + + return ss.str(); +} + +void TeamcityProgressListener::addFailure(const TestFailure &failure) +{ + + string details = failure.details; + + if (failure.sourceLine.isValid()) { + details.append(" at "); + details.append(sourceLine2string(failure.sourceLine)); + details.append("\n"); + } + + messages.testFailed( + failure.testName, + failure.description, + details, + flowid + ); +} + +void TeamcityProgressListener::endTest(const std::string& test) +{ + messages.testFinished(test, -1, flowid); +} + +void TeamcityProgressListener::startSuite(const std::string& test) +{ + messages.suiteStarted(test, flowid); +} + +void TeamcityProgressListener::endSuite(const std::string& test) +{ + messages.suiteFinished(test, flowid); +} + +} diff --git a/spine-c/spine-c-unit-tests/teamcity/teamcity_cppunit.h b/spine-c/spine-c-unit-tests/teamcity/teamcity_cppunit.h new file mode 100755 index 000000000..7541a5186 --- /dev/null +++ b/spine-c/spine-c-unit-tests/teamcity/teamcity_cppunit.h @@ -0,0 +1,83 @@ +/* Copyright 2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Revision: 88625 $ +*/ + +#pragma once + +#include + +#include "teamcity_messages.h" + +namespace JetBrains { + + class SourceLine + { + public: + SourceLine():lineNumber(-1){} + SourceLine(const std::string& theFile, int theLineNum):fileName(theFile),lineNumber(theLineNum){} + ~SourceLine(){} + + std::string fileName; + int lineNumber; + bool isValid() const {return (!fileName.empty() && lineNumber > -1);} + }; + + class TestFailure + { + public: + std::string details; + SourceLine sourceLine; + std::string testName; + std::string description; + public: + TestFailure(){} + ~TestFailure(){} + + TestFailure(const std::string& theTestName, const std::string& theDetails, SourceLine theSourcelLine, const std::string& theDescription) + { + testName = theTestName; + details = theDetails; + sourceLine = theSourcelLine; + description = theDescription; + } + }; + + class TeamcityProgressListener + { + public: + TeamcityMessages messages; + public: + TeamcityProgressListener(const std::string& _flowid); + TeamcityProgressListener(); + ~TeamcityProgressListener(){} + + void startTest(const std::string& test); + void addFailure(const TestFailure &failure); + void endTest(const std::string& test); + void startSuite(const std::string& test); + void endSuite(const std::string& test); + + private: + std::string flowid; + + // Prevents the use of the copy constructor. + TeamcityProgressListener(const TeamcityProgressListener ©); + + // Prevents the use of the copy operator. + void operator =(const TeamcityProgressListener ©); + }; + +} \ No newline at end of file diff --git a/spine-c/spine-c-unit-tests/teamcity/teamcity_messages.cpp b/spine-c/spine-c-unit-tests/teamcity/teamcity_messages.cpp new file mode 100755 index 000000000..6f88d1ee9 --- /dev/null +++ b/spine-c/spine-c-unit-tests/teamcity/teamcity_messages.cpp @@ -0,0 +1,174 @@ +/* Copyright 2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Revision: 88625 $ +*/ + +#include +#include + +#include "teamcity_messages.h" + +using namespace std; + +namespace JetBrains { + +std::string getFlowIdFromEnvironment() { + const char *flowId = getenv("TEAMCITY_PROCESS_FLOW_ID"); + return flowId == NULL ? "" : flowId; +} + +bool underTeamcity() { + return getenv("TEAMCITY_PROJECT_NAME") != NULL; +} + +TeamcityMessages::TeamcityMessages() +: m_out(&cout) +{} + +void TeamcityMessages::setOutput(ostream &out) { + m_out = &out; +} + +string TeamcityMessages::escape(string s) { + string result; + + for (size_t i = 0; i < s.length(); i++) { + char c = s[i]; + + switch (c) { + case '\n': result.append("|n"); break; + case '\r': result.append("|r"); break; + case '\'': result.append("|'"); break; + case '|': result.append("||"); break; + case ']': result.append("|]"); break; + default: result.append(&c, 1); + } + } + + return result; +} + +void TeamcityMessages::openMsg(const string &name) { + // endl for http://jetbrains.net/tracker/issue/TW-4412 + *m_out << endl << "##teamcity[" << name; +} + +void TeamcityMessages::closeMsg() { + *m_out << "]"; + // endl for http://jetbrains.net/tracker/issue/TW-4412 + *m_out << endl; + m_out->flush(); +} + +void TeamcityMessages::writeProperty(string name, string value) { + *m_out << " " << name << "='" << escape(value) << "'"; +} + +void TeamcityMessages::suiteStarted(string name, string flowid) { + openMsg("testSuiteStarted"); + writeProperty("name", name); + if(flowid.length() > 0) { + writeProperty("flowId", flowid); + } + + closeMsg(); +} + +void TeamcityMessages::suiteFinished(string name, string flowid) { + openMsg("testSuiteFinished"); + writeProperty("name", name); + if(flowid.length() > 0) { + writeProperty("flowId", flowid); + } + + closeMsg(); +} + +void TeamcityMessages::testStarted(string name, string flowid) { + openMsg("testStarted"); + writeProperty("name", name); + if(flowid.length() > 0) { + writeProperty("flowId", flowid); + } + + closeMsg(); +} + +void TeamcityMessages::testFinished(string name, int durationMs, string flowid) { + openMsg("testFinished"); + + writeProperty("name", name); + + if(flowid.length() > 0) { + writeProperty("flowId", flowid); + } + + if(durationMs >= 0) { + stringstream out; + out << durationMs; + writeProperty("duration", out.str()); + } + + closeMsg(); +} + +void TeamcityMessages::testFailed(string name, string message, string details, string flowid) { + openMsg("testFailed"); + writeProperty("name", name); + writeProperty("message", message); + writeProperty("details", details); + if(flowid.length() > 0) { + writeProperty("flowId", flowid); + } + + closeMsg(); +} + +void TeamcityMessages::testIgnored(std::string name, std::string message, string flowid) { + openMsg("testIgnored"); + writeProperty("name", name); + writeProperty("message", message); + if(flowid.length() > 0) { + writeProperty("flowId", flowid); + } + + closeMsg(); +} + +void TeamcityMessages::messageError(const std::string& text) +{ + openMsg("message"); + writeProperty("text", text); + writeProperty("status", "ERROR"); + closeMsg(); +} + +void TeamcityMessages::messageWarning(const std::string& text) +{ + openMsg("message"); + writeProperty("text", text); + writeProperty("status", "WARNING"); + closeMsg(); +} + +void TeamcityMessages::messageNormal(const std::string& text) +{ + openMsg("message"); + writeProperty("text", text); + writeProperty("status", "NORMAL"); + closeMsg(); +} + +} diff --git a/spine-c/spine-c-unit-tests/teamcity/teamcity_messages.h b/spine-c/spine-c-unit-tests/teamcity/teamcity_messages.h new file mode 100755 index 000000000..36ad80797 --- /dev/null +++ b/spine-c/spine-c-unit-tests/teamcity/teamcity_messages.h @@ -0,0 +1,59 @@ +/* Copyright 2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Revision: 88625 $ +*/ + +#ifndef H_TEAMCITY_MESSAGES +#define H_TEAMCITY_MESSAGES + +#include +#include + +namespace JetBrains { + +std::string getFlowIdFromEnvironment(); +bool underTeamcity(); + +class TeamcityMessages { + std::ostream *m_out; + +protected: + std::string escape(std::string s); + + void openMsg(const std::string &name); + void writeProperty(std::string name, std::string value); + void closeMsg(); + +public: + TeamcityMessages(); + + void setOutput(std::ostream &); + + void suiteStarted(std::string name, std::string flowid = ""); + void suiteFinished(std::string name, std::string flowid = ""); + + void testStarted(std::string name, std::string flowid = ""); + void testFailed(std::string name, std::string message, std::string details, std::string flowid = ""); + void testIgnored(std::string name, std::string message, std::string flowid = ""); + void testFinished(std::string name, int durationMs = -1, std::string flowid = ""); + + void messageError(const std::string& text); + void messageWarning(const std::string& text); + void messageNormal(const std::string& text); +}; + +} + +#endif /* H_TEAMCITY_MESSAGES */ diff --git a/spine-c/spine-c-unit-tests/tests/CPP_InterfaceTestFixture.cpp b/spine-c/spine-c-unit-tests/tests/CPP_InterfaceTestFixture.cpp new file mode 100755 index 000000000..dde75c363 --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/CPP_InterfaceTestFixture.cpp @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////// +// filename: C_InterfaceTestFixture.cpp +// +// notes: There is no C++ interface! +// +///////////////////////////////////////////////////////////////////// + +#include "CPP_InterfaceTestFixture.h" + +CPP_InterfaceTestFixture::~CPP_InterfaceTestFixture() +{ + finalize(); +} + +void CPP_InterfaceTestFixture::initialize() +{ + // on a Per- Fixture Basis, before Test execution +} + +void CPP_InterfaceTestFixture::finalize() +{ + // on a Per- Fixture Basis, after all tests pass/fail +} + +void CPP_InterfaceTestFixture::setUp() +{ + // Setup on Per-Test Basis +} + +void CPP_InterfaceTestFixture::tearDown() +{ + // Tear Down on Per-Test Basis +} + +void CPP_InterfaceTestFixture::spineboyTestCase() +{ + // There is no C++ interface. +} + +void CPP_InterfaceTestFixture::raptorTestCase() +{ + // There is no C++ interface. +} + +void CPP_InterfaceTestFixture::goblinsTestCase() +{ + // No c++ interface +} diff --git a/spine-c/spine-c-unit-tests/tests/CPP_InterfaceTestFixture.h b/spine-c/spine-c-unit-tests/tests/CPP_InterfaceTestFixture.h new file mode 100755 index 000000000..8dc5fed36 --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/CPP_InterfaceTestFixture.h @@ -0,0 +1,47 @@ +#pragma once +////////////////////////////////////////////////////////////////////// +// filename: C_InterfaceTestFixture.h +// +// purpose: Run example animations for regression testing +// on "C++" interface to make sure modifications to "C" +// interface doesn't cause memory leaks or regression +// errors. +///////////////////////////////////////////////////////////////////// + +#include "MiniCppUnit.hxx" +#include "TestOptions.h" + +class CPP_InterfaceTestFixture : public TestFixture < CPP_InterfaceTestFixture > +{ +public: + TEST_FIXTURE(CPP_InterfaceTestFixture){ + TEST_CASE(spineboyTestCase); + TEST_CASE(raptorTestCase); + TEST_CASE(goblinsTestCase); + + initialize(); + } + + virtual ~CPP_InterfaceTestFixture(); + + ////////////////////////////////////////////////////////////////////////// + // Test Cases + ////////////////////////////////////////////////////////////////////////// +public: + void spineboyTestCase(); + void raptorTestCase(); + void goblinsTestCase(); + + ////////////////////////////////////////////////////////////////////////// + // test fixture setup + ////////////////////////////////////////////////////////////////////////// + void initialize(); + void finalize(); +public: + virtual void setUp(); + virtual void tearDown(); + +}; +#if defined(gForceAllTests) || defined(gCPPInterfaceTestFixture) +REGISTER_FIXTURE(CPP_InterfaceTestFixture); +#endif diff --git a/spine-c/spine-c-unit-tests/tests/C_InterfaceTestFixture.cpp b/spine-c/spine-c-unit-tests/tests/C_InterfaceTestFixture.cpp new file mode 100755 index 000000000..56f99b6e3 --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/C_InterfaceTestFixture.cpp @@ -0,0 +1,123 @@ +#include "C_InterfaceTestFixture.h" +#include "SpineEventMonitor.h" + +#include "spine/spine.h" +#include + +#include "KMemory.h" // last include + +#define SPINEBOY_JSON "testdata/spineboy/spineboy.json" +#define SPINEBOY_ATLAS "testdata/spineboy/spineboy.atlas" + +#define RAPTOR_JSON "testdata/raptor/raptor.json" +#define RAPTOR_ATLAS "testdata/raptor/raptor.atlas" + +#define GOBLINS_JSON "testdata/goblins/goblins.json" +#define GOBLINS_ATLAS "testdata/goblins/goblins.atlas" + +#define MAX_RUN_TIME 6000 // equal to about 100 seconds of execution + +void C_InterfaceTestFixture::setUp() +{ +} + +void C_InterfaceTestFixture::tearDown() +{ +} + +static spSkeletonData* readSkeletonJsonData(const char* filename, spAtlas* atlas) { + spSkeletonJson* json = spSkeletonJson_create(atlas); + ASSERT(json != nullptr); + + spSkeletonData* skeletonData = spSkeletonJson_readSkeletonDataFile(json, filename); + ASSERT(skeletonData != nullptr); + + spSkeletonJson_dispose(json); + return skeletonData; +} + +typedef std::vector AnimList; + +static size_t enumerateAnimations(AnimList& outList, spSkeletonData* skeletonData) +{ + if (skeletonData){ + + for (int n = 0; n < skeletonData->animationsCount; n++) + outList.push_back(skeletonData->animations[n]->name); + } + + return outList.size(); +} + +static void testRunner(const char* jsonName, const char* atlasName) +{ + /////////////////////////////////////////////////////////////////////////// + // Global Animation Information + spAtlas* atlas = spAtlas_createFromFile(atlasName, 0); + ASSERT(atlas != nullptr); + + spSkeletonData* skeletonData = readSkeletonJsonData(jsonName, atlas); + ASSERT(skeletonData != nullptr); + + spAnimationStateData* stateData = spAnimationStateData_create(skeletonData); + ASSERT(stateData != nullptr); + stateData->defaultMix = 0.2f; // force mixing + + /////////////////////////////////////////////////////////////////////////// + // Animation Instance + spSkeleton* skeleton = spSkeleton_create(skeletonData); + ASSERT(skeleton != nullptr); + + spAnimationState* state = spAnimationState_create(stateData); + ASSERT(state != nullptr); + + + /////////////////////////////////////////////////////////////////////////// + // Run animation + spSkeleton_setToSetupPose(skeleton); + SpineEventMonitor eventMonitor(state); +// eventMonitor.SetDebugLogging(true); + + + AnimList anims; // Let's chain all the animations together as a test + size_t count = enumerateAnimations(anims, skeletonData); + if (count > 0) spAnimationState_setAnimationByName(state, 0, anims[0].c_str(), false); + for (size_t i = 1; i < count; ++i) { + spAnimationState_addAnimationByName(state, 0, anims[i].c_str(), false, 0.0f); + } + + // Run Loop + for (int i = 0; i < MAX_RUN_TIME && eventMonitor.isAnimationPlaying(); ++i) { + const float timeSlice = 1.0f / 60.0f; + spSkeleton_update(skeleton, timeSlice); + spAnimationState_update(state, timeSlice); + spAnimationState_apply(state, skeleton); + } + + + /////////////////////////////////////////////////////////////////////////// + // Dispose Instance + spSkeleton_dispose(skeleton); + spAnimationState_dispose(state); + + /////////////////////////////////////////////////////////////////////////// + // Dispose Global + spAnimationStateData_dispose(stateData); + spSkeletonData_dispose(skeletonData); + spAtlas_dispose(atlas); +} + +void C_InterfaceTestFixture::spineboyTestCase() +{ + testRunner(SPINEBOY_JSON, SPINEBOY_ATLAS); +} + +void C_InterfaceTestFixture::raptorTestCase() +{ + testRunner(RAPTOR_JSON, RAPTOR_ATLAS); +} + +void C_InterfaceTestFixture::goblinsTestCase() +{ + testRunner(GOBLINS_JSON, GOBLINS_ATLAS); +} diff --git a/spine-c/spine-c-unit-tests/tests/C_InterfaceTestFixture.h b/spine-c/spine-c-unit-tests/tests/C_InterfaceTestFixture.h new file mode 100755 index 000000000..2f30d2bea --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/C_InterfaceTestFixture.h @@ -0,0 +1,33 @@ +#pragma once +////////////////////////////////////////////////////////////////////// +// filename: C_InterfaceTestFixture.h +// +// purpose: Run example animations for regression testing +// on "C" interface +///////////////////////////////////////////////////////////////////// + +#include "TestOptions.h" +#include "MiniCppUnit.hxx" + +class C_InterfaceTestFixture : public TestFixture +{ +public: + TEST_FIXTURE(C_InterfaceTestFixture) + { + // enable/disable individual tests here + TEST_CASE(spineboyTestCase); + TEST_CASE(raptorTestCase); + TEST_CASE(goblinsTestCase); + } + +public: + virtual void setUp(); + virtual void tearDown(); + + void spineboyTestCase(); + void raptorTestCase(); + void goblinsTestCase(); +}; +#if defined(gForceAllTests) || defined(gCInterfaceTestFixture) +REGISTER_FIXTURE(C_InterfaceTestFixture); +#endif \ No newline at end of file diff --git a/spine-c/spine-c-unit-tests/tests/EmptyTestFixture.cpp b/spine-c/spine-c-unit-tests/tests/EmptyTestFixture.cpp new file mode 100755 index 000000000..d2260b7d5 --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/EmptyTestFixture.cpp @@ -0,0 +1,25 @@ +#include "EmptyTestFixture.h" + +#include "KMemory.h" // Last include + + +void EmptyTestFixture::setUp() +{ +} + +void EmptyTestFixture::tearDown() +{ +} + +void EmptyTestFixture::emptyTestCase_1() +{ + // char* pLeak = new char[256]; // test leak detector +} + +void EmptyTestFixture::emptyTestCase_2() +{ +} + +void EmptyTestFixture::emptyTestCase_3() +{ +} diff --git a/spine-c/spine-c-unit-tests/tests/EmptyTestFixture.h b/spine-c/spine-c-unit-tests/tests/EmptyTestFixture.h new file mode 100755 index 000000000..c11cfd5f2 --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/EmptyTestFixture.h @@ -0,0 +1,26 @@ +#pragma once +#include "TestOptions.h" +#include "MiniCppUnit.hxx" + +class EmptyTestFixture : public TestFixture +{ +public: + TEST_FIXTURE(EmptyTestFixture) + { + // enable/disable individual tests here + TEST_CASE(emptyTestCase_1); + TEST_CASE(emptyTestCase_2); + TEST_CASE(emptyTestCase_3); + } + +public: + virtual void setUp(); + virtual void tearDown(); + + void emptyTestCase_1(); + void emptyTestCase_2(); + void emptyTestCase_3(); +}; +#if defined(gForceAllTests) || defined(gEmptyTestFixture) +REGISTER_FIXTURE(EmptyTestFixture); +#endif \ No newline at end of file diff --git a/spine-c/spine-c-unit-tests/tests/MemoryTestFixture.cpp b/spine-c/spine-c-unit-tests/tests/MemoryTestFixture.cpp new file mode 100755 index 000000000..2f11c4183 --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/MemoryTestFixture.cpp @@ -0,0 +1,182 @@ +#include "MemoryTestFixture.h" +#include "SpineEventMonitor.h" + +#include "spine/spine.h" + +#include "KMemory.h" // last include + +#define SPINEBOY_JSON "testdata/spineboy/spineboy.json" +#define SPINEBOY_ATLAS "testdata/spineboy/spineboy.atlas" + +#define MAX_RUN_TIME 6000 // equal to about 100 seconds of execution + +MemoryTestFixture::~MemoryTestFixture() +{ + finalize(); +} + +void MemoryTestFixture::initialize() +{ + // on a Per- Fixture Basis, before Test execution +} + +void MemoryTestFixture::finalize() +{ + // on a Per- Fixture Basis, after all tests pass/fail +} + +void MemoryTestFixture::setUp() +{ + // Setup on Per-Test Basis +} + +void MemoryTestFixture::tearDown() +{ + // Tear Down on Per-Test Basis +} + + +////////////////////////////////////////////////////////////////////////// +// Helper methods +static spSkeletonData* readSkeletonJsonData(const char* filename, spAtlas* atlas) { + spSkeletonJson* json = spSkeletonJson_create(atlas); + ASSERT(json != nullptr); + + spSkeletonData* skeletonData = spSkeletonJson_readSkeletonDataFile(json, filename); + ASSERT(skeletonData != nullptr); + + spSkeletonJson_dispose(json); + return skeletonData; +} + +static void LoadSpineboyExample(spAtlas* &atlas, spSkeletonData* &skeletonData, spAnimationStateData* &stateData, spSkeleton* &skeleton, spAnimationState* &state) +{ + /////////////////////////////////////////////////////////////////////////// + // Global Animation Information + atlas = spAtlas_createFromFile(SPINEBOY_ATLAS, 0); + ASSERT(atlas != nullptr); + + skeletonData = readSkeletonJsonData(SPINEBOY_JSON, atlas); + ASSERT(skeletonData != nullptr); + + stateData = spAnimationStateData_create(skeletonData); + ASSERT(stateData != nullptr); + stateData->defaultMix = 0.4f; // force mixing + + /////////////////////////////////////////////////////////////////////////// + // Animation Instance + skeleton = spSkeleton_create(skeletonData); + ASSERT(skeleton != nullptr); + + state = spAnimationState_create(stateData); + ASSERT(state != nullptr); +} + +static void DisposeAll(spSkeleton* skeleton, spAnimationState* state, spAnimationStateData* stateData, spSkeletonData* skeletonData, spAtlas* atlas) +{ + /////////////////////////////////////////////////////////////////////////// + // Dispose Instance + spSkeleton_dispose(skeleton); + spAnimationState_dispose(state); + + /////////////////////////////////////////////////////////////////////////// + // Dispose Global + spAnimationStateData_dispose(stateData); + spSkeletonData_dispose(skeletonData); + spAtlas_dispose(atlas); +} + + +////////////////////////////////////////////////////////////////////////// +// Reproduce Memory leak as described in Issue #776 +// https://github.com/EsotericSoftware/spine-runtimes/issues/776 +void MemoryTestFixture::reproduceIssue_776() +{ + spAtlas* atlas = nullptr; + spSkeletonData* skeletonData = nullptr; + spAnimationStateData* stateData = nullptr; + spSkeleton* skeleton = nullptr; + spAnimationState* state = nullptr; + + ////////////////////////////////////////////////////////////////////////// + // Initialize Animations + LoadSpineboyExample(atlas, skeletonData, stateData, skeleton, state); + + /////////////////////////////////////////////////////////////////////////// + // Run animation + spSkeleton_setToSetupPose(skeleton); + InterruptMonitor eventMonitor(state); + //eventMonitor.SetDebugLogging(true); + + // Interrupt the animation on this specific sequence of spEventType(s) + eventMonitor + .AddInterruptEvent(SP_ANIMATION_INTERRUPT, "jump") + .AddInterruptEvent(SP_ANIMATION_START); + + spAnimationState_setAnimationByName(state, 0, "walk", true); + spAnimationState_addAnimationByName(state, 0, "jump", false, 0.0f); + spAnimationState_addAnimationByName(state, 0, "run", true, 0.0f); + spAnimationState_addAnimationByName(state, 0, "jump", false, 3.0f); + spAnimationState_addAnimationByName(state, 0, "walk", true, 0.0f); + spAnimationState_addAnimationByName(state, 0, "idle", false, 1.0f); + + for (int i = 0; i < MAX_RUN_TIME && eventMonitor.isAnimationPlaying(); ++i) { + const float timeSlice = 1.0f / 60.0f; + spSkeleton_update(skeleton, timeSlice); + spAnimationState_update(state, timeSlice); + spAnimationState_apply(state, skeleton); + } + + ////////////////////////////////////////////////////////////////////////// + // Cleanup Animations + DisposeAll(skeleton, state, stateData, skeletonData, atlas); +} + +void MemoryTestFixture::reproduceIssue_777() +{ + spAtlas* atlas = nullptr; + spSkeletonData* skeletonData = nullptr; + spAnimationStateData* stateData = nullptr; + spSkeleton* skeleton = nullptr; + spAnimationState* state = nullptr; + + ////////////////////////////////////////////////////////////////////////// + // Initialize Animations + LoadSpineboyExample(atlas, skeletonData, stateData, skeleton, state); + + /////////////////////////////////////////////////////////////////////////// + // Run animation + spSkeleton_setToSetupPose(skeleton); + SpineEventMonitor eventMonitor(state); + //eventMonitor.SetDebugLogging(true); + + // Set Animation and Play for 5 frames + spAnimationState_setAnimationByName(state, 0, "walk", true); + for (int i = 0; i < 5; ++i) { + const float timeSlice = 1.0f / 60.0f; + spSkeleton_update(skeleton, timeSlice); + spAnimationState_update(state, timeSlice); + spAnimationState_apply(state, skeleton); + } + + // Change animation twice in a row + spAnimationState_setAnimationByName(state, 0, "walk", false); + spAnimationState_setAnimationByName(state, 0, "run", false); + + // run normal update + for (int i = 0; i < 5; ++i) { + const float timeSlice = 1.0f / 60.0f; + spSkeleton_update(skeleton, timeSlice); + spAnimationState_update(state, timeSlice); + spAnimationState_apply(state, skeleton); + } + + // Now we'd lose mixingFrom (the first "walk" entry we set above) and should leak + spAnimationState_setAnimationByName(state, 0, "run", false); + + ////////////////////////////////////////////////////////////////////////// + // Cleanup Animations + DisposeAll(skeleton, state, stateData, skeletonData, atlas); +} + + diff --git a/spine-c/spine-c-unit-tests/tests/MemoryTestFixture.h b/spine-c/spine-c-unit-tests/tests/MemoryTestFixture.h new file mode 100755 index 000000000..d71ece96a --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/MemoryTestFixture.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////// +// filename: MemoryTestFixture.h +// +// purpose: Reproduce Memory Error/Leak Bugs to help debug +// and for regression testing +///////////////////////////////////////////////////////////////////// + +#pragma once +#include "MiniCppUnit.hxx" +#include "TestOptions.h" + +class MemoryTestFixture : public TestFixture < MemoryTestFixture > +{ +public: + TEST_FIXTURE(MemoryTestFixture){ + + // Comment out here to disable individual test cases + TEST_CASE(reproduceIssue_776); + TEST_CASE(reproduceIssue_777); + + initialize(); + } + + virtual ~MemoryTestFixture(); + + ////////////////////////////////////////////////////////////////////////// + // Test Cases + ////////////////////////////////////////////////////////////////////////// +public: + void reproduceIssue_776(); + void reproduceIssue_777(); + + ////////////////////////////////////////////////////////////////////////// + // test fixture setup + ////////////////////////////////////////////////////////////////////////// + void initialize(); + void finalize(); +public: + virtual void setUp(); + virtual void tearDown(); +}; +#if defined(gForceAllTests) || defined(gMemoryTestFixture) +REGISTER_FIXTURE(MemoryTestFixture); +#endif \ No newline at end of file diff --git a/spine-c/spine-c-unit-tests/tests/SpineEventMonitor.cpp b/spine-c/spine-c-unit-tests/tests/SpineEventMonitor.cpp new file mode 100755 index 000000000..f13780868 --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/SpineEventMonitor.cpp @@ -0,0 +1,163 @@ +#include "SpineEventMonitor.h" + +#include "spine/spine.h" +#include "KString.h" + +#include "KMemory.h" // Last include + +SpineEventMonitor::SpineEventMonitor(spAnimationState* _pAnimationState /*= nullptr*/) +{ + bLogging = false; + RegisterListener(_pAnimationState); +} + +SpineEventMonitor::~SpineEventMonitor() +{ + pAnimState = nullptr; +} + +void SpineEventMonitor::RegisterListener(spAnimationState * _pAnimationState) +{ + if (_pAnimationState) { + _pAnimationState->rendererObject = this; + _pAnimationState->listener = (spAnimationStateListener)&SpineEventMonitor::spineAnimStateHandler; + } + pAnimState = _pAnimationState; +} + +bool SpineEventMonitor::isAnimationPlaying() +{ + if (pAnimState) + return spAnimationState_getCurrent(pAnimState, 0) != nullptr; + return false; +} + +void SpineEventMonitor::spineAnimStateHandler(spAnimationState * state, int type, spTrackEntry * entry, spEvent * event) +{ + if (state && state->rendererObject) { + SpineEventMonitor* pEventMonitor = (SpineEventMonitor*)state->rendererObject; + pEventMonitor->OnSpineAnimationStateEvent(state, type, entry, event); + } +} + +void SpineEventMonitor::OnSpineAnimationStateEvent(spAnimationState * state, int type, spTrackEntry * trackEntry, spEvent * event) +{ + const char* eventName = nullptr; + if (state == pAnimState) { // only monitor ours + switch(type) + { + case SP_ANIMATION_START: eventName = "SP_ANIMATION_START"; break; + case SP_ANIMATION_INTERRUPT: eventName = "SP_ANIMATION_INTERRUPT"; break; + case SP_ANIMATION_END: eventName = "SP_ANIMATION_END"; break; + case SP_ANIMATION_COMPLETE: eventName = "SP_ANIMATION_COMPLETE"; break; + case SP_ANIMATION_DISPOSE: eventName = "SP_ANIMATION_DISPOSE"; break; + case SP_ANIMATION_EVENT: eventName = "SP_ANIMATION_EVENT"; break; + default: + break; + } + + if (bLogging && eventName && trackEntry && trackEntry->animation && trackEntry->animation->name) + KOutputDebug(DEBUGLVL, "[%s : '%s']\n", eventName, trackEntry->animation->name);//*/ + } +} + + + +InterruptMonitor::InterruptMonitor(spAnimationState * _pAnimationState): + SpineEventMonitor(_pAnimationState) +{ + bForceInterrupt = false; + mEventStackCursor = 0; // cursor used to track events +} + +bool InterruptMonitor::isAnimationPlaying() +{ + return !bForceInterrupt && SpineEventMonitor::isAnimationPlaying(); +} + +// Stops the animation on any occurance of the spEventType +InterruptMonitor& InterruptMonitor::AddInterruptEvent(int theEventType) +{ + InterruptEvent ev; + ev.mEventType = theEventType; + mEventStack.push_back(ev); + return *this; +} + +// Stops the animation when the [spEventType : 'animationName'] occurs +InterruptMonitor& InterruptMonitor::AddInterruptEvent(int theEventType, const std::string & theAnimationName) +{ + InterruptEvent ev; + ev.mEventType = theEventType; + ev.mAnimName = theAnimationName; + mEventStack.push_back(ev); + return *this; +} + +// stops the first encounter of spEventType on the specified TrackEntry +InterruptMonitor& InterruptMonitor::AddInterruptEvent(int theEventType, spTrackEntry * theTrackEntry) +{ + InterruptEvent ev; + ev.mEventType = theEventType; + ev.mTrackEntry = theTrackEntry; + mEventStack.push_back(ev); + return *this; +} + +// Stops on the first SP_ANIMATION_EVENT with the string payload of 'theEventTriggerName' +InterruptMonitor& InterruptMonitor::AddInterruptEventTrigger(const std::string & theEventTriggerName) +{ + InterruptEvent ev; + ev.mEventType = SP_ANIMATION_EVENT; + ev.mEventName = theEventTriggerName; + mEventStack.push_back(ev); + return *this; +} + +void InterruptMonitor::OnSpineAnimationStateEvent(spAnimationState * state, int type, spTrackEntry * trackEntry, spEvent * event) +{ + SpineEventMonitor::OnSpineAnimationStateEvent(state, type, trackEntry, event); + + if (mEventStackCursor < mEventStack.size()) { + if (mEventStack[mEventStackCursor].matches(state, type, trackEntry, event)) + ++mEventStackCursor; + + if (mEventStackCursor >= mEventStack.size()) { + bForceInterrupt = true; + OnMatchingComplete(); + } + } +} + +inline bool InterruptMonitor::InterruptEvent::matches(spAnimationState * state, int type, spTrackEntry * trackEntry, spEvent * event) { + + // Must match spEventType {SP_ANIMATION_START, SP_ANIMATION_INTERRUPT, SP_ANIMATION_END, SP_ANIMATION_COMPLETE, SP_ANIMATION_DISPOSE, SP_ANIMATION_EVENT } + if (mEventType == type) { + + // Looking for specific TrackEntry by pointer + if (mTrackEntry != nullptr) { + return mTrackEntry == trackEntry; + } + + // looking for Animation Track by name + if (!mAnimName.empty()) { + if (trackEntry && trackEntry->animation && trackEntry->animation->name) { + if (CompareNoCase(trackEntry->animation->name, mAnimName) == 0) { + return true; + } + } + return false; + } + + // looking for Event String Text + if (!mEventName.empty()) { + if (event && event->stringValue) { + return (CompareNoCase(event->stringValue, mEventName) == 0); + } + return false; + } + + return true; // waiting for ANY spEventType that matches + } + return false; +} diff --git a/spine-c/spine-c-unit-tests/tests/SpineEventMonitor.h b/spine-c/spine-c-unit-tests/tests/SpineEventMonitor.h new file mode 100755 index 000000000..287e67d1d --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/SpineEventMonitor.h @@ -0,0 +1,122 @@ +////////////////////////////////////////////////////////////////////// +// filename: SpineEventMonitor.h +// +// purpose: Monitor spAnimationState Events +///////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include + +// forward declarations +typedef struct spAnimationState spAnimationState; +typedef struct spTrackEntry spTrackEntry; +typedef struct spEvent spEvent; + +////////////////////////////////////////////////////////////////////// +// class: SpineEventMonitor +// +// purpose: Monitor spAnimationState Events and report when there +// are no more spTrackEntry(s) waiting to play on track 0; +// +// Also allows for debug printing of Events to console. +///////////////////////////////////////////////////////////////////// +class SpineEventMonitor +{ +public: + SpineEventMonitor(spAnimationState* _pAnimationState = nullptr); + virtual ~SpineEventMonitor(); + + void RegisterListener(spAnimationState* _pAnimationState); + + void SetDebugLogging(bool val) { bLogging = val; } + bool GetDebugLogging() { return bLogging; } + + virtual bool isAnimationPlaying(); + +protected: + static void spineAnimStateHandler(spAnimationState* state, int type, spTrackEntry* entry, spEvent* event); + virtual void OnSpineAnimationStateEvent(spAnimationState* state, int type, spTrackEntry* trackEntry, spEvent* event); + +protected: + spAnimationState *pAnimState; + bool bLogging; +}; + +////////////////////////////////////////////////////////////////////// +// class: InterruptMonitor +// +// purpose: Allows a programmer to interrupt/stop the updating +// of an animation based on a specific sequence of +// events generated by the animation. +///////////////////////////////////////////////////////////////////// +class InterruptMonitor : public SpineEventMonitor +{ +private: + struct InterruptEvent + { + InterruptEvent() { + mEventType = -1; // invalid + mTrackEntry = nullptr; + } + + bool matches(spAnimationState* state, int type, spTrackEntry* trackEntry, spEvent* event); + + std::string mAnimName; + int mEventType; + spTrackEntry* mTrackEntry; + std::string mEventName; + }; + typedef std::vector InterruptEventStack; + + +public: + InterruptMonitor(spAnimationState* _pAnimationState = nullptr); + ~InterruptMonitor() {} + + virtual bool isAnimationPlaying() override; + +public: + InterruptMonitor& AddInterruptEvent(int theEventType); + InterruptMonitor& AddInterruptEvent(int theEventType, const std::string& theAnimationName); + InterruptMonitor& AddInterruptEvent(int theEventType, spTrackEntry* theTrackEntry); + InterruptMonitor& AddInterruptEventTrigger(const std::string& theEventTriggerName); + +protected: + virtual void OnSpineAnimationStateEvent(spAnimationState* state, int type, spTrackEntry* trackEntry, spEvent* event) override; + virtual void OnMatchingComplete() {} + +protected: + bool bForceInterrupt; + InterruptEventStack mEventStack; // must match these events in this order + size_t mEventStackCursor; +}; + +/* + +EXAMPLE +======= + +SpineEventMonitor eventMonitor(state); +eventMonitor.SetDebugLogging(true); + +while(eventMonitor.isAnimationPlaying()){ + // update... +} + + + +EXAMPLE +======= + +InterruptMonitor eventMonitor(state); +eventMonitor.SetDebugLogging(true); + +// Interrupt the animation on this specific sequence of spEventType(s) +eventMonitor + .AddInterruptEvent(SP_ANIMATION_INTERRUPT, "jump") // First, wait for INTERRUPT signal on the 'jump' animation spTrackEntry + .AddInterruptEvent(SP_ANIMATION_START); // Then, stop on any following START signal + + +*/ \ No newline at end of file diff --git a/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.cpp b/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.cpp new file mode 100755 index 000000000..9c2a964a9 --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.cpp @@ -0,0 +1,26 @@ +#include "CPP_InterfaceTestFixture.h" + +CPP_InterfaceTestFixture::~CPP_InterfaceTestFixture() +{ + finalize(); +} + +void CPP_InterfaceTestFixture::initialize() +{ + // on a Per- Fixture Basis, before Test execution +} + +void CPP_InterfaceTestFixture::finalize() +{ + // on a Per- Fixture Basis, after all tests pass/fail +} + +void CPP_InterfaceTestFixture::setUp() +{ + // Setup on Per-Test Basis +} + +void CPP_InterfaceTestFixture::tearDown() +{ + // Tear Down on Per-Test Basis +} diff --git a/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.h b/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.h new file mode 100755 index 000000000..5fcb99c79 --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.h @@ -0,0 +1,30 @@ +#pragma once +#include "MiniCppUnit.hxx" + +class CPP_InterfaceTestFixture : public TestFixture < CPP_InterfaceTestFixture > +{ +public: + TEST_FIXTURE(CPP_InterfaceTestFixture){ + //TEST_CASE(parseJSON); + + initialize(); + } + + virtual ~CPP_InterfaceTestFixture(); + + ////////////////////////////////////////////////////////////////////////// + // Test Cases + ////////////////////////////////////////////////////////////////////////// +public: + // void parseJSON(); + + ////////////////////////////////////////////////////////////////////////// + // test fixture setup + ////////////////////////////////////////////////////////////////////////// + void initialize(); + void finalize(); +public: + virtual void setUp(); + virtual void tearDown(); +}; +REGISTER_FIXTURE(CPP_InterfaceTestFixture); \ No newline at end of file diff --git a/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/_TestFixture.cpp b/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/_TestFixture.cpp new file mode 100755 index 000000000..67780f31a --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/_TestFixture.cpp @@ -0,0 +1,26 @@ +#include "[[FIXTURE_TYPE]].h" + +[[FIXTURE_TYPE]]::~[[FIXTURE_TYPE]]() +{ + finalize(); +} + +void [[FIXTURE_TYPE]]::initialize() +{ + // on a Per- Fixture Basis, before Test execution +} + +void [[FIXTURE_TYPE]]::finalize() +{ + // on a Per- Fixture Basis, after all tests pass/fail +} + +void [[FIXTURE_TYPE]]::setUp() +{ + // Setup on Per-Test Basis +} + +void [[FIXTURE_TYPE]]::tearDown() +{ + // Tear Down on Per-Test Basis +} diff --git a/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/_TestFixture.h b/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/_TestFixture.h new file mode 100755 index 000000000..3103cda85 --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/_TestFixture.h @@ -0,0 +1,30 @@ +#pragma once +#include "MiniCppUnit.hxx" + +class [[FIXTURE_TYPE]] : public TestFixture < [[FIXTURE_TYPE]] > +{ +public: + TEST_FIXTURE([[FIXTURE_TYPE]]){ + //TEST_CASE(parseJSON); + + initialize(); + } + + virtual ~[[FIXTURE_TYPE]](); + + ////////////////////////////////////////////////////////////////////////// + // Test Cases + ////////////////////////////////////////////////////////////////////////// +public: + // void parseJSON(); + + ////////////////////////////////////////////////////////////////////////// + // test fixture setup + ////////////////////////////////////////////////////////////////////////// + void initialize(); + void finalize(); +public: + virtual void setUp(); + virtual void tearDown(); +}; +REGISTER_FIXTURE([[FIXTURE_TYPE]]); \ No newline at end of file diff --git a/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/fnr.exe b/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/fnr.exe new file mode 100755 index 0000000000000000000000000000000000000000..548fc5d91fbc747827dbcc53514793a052e1099f GIT binary patch literal 185200 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[>4`JN{}c&;FiV|m>|slNX# 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 literal 0 HcmV?d00001 diff --git a/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/makeFixture.bat b/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/makeFixture.bat new file mode 100755 index 000000000..634154a29 --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/TestFixtureGenerator/makeFixture.bat @@ -0,0 +1,17 @@ +@echo off +if "%1"=="" goto blank + +copy "_TestFixture.cpp" "%1TestFixture.cpp" +copy "_TestFixture.h" "%1TestFixture.h" + + +fnr --cl --find "[[FIXTURE_TYPE]]" --replace "%1TestFixture" --fileMask "%1TestFixture.cpp" --dir %cd% +fnr --cl --find "[[FIXTURE_TYPE]]" --replace "%1TestFixture" --fileMask "%1TestFixture.h" --dir %cd% + +goto done + +:blank +echo Usage: +echo %~n0 FixtureTypeName + +:done \ No newline at end of file diff --git a/spine-c/spine-c-unit-tests/tests/TestOptions.h b/spine-c/spine-c-unit-tests/tests/TestOptions.h new file mode 100755 index 000000000..7f00ffbb7 --- /dev/null +++ b/spine-c/spine-c-unit-tests/tests/TestOptions.h @@ -0,0 +1,32 @@ +#pragma once + +////////////////////////////////////////////////////////////////////////// +// Force all Tests to 'ON.' Use this for final 'Regression' Testing. + +//#define gForceAllTests + +//#define TURN_ON_ALL_TESTS // Comment this line out to switch to fast testing only + +#ifdef TURN_ON_ALL_TESTS +////////////////////////////////////////////////////////////////////////// +// All tests are ON by default, but you can turn off individual tests. + +#define gEmptyTestFixture +#define gCInterfaceTestFixture +#define gCPPInterfaceTestFixture +#define gMemoryTestFixture + + +#else + +////////////////////////////////////////////////////////////////////////// +// Slow Tests are disabled by default. Use this section to turn on +// Individual tests. +#define gEmptyTestFixture // Fast + +#define gCInterfaceTestFixture // slow +#define gCPPInterfaceTestFixture // fast + +#define gMemoryTestFixture // medium + +#endif \ No newline at end of file diff --git a/spine-c/include/spine/Animation.h b/spine-c/spine-c/include/spine/Animation.h similarity index 100% rename from spine-c/include/spine/Animation.h rename to spine-c/spine-c/include/spine/Animation.h diff --git a/spine-c/include/spine/AnimationState.h b/spine-c/spine-c/include/spine/AnimationState.h similarity index 100% rename from spine-c/include/spine/AnimationState.h rename to spine-c/spine-c/include/spine/AnimationState.h diff --git a/spine-c/include/spine/AnimationStateData.h b/spine-c/spine-c/include/spine/AnimationStateData.h similarity index 100% rename from spine-c/include/spine/AnimationStateData.h rename to spine-c/spine-c/include/spine/AnimationStateData.h diff --git a/spine-c/include/spine/Atlas.h b/spine-c/spine-c/include/spine/Atlas.h similarity index 100% rename from spine-c/include/spine/Atlas.h rename to spine-c/spine-c/include/spine/Atlas.h diff --git a/spine-c/include/spine/AtlasAttachmentLoader.h b/spine-c/spine-c/include/spine/AtlasAttachmentLoader.h similarity index 100% rename from spine-c/include/spine/AtlasAttachmentLoader.h rename to spine-c/spine-c/include/spine/AtlasAttachmentLoader.h diff --git a/spine-c/include/spine/Attachment.h b/spine-c/spine-c/include/spine/Attachment.h similarity index 100% rename from spine-c/include/spine/Attachment.h rename to spine-c/spine-c/include/spine/Attachment.h diff --git a/spine-c/include/spine/AttachmentLoader.h b/spine-c/spine-c/include/spine/AttachmentLoader.h similarity index 100% rename from spine-c/include/spine/AttachmentLoader.h rename to spine-c/spine-c/include/spine/AttachmentLoader.h diff --git a/spine-c/include/spine/Bone.h b/spine-c/spine-c/include/spine/Bone.h similarity index 100% rename from spine-c/include/spine/Bone.h rename to spine-c/spine-c/include/spine/Bone.h diff --git a/spine-c/include/spine/BoneData.h b/spine-c/spine-c/include/spine/BoneData.h similarity index 100% rename from spine-c/include/spine/BoneData.h rename to spine-c/spine-c/include/spine/BoneData.h diff --git a/spine-c/include/spine/BoundingBoxAttachment.h b/spine-c/spine-c/include/spine/BoundingBoxAttachment.h similarity index 100% rename from spine-c/include/spine/BoundingBoxAttachment.h rename to spine-c/spine-c/include/spine/BoundingBoxAttachment.h diff --git a/spine-c/include/spine/Event.h b/spine-c/spine-c/include/spine/Event.h similarity index 100% rename from spine-c/include/spine/Event.h rename to spine-c/spine-c/include/spine/Event.h diff --git a/spine-c/include/spine/EventData.h b/spine-c/spine-c/include/spine/EventData.h similarity index 100% rename from spine-c/include/spine/EventData.h rename to spine-c/spine-c/include/spine/EventData.h diff --git a/spine-c/include/spine/IkConstraint.h b/spine-c/spine-c/include/spine/IkConstraint.h similarity index 100% rename from spine-c/include/spine/IkConstraint.h rename to spine-c/spine-c/include/spine/IkConstraint.h diff --git a/spine-c/include/spine/IkConstraintData.h b/spine-c/spine-c/include/spine/IkConstraintData.h similarity index 100% rename from spine-c/include/spine/IkConstraintData.h rename to spine-c/spine-c/include/spine/IkConstraintData.h diff --git a/spine-c/include/spine/MeshAttachment.h b/spine-c/spine-c/include/spine/MeshAttachment.h similarity index 100% rename from spine-c/include/spine/MeshAttachment.h rename to spine-c/spine-c/include/spine/MeshAttachment.h diff --git a/spine-c/include/spine/PathAttachment.h b/spine-c/spine-c/include/spine/PathAttachment.h similarity index 100% rename from spine-c/include/spine/PathAttachment.h rename to spine-c/spine-c/include/spine/PathAttachment.h diff --git a/spine-c/include/spine/PathConstraint.h b/spine-c/spine-c/include/spine/PathConstraint.h similarity index 100% rename from spine-c/include/spine/PathConstraint.h rename to spine-c/spine-c/include/spine/PathConstraint.h diff --git a/spine-c/include/spine/PathConstraintData.h b/spine-c/spine-c/include/spine/PathConstraintData.h similarity index 100% rename from spine-c/include/spine/PathConstraintData.h rename to spine-c/spine-c/include/spine/PathConstraintData.h diff --git a/spine-c/include/spine/RegionAttachment.h b/spine-c/spine-c/include/spine/RegionAttachment.h similarity index 100% rename from spine-c/include/spine/RegionAttachment.h rename to spine-c/spine-c/include/spine/RegionAttachment.h diff --git a/spine-c/include/spine/Skeleton.h b/spine-c/spine-c/include/spine/Skeleton.h similarity index 100% rename from spine-c/include/spine/Skeleton.h rename to spine-c/spine-c/include/spine/Skeleton.h diff --git a/spine-c/include/spine/SkeletonBinary.h b/spine-c/spine-c/include/spine/SkeletonBinary.h similarity index 100% rename from spine-c/include/spine/SkeletonBinary.h rename to spine-c/spine-c/include/spine/SkeletonBinary.h diff --git a/spine-c/include/spine/SkeletonBounds.h b/spine-c/spine-c/include/spine/SkeletonBounds.h similarity index 100% rename from spine-c/include/spine/SkeletonBounds.h rename to spine-c/spine-c/include/spine/SkeletonBounds.h diff --git a/spine-c/include/spine/SkeletonData.h b/spine-c/spine-c/include/spine/SkeletonData.h similarity index 100% rename from spine-c/include/spine/SkeletonData.h rename to spine-c/spine-c/include/spine/SkeletonData.h diff --git a/spine-c/include/spine/SkeletonJson.h b/spine-c/spine-c/include/spine/SkeletonJson.h similarity index 100% rename from spine-c/include/spine/SkeletonJson.h rename to spine-c/spine-c/include/spine/SkeletonJson.h diff --git a/spine-c/include/spine/Skin.h b/spine-c/spine-c/include/spine/Skin.h similarity index 100% rename from spine-c/include/spine/Skin.h rename to spine-c/spine-c/include/spine/Skin.h diff --git a/spine-c/include/spine/Slot.h b/spine-c/spine-c/include/spine/Slot.h similarity index 100% rename from spine-c/include/spine/Slot.h rename to spine-c/spine-c/include/spine/Slot.h diff --git a/spine-c/include/spine/SlotData.h b/spine-c/spine-c/include/spine/SlotData.h similarity index 100% rename from spine-c/include/spine/SlotData.h rename to spine-c/spine-c/include/spine/SlotData.h diff --git a/spine-c/include/spine/TransformConstraint.h b/spine-c/spine-c/include/spine/TransformConstraint.h similarity index 100% rename from spine-c/include/spine/TransformConstraint.h rename to spine-c/spine-c/include/spine/TransformConstraint.h diff --git a/spine-c/include/spine/TransformConstraintData.h b/spine-c/spine-c/include/spine/TransformConstraintData.h similarity index 100% rename from spine-c/include/spine/TransformConstraintData.h rename to spine-c/spine-c/include/spine/TransformConstraintData.h diff --git a/spine-c/include/spine/VertexAttachment.h b/spine-c/spine-c/include/spine/VertexAttachment.h similarity index 100% rename from spine-c/include/spine/VertexAttachment.h rename to spine-c/spine-c/include/spine/VertexAttachment.h diff --git a/spine-c/include/spine/extension.h b/spine-c/spine-c/include/spine/extension.h similarity index 100% rename from spine-c/include/spine/extension.h rename to spine-c/spine-c/include/spine/extension.h diff --git a/spine-c/include/spine/spine.h b/spine-c/spine-c/include/spine/spine.h similarity index 100% rename from spine-c/include/spine/spine.h rename to spine-c/spine-c/include/spine/spine.h diff --git a/spine-c/src/spine/Animation.c b/spine-c/spine-c/src/spine/Animation.c similarity index 100% rename from spine-c/src/spine/Animation.c rename to spine-c/spine-c/src/spine/Animation.c diff --git a/spine-c/src/spine/AnimationState.c b/spine-c/spine-c/src/spine/AnimationState.c similarity index 100% rename from spine-c/src/spine/AnimationState.c rename to spine-c/spine-c/src/spine/AnimationState.c diff --git a/spine-c/src/spine/AnimationStateData.c b/spine-c/spine-c/src/spine/AnimationStateData.c similarity index 100% rename from spine-c/src/spine/AnimationStateData.c rename to spine-c/spine-c/src/spine/AnimationStateData.c diff --git a/spine-c/src/spine/Atlas.c b/spine-c/spine-c/src/spine/Atlas.c similarity index 100% rename from spine-c/src/spine/Atlas.c rename to spine-c/spine-c/src/spine/Atlas.c diff --git a/spine-c/src/spine/AtlasAttachmentLoader.c b/spine-c/spine-c/src/spine/AtlasAttachmentLoader.c similarity index 100% rename from spine-c/src/spine/AtlasAttachmentLoader.c rename to spine-c/spine-c/src/spine/AtlasAttachmentLoader.c diff --git a/spine-c/src/spine/Attachment.c b/spine-c/spine-c/src/spine/Attachment.c similarity index 100% rename from spine-c/src/spine/Attachment.c rename to spine-c/spine-c/src/spine/Attachment.c diff --git a/spine-c/src/spine/AttachmentLoader.c b/spine-c/spine-c/src/spine/AttachmentLoader.c similarity index 100% rename from spine-c/src/spine/AttachmentLoader.c rename to spine-c/spine-c/src/spine/AttachmentLoader.c diff --git a/spine-c/src/spine/Bone.c b/spine-c/spine-c/src/spine/Bone.c similarity index 100% rename from spine-c/src/spine/Bone.c rename to spine-c/spine-c/src/spine/Bone.c diff --git a/spine-c/src/spine/BoneData.c b/spine-c/spine-c/src/spine/BoneData.c similarity index 100% rename from spine-c/src/spine/BoneData.c rename to spine-c/spine-c/src/spine/BoneData.c diff --git a/spine-c/src/spine/BoundingBoxAttachment.c b/spine-c/spine-c/src/spine/BoundingBoxAttachment.c similarity index 100% rename from spine-c/src/spine/BoundingBoxAttachment.c rename to spine-c/spine-c/src/spine/BoundingBoxAttachment.c diff --git a/spine-c/src/spine/Event.c b/spine-c/spine-c/src/spine/Event.c similarity index 100% rename from spine-c/src/spine/Event.c rename to spine-c/spine-c/src/spine/Event.c diff --git a/spine-c/src/spine/EventData.c b/spine-c/spine-c/src/spine/EventData.c similarity index 100% rename from spine-c/src/spine/EventData.c rename to spine-c/spine-c/src/spine/EventData.c diff --git a/spine-c/src/spine/IkConstraint.c b/spine-c/spine-c/src/spine/IkConstraint.c similarity index 100% rename from spine-c/src/spine/IkConstraint.c rename to spine-c/spine-c/src/spine/IkConstraint.c diff --git a/spine-c/src/spine/IkConstraintData.c b/spine-c/spine-c/src/spine/IkConstraintData.c similarity index 100% rename from spine-c/src/spine/IkConstraintData.c rename to spine-c/spine-c/src/spine/IkConstraintData.c diff --git a/spine-c/src/spine/Json.c b/spine-c/spine-c/src/spine/Json.c similarity index 100% rename from spine-c/src/spine/Json.c rename to spine-c/spine-c/src/spine/Json.c diff --git a/spine-c/src/spine/Json.h b/spine-c/spine-c/src/spine/Json.h similarity index 100% rename from spine-c/src/spine/Json.h rename to spine-c/spine-c/src/spine/Json.h diff --git a/spine-c/src/spine/MeshAttachment.c b/spine-c/spine-c/src/spine/MeshAttachment.c similarity index 100% rename from spine-c/src/spine/MeshAttachment.c rename to spine-c/spine-c/src/spine/MeshAttachment.c diff --git a/spine-c/src/spine/PathAttachment.c b/spine-c/spine-c/src/spine/PathAttachment.c similarity index 100% rename from spine-c/src/spine/PathAttachment.c rename to spine-c/spine-c/src/spine/PathAttachment.c diff --git a/spine-c/src/spine/PathConstraint.c b/spine-c/spine-c/src/spine/PathConstraint.c similarity index 100% rename from spine-c/src/spine/PathConstraint.c rename to spine-c/spine-c/src/spine/PathConstraint.c diff --git a/spine-c/src/spine/PathConstraintData.c b/spine-c/spine-c/src/spine/PathConstraintData.c similarity index 100% rename from spine-c/src/spine/PathConstraintData.c rename to spine-c/spine-c/src/spine/PathConstraintData.c diff --git a/spine-c/src/spine/RegionAttachment.c b/spine-c/spine-c/src/spine/RegionAttachment.c similarity index 100% rename from spine-c/src/spine/RegionAttachment.c rename to spine-c/spine-c/src/spine/RegionAttachment.c diff --git a/spine-c/src/spine/Skeleton.c b/spine-c/spine-c/src/spine/Skeleton.c similarity index 100% rename from spine-c/src/spine/Skeleton.c rename to spine-c/spine-c/src/spine/Skeleton.c diff --git a/spine-c/src/spine/SkeletonBinary.c b/spine-c/spine-c/src/spine/SkeletonBinary.c similarity index 100% rename from spine-c/src/spine/SkeletonBinary.c rename to spine-c/spine-c/src/spine/SkeletonBinary.c diff --git a/spine-c/src/spine/SkeletonBounds.c b/spine-c/spine-c/src/spine/SkeletonBounds.c similarity index 100% rename from spine-c/src/spine/SkeletonBounds.c rename to spine-c/spine-c/src/spine/SkeletonBounds.c diff --git a/spine-c/src/spine/SkeletonData.c b/spine-c/spine-c/src/spine/SkeletonData.c similarity index 100% rename from spine-c/src/spine/SkeletonData.c rename to spine-c/spine-c/src/spine/SkeletonData.c diff --git a/spine-c/src/spine/SkeletonJson.c b/spine-c/spine-c/src/spine/SkeletonJson.c similarity index 100% rename from spine-c/src/spine/SkeletonJson.c rename to spine-c/spine-c/src/spine/SkeletonJson.c diff --git a/spine-c/src/spine/Skin.c b/spine-c/spine-c/src/spine/Skin.c similarity index 100% rename from spine-c/src/spine/Skin.c rename to spine-c/spine-c/src/spine/Skin.c diff --git a/spine-c/src/spine/Slot.c b/spine-c/spine-c/src/spine/Slot.c similarity index 100% rename from spine-c/src/spine/Slot.c rename to spine-c/spine-c/src/spine/Slot.c diff --git a/spine-c/src/spine/SlotData.c b/spine-c/spine-c/src/spine/SlotData.c similarity index 100% rename from spine-c/src/spine/SlotData.c rename to spine-c/spine-c/src/spine/SlotData.c diff --git a/spine-c/src/spine/TransformConstraint.c b/spine-c/spine-c/src/spine/TransformConstraint.c similarity index 100% rename from spine-c/src/spine/TransformConstraint.c rename to spine-c/spine-c/src/spine/TransformConstraint.c diff --git a/spine-c/src/spine/TransformConstraintData.c b/spine-c/spine-c/src/spine/TransformConstraintData.c similarity index 100% rename from spine-c/src/spine/TransformConstraintData.c rename to spine-c/spine-c/src/spine/TransformConstraintData.c diff --git a/spine-c/src/spine/VertexAttachment.c b/spine-c/spine-c/src/spine/VertexAttachment.c similarity index 100% rename from spine-c/src/spine/VertexAttachment.c rename to spine-c/spine-c/src/spine/VertexAttachment.c diff --git a/spine-c/src/spine/extension.c b/spine-c/spine-c/src/spine/extension.c similarity index 100% rename from spine-c/src/spine/extension.c rename to spine-c/spine-c/src/spine/extension.c diff --git a/spine-c/src/spine/kvec.h b/spine-c/spine-c/src/spine/kvec.h similarity index 100% rename from spine-c/src/spine/kvec.h rename to spine-c/spine-c/src/spine/kvec.h diff --git a/spine-cocos2d-objc/README.md b/spine-cocos2d-objc/README.md index fa9a9ee4a..ce45267f1 100644 --- a/spine-cocos2d-objc/README.md +++ b/spine-cocos2d-objc/README.md @@ -20,8 +20,8 @@ spine-cocos2d-objc does not yet support loading the binary format. 1. Create a new cocos2d-obj project. See the [cocos2d-objc documentation](http://cocos2d-objc.org/started/) or have a look at the example in this repository. 2. Download the Spine Runtimes source using git (`git clone https://github.com/esotericsoftware/spine-runtimes`) or download it [as a zip](https://github.com/EsotericSoftware/spine-runtimes/archive/master.zip) -3. Add the sources from `spine-c/src/spine` and `spine-cocos2d-objc/src/spine` to your project -4. Add the folders `spine-c/include` and `spine-cocos2d-objc/src` to your header search path. Note that includes are specified as `#inclue `, so the `spine` directory cannot be omitted when copying the source files. +3. Add the sources from `spine-c/spine-c/src/spine` and `spine-cocos2d-objc/src/spine` to your project +4. Add the folders `spine-c/spine-c/include` and `spine-cocos2d-objc/src` to your header search path. Note that includes are specified as `#inclue `, so the `spine` directory cannot be omitted when copying the source files. See the [Spine Runtimes documentation](http://esotericsoftware.com/spine-documentation#runtimesTitle) on how to use the APIs or check out the Spine cocos2d-objc example. diff --git a/spine-cocos2dx/README.md b/spine-cocos2dx/README.md index 320886b76..229cc3989 100644 --- a/spine-cocos2dx/README.md +++ b/spine-cocos2dx/README.md @@ -24,8 +24,8 @@ The setup for cocos2d-x differs from most other Spine Runtimes because the cocos 2. Delete the folder `cocos2d/cocos/editor-support/spine`. This will remove the outdated Spine cocos2d-x runtime shipped by cocos2d-x. 3. Open your project in your IDE of choice, then open the cocos2d_libs sub project and delete the `editor-support/spine` group. This will remove the outdated Spine cocos2d-x runtime shipped by cocos2d-x from your build. 3. Download the Spine Runtimes source using git (`git clone https://github.com/esotericsoftware/spine-runtimes`) or download it [as a zip](https://github.com/EsotericSoftware/spine-runtimes/archive/master.zip) -4. Add the sources from `spine-c/src/spine` and `spine-cocos2dx/src/spine` to your project -4. Add the folders `spine-c/include` and `spine-cocos2dx/src` to your header search path. Note that includes are specified as `#inclue `, so the `spine` directory cannot be omitted when copying the source files. +4. Add the sources from `spine-c/spine-c/src/spine` and `spine-cocos2dx/src/spine` to your project +4. Add the folders `spine-c/spine-c/include` and `spine-cocos2dx/src` to your header search path. Note that includes are specified as `#inclue `, so the `spine` directory cannot be omitted when copying the source files. ## Example The Spine cocos2d-x example works on Windows and Mac OS X. diff --git a/spine-sfml/README.md b/spine-sfml/README.md index 5685bf75c..92ed26ce3 100644 --- a/spine-sfml/README.md +++ b/spine-sfml/README.md @@ -19,8 +19,8 @@ spine-sfml does not yet support loading the binary format. ## Usage 1. Create a new SFML project. See the [SFML documentation](http://www.sfml-dev.org/tutorials/2.1/) or have a look at the example in this repository. 2. Download the Spine Runtimes source using git (`git clone https://github.com/esotericsoftware/spine-runtimes`) or download it [as a zip](https://github.com/EsotericSoftware/spine-runtimes/archive/master.zip) -3. Add the sources from `spine-c/src/spine` and `spine-sfml/src/spine` to your project -4. Add the folder `spine-c/include` to your header search path. Note that includes are specified as `#inclue `, so the `spine` directory cannot be omitted when copying the source files. +3. Add the sources from `spine-c/spine-c/src/spine` and `spine-sfml/src/spine` to your project +4. Add the folder `spine-c/spine-c/include` to your header search path. Note that includes are specified as `#inclue `, so the `spine` directory cannot be omitted when copying the source files. See the [Spine Runtimes documentation](http://esotericsoftware.com/spine-documentation#runtimesTitle) on how to use the APIs or check out the Spine SFML example. From 9960402e393804f4b52514595649a48c909c3877 Mon Sep 17 00:00:00 2001 From: badlogic Date: Mon, 28 Nov 2016 16:15:35 +0100 Subject: [PATCH 2/3] [cocos2dx][cocos2dobj] Fixed up cocos2d-x and cocos2d-objc xcode projects for new spine-c directory --- .../project.pbxproj | 262 ++++++------ .../example/proj.android/jni/Android.mk | 66 +-- .../spine-cocos2d-x.xcodeproj/project.pbxproj | 402 +++++++++--------- 3 files changed, 369 insertions(+), 361 deletions(-) diff --git a/spine-cocos2d-objc/spine-cocos2d-objc.xcodeproj/project.pbxproj b/spine-cocos2d-objc/spine-cocos2d-objc.xcodeproj/project.pbxproj index 4adeab7d9..863d50a85 100644 --- a/spine-cocos2d-objc/spine-cocos2d-objc.xcodeproj/project.pbxproj +++ b/spine-cocos2d-objc/spine-cocos2d-objc.xcodeproj/project.pbxproj @@ -33,37 +33,38 @@ 652107961895250000B1FF07 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 652107951895250000B1FF07 /* CoreText.framework */; }; 765A2EF61D7D7A08003FB779 /* goblins.atlas in Resources */ = {isa = PBXBuildFile; fileRef = 765A2EF41D7D7A08003FB779 /* goblins.atlas */; }; 765A2EF71D7D7A08003FB779 /* goblins.png in Resources */ = {isa = PBXBuildFile; fileRef = 765A2EF51D7D7A08003FB779 /* goblins.png */; }; - 76F5BD7D1D2BDCB5005917E5 /* Animation.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD5D1D2BDCB5005917E5 /* Animation.c */; }; - 76F5BD7E1D2BDCB5005917E5 /* AnimationState.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD5E1D2BDCB5005917E5 /* AnimationState.c */; }; - 76F5BD7F1D2BDCB5005917E5 /* AnimationStateData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD5F1D2BDCB5005917E5 /* AnimationStateData.c */; }; - 76F5BD801D2BDCB5005917E5 /* Atlas.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD601D2BDCB5005917E5 /* Atlas.c */; }; - 76F5BD811D2BDCB5005917E5 /* AtlasAttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD611D2BDCB5005917E5 /* AtlasAttachmentLoader.c */; }; - 76F5BD821D2BDCB5005917E5 /* Attachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD621D2BDCB5005917E5 /* Attachment.c */; }; - 76F5BD831D2BDCB5005917E5 /* AttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD631D2BDCB5005917E5 /* AttachmentLoader.c */; }; - 76F5BD841D2BDCB5005917E5 /* Bone.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD641D2BDCB5005917E5 /* Bone.c */; }; - 76F5BD851D2BDCB5005917E5 /* BoneData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD651D2BDCB5005917E5 /* BoneData.c */; }; - 76F5BD861D2BDCB5005917E5 /* BoundingBoxAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD661D2BDCB5005917E5 /* BoundingBoxAttachment.c */; }; - 76F5BD871D2BDCB5005917E5 /* Event.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD671D2BDCB5005917E5 /* Event.c */; }; - 76F5BD881D2BDCB5005917E5 /* EventData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD681D2BDCB5005917E5 /* EventData.c */; }; - 76F5BD891D2BDCB5005917E5 /* extension.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD691D2BDCB5005917E5 /* extension.c */; }; - 76F5BD8A1D2BDCB5005917E5 /* IkConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD6A1D2BDCB5005917E5 /* IkConstraint.c */; }; - 76F5BD8B1D2BDCB5005917E5 /* IkConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD6B1D2BDCB5005917E5 /* IkConstraintData.c */; }; - 76F5BD8C1D2BDCB5005917E5 /* Json.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD6C1D2BDCB5005917E5 /* Json.c */; }; - 76F5BD8D1D2BDCB5005917E5 /* MeshAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD6E1D2BDCB5005917E5 /* MeshAttachment.c */; }; - 76F5BD8E1D2BDCB5005917E5 /* PathAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD6F1D2BDCB5005917E5 /* PathAttachment.c */; }; - 76F5BD8F1D2BDCB5005917E5 /* PathConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD701D2BDCB5005917E5 /* PathConstraint.c */; }; - 76F5BD901D2BDCB5005917E5 /* PathConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD711D2BDCB5005917E5 /* PathConstraintData.c */; }; - 76F5BD911D2BDCB5005917E5 /* RegionAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD721D2BDCB5005917E5 /* RegionAttachment.c */; }; - 76F5BD921D2BDCB5005917E5 /* Skeleton.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD731D2BDCB5005917E5 /* Skeleton.c */; }; - 76F5BD931D2BDCB5005917E5 /* SkeletonBounds.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD741D2BDCB5005917E5 /* SkeletonBounds.c */; }; - 76F5BD941D2BDCB5005917E5 /* SkeletonData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD751D2BDCB5005917E5 /* SkeletonData.c */; }; - 76F5BD951D2BDCB5005917E5 /* SkeletonJson.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD761D2BDCB5005917E5 /* SkeletonJson.c */; }; - 76F5BD961D2BDCB5005917E5 /* Skin.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD771D2BDCB5005917E5 /* Skin.c */; }; - 76F5BD971D2BDCB5005917E5 /* Slot.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD781D2BDCB5005917E5 /* Slot.c */; }; - 76F5BD981D2BDCB5005917E5 /* SlotData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD791D2BDCB5005917E5 /* SlotData.c */; }; - 76F5BD991D2BDCB5005917E5 /* TransformConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD7A1D2BDCB5005917E5 /* TransformConstraint.c */; }; - 76F5BD9A1D2BDCB5005917E5 /* TransformConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD7B1D2BDCB5005917E5 /* TransformConstraintData.c */; }; - 76F5BD9B1D2BDCB5005917E5 /* VertexAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD7C1D2BDCB5005917E5 /* VertexAttachment.c */; }; + 76F28D161DEC810300CDE54D /* Animation.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CF41DEC810200CDE54D /* Animation.c */; }; + 76F28D171DEC810300CDE54D /* AnimationState.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CF51DEC810300CDE54D /* AnimationState.c */; }; + 76F28D181DEC810300CDE54D /* AnimationStateData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CF61DEC810300CDE54D /* AnimationStateData.c */; }; + 76F28D191DEC810300CDE54D /* Atlas.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CF71DEC810300CDE54D /* Atlas.c */; }; + 76F28D1A1DEC810300CDE54D /* AtlasAttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CF81DEC810300CDE54D /* AtlasAttachmentLoader.c */; }; + 76F28D1B1DEC810300CDE54D /* Attachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CF91DEC810300CDE54D /* Attachment.c */; }; + 76F28D1C1DEC810300CDE54D /* AttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CFA1DEC810300CDE54D /* AttachmentLoader.c */; }; + 76F28D1D1DEC810300CDE54D /* Bone.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CFB1DEC810300CDE54D /* Bone.c */; }; + 76F28D1E1DEC810300CDE54D /* BoneData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CFC1DEC810300CDE54D /* BoneData.c */; }; + 76F28D1F1DEC810300CDE54D /* BoundingBoxAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CFD1DEC810300CDE54D /* BoundingBoxAttachment.c */; }; + 76F28D201DEC810300CDE54D /* Event.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CFE1DEC810300CDE54D /* Event.c */; }; + 76F28D211DEC810300CDE54D /* EventData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CFF1DEC810300CDE54D /* EventData.c */; }; + 76F28D221DEC810300CDE54D /* extension.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D001DEC810300CDE54D /* extension.c */; }; + 76F28D231DEC810300CDE54D /* IkConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D011DEC810300CDE54D /* IkConstraint.c */; }; + 76F28D241DEC810300CDE54D /* IkConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D021DEC810300CDE54D /* IkConstraintData.c */; }; + 76F28D251DEC810300CDE54D /* Json.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D031DEC810300CDE54D /* Json.c */; }; + 76F28D261DEC810300CDE54D /* MeshAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D061DEC810300CDE54D /* MeshAttachment.c */; }; + 76F28D271DEC810300CDE54D /* PathAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D071DEC810300CDE54D /* PathAttachment.c */; }; + 76F28D281DEC810300CDE54D /* PathConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D081DEC810300CDE54D /* PathConstraint.c */; }; + 76F28D291DEC810300CDE54D /* PathConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D091DEC810300CDE54D /* PathConstraintData.c */; }; + 76F28D2A1DEC810300CDE54D /* RegionAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D0A1DEC810300CDE54D /* RegionAttachment.c */; }; + 76F28D2B1DEC810300CDE54D /* Skeleton.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D0B1DEC810300CDE54D /* Skeleton.c */; }; + 76F28D2C1DEC810300CDE54D /* SkeletonBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D0C1DEC810300CDE54D /* SkeletonBinary.c */; }; + 76F28D2D1DEC810300CDE54D /* SkeletonBounds.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D0D1DEC810300CDE54D /* SkeletonBounds.c */; }; + 76F28D2E1DEC810300CDE54D /* SkeletonData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D0E1DEC810300CDE54D /* SkeletonData.c */; }; + 76F28D2F1DEC810300CDE54D /* SkeletonJson.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D0F1DEC810300CDE54D /* SkeletonJson.c */; }; + 76F28D301DEC810300CDE54D /* Skin.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D101DEC810300CDE54D /* Skin.c */; }; + 76F28D311DEC810300CDE54D /* Slot.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D111DEC810300CDE54D /* Slot.c */; }; + 76F28D321DEC810300CDE54D /* SlotData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D121DEC810300CDE54D /* SlotData.c */; }; + 76F28D331DEC810300CDE54D /* TransformConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D131DEC810300CDE54D /* TransformConstraint.c */; }; + 76F28D341DEC810300CDE54D /* TransformConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D141DEC810300CDE54D /* TransformConstraintData.c */; }; + 76F28D351DEC810300CDE54D /* VertexAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28D151DEC810300CDE54D /* VertexAttachment.c */; }; 76F5BDA21D2BDE1C005917E5 /* raptor.atlas in Resources */ = {isa = PBXBuildFile; fileRef = 76F5BD9C1D2BDE1C005917E5 /* raptor.atlas */; }; 76F5BDA31D2BDE1C005917E5 /* raptor.json in Resources */ = {isa = PBXBuildFile; fileRef = 76F5BD9D1D2BDE1C005917E5 /* raptor.json */; }; 76F5BDA41D2BDE1C005917E5 /* raptor.png in Resources */ = {isa = PBXBuildFile; fileRef = 76F5BD9E1D2BDE1C005917E5 /* raptor.png */; }; @@ -156,38 +157,40 @@ 652107951895250000B1FF07 /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; }; 765A2EF41D7D7A08003FB779 /* goblins.atlas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = goblins.atlas; path = Resources/goblins.atlas; sourceTree = ""; }; 765A2EF51D7D7A08003FB779 /* goblins.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = goblins.png; path = Resources/goblins.png; sourceTree = ""; }; - 76F5BD5D1D2BDCB5005917E5 /* Animation.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Animation.c; path = "../spine-c/src/spine/Animation.c"; sourceTree = ""; }; - 76F5BD5E1D2BDCB5005917E5 /* AnimationState.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AnimationState.c; path = "../spine-c/src/spine/AnimationState.c"; sourceTree = ""; }; - 76F5BD5F1D2BDCB5005917E5 /* AnimationStateData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AnimationStateData.c; path = "../spine-c/src/spine/AnimationStateData.c"; sourceTree = ""; }; - 76F5BD601D2BDCB5005917E5 /* Atlas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Atlas.c; path = "../spine-c/src/spine/Atlas.c"; sourceTree = ""; }; - 76F5BD611D2BDCB5005917E5 /* AtlasAttachmentLoader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AtlasAttachmentLoader.c; path = "../spine-c/src/spine/AtlasAttachmentLoader.c"; sourceTree = ""; }; - 76F5BD621D2BDCB5005917E5 /* Attachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Attachment.c; path = "../spine-c/src/spine/Attachment.c"; sourceTree = ""; }; - 76F5BD631D2BDCB5005917E5 /* AttachmentLoader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AttachmentLoader.c; path = "../spine-c/src/spine/AttachmentLoader.c"; sourceTree = ""; }; - 76F5BD641D2BDCB5005917E5 /* Bone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Bone.c; path = "../spine-c/src/spine/Bone.c"; sourceTree = ""; }; - 76F5BD651D2BDCB5005917E5 /* BoneData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = BoneData.c; path = "../spine-c/src/spine/BoneData.c"; sourceTree = ""; }; - 76F5BD661D2BDCB5005917E5 /* BoundingBoxAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = BoundingBoxAttachment.c; path = "../spine-c/src/spine/BoundingBoxAttachment.c"; sourceTree = ""; }; - 76F5BD671D2BDCB5005917E5 /* Event.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Event.c; path = "../spine-c/src/spine/Event.c"; sourceTree = ""; }; - 76F5BD681D2BDCB5005917E5 /* EventData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = EventData.c; path = "../spine-c/src/spine/EventData.c"; sourceTree = ""; }; - 76F5BD691D2BDCB5005917E5 /* extension.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = extension.c; path = "../spine-c/src/spine/extension.c"; sourceTree = ""; }; - 76F5BD6A1D2BDCB5005917E5 /* IkConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = IkConstraint.c; path = "../spine-c/src/spine/IkConstraint.c"; sourceTree = ""; }; - 76F5BD6B1D2BDCB5005917E5 /* IkConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = IkConstraintData.c; path = "../spine-c/src/spine/IkConstraintData.c"; sourceTree = ""; }; - 76F5BD6C1D2BDCB5005917E5 /* Json.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Json.c; path = "../spine-c/src/spine/Json.c"; sourceTree = ""; }; - 76F5BD6D1D2BDCB5005917E5 /* Json.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Json.h; path = "../spine-c/src/spine/Json.h"; sourceTree = ""; }; - 76F5BD6E1D2BDCB5005917E5 /* MeshAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = MeshAttachment.c; path = "../spine-c/src/spine/MeshAttachment.c"; sourceTree = ""; }; - 76F5BD6F1D2BDCB5005917E5 /* PathAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PathAttachment.c; path = "../spine-c/src/spine/PathAttachment.c"; sourceTree = ""; }; - 76F5BD701D2BDCB5005917E5 /* PathConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PathConstraint.c; path = "../spine-c/src/spine/PathConstraint.c"; sourceTree = ""; }; - 76F5BD711D2BDCB5005917E5 /* PathConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PathConstraintData.c; path = "../spine-c/src/spine/PathConstraintData.c"; sourceTree = ""; }; - 76F5BD721D2BDCB5005917E5 /* RegionAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = RegionAttachment.c; path = "../spine-c/src/spine/RegionAttachment.c"; sourceTree = ""; }; - 76F5BD731D2BDCB5005917E5 /* Skeleton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Skeleton.c; path = "../spine-c/src/spine/Skeleton.c"; sourceTree = ""; }; - 76F5BD741D2BDCB5005917E5 /* SkeletonBounds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonBounds.c; path = "../spine-c/src/spine/SkeletonBounds.c"; sourceTree = ""; }; - 76F5BD751D2BDCB5005917E5 /* SkeletonData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonData.c; path = "../spine-c/src/spine/SkeletonData.c"; sourceTree = ""; }; - 76F5BD761D2BDCB5005917E5 /* SkeletonJson.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonJson.c; path = "../spine-c/src/spine/SkeletonJson.c"; sourceTree = ""; }; - 76F5BD771D2BDCB5005917E5 /* Skin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Skin.c; path = "../spine-c/src/spine/Skin.c"; sourceTree = ""; }; - 76F5BD781D2BDCB5005917E5 /* Slot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Slot.c; path = "../spine-c/src/spine/Slot.c"; sourceTree = ""; }; - 76F5BD791D2BDCB5005917E5 /* SlotData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SlotData.c; path = "../spine-c/src/spine/SlotData.c"; sourceTree = ""; }; - 76F5BD7A1D2BDCB5005917E5 /* TransformConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TransformConstraint.c; path = "../spine-c/src/spine/TransformConstraint.c"; sourceTree = ""; }; - 76F5BD7B1D2BDCB5005917E5 /* TransformConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TransformConstraintData.c; path = "../spine-c/src/spine/TransformConstraintData.c"; sourceTree = ""; }; - 76F5BD7C1D2BDCB5005917E5 /* VertexAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = VertexAttachment.c; path = "../spine-c/src/spine/VertexAttachment.c"; sourceTree = ""; }; + 76F28CF41DEC810200CDE54D /* Animation.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Animation.c; path = "../spine-c/spine-c/src/spine/Animation.c"; sourceTree = ""; }; + 76F28CF51DEC810300CDE54D /* AnimationState.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AnimationState.c; path = "../spine-c/spine-c/src/spine/AnimationState.c"; sourceTree = ""; }; + 76F28CF61DEC810300CDE54D /* AnimationStateData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AnimationStateData.c; path = "../spine-c/spine-c/src/spine/AnimationStateData.c"; sourceTree = ""; }; + 76F28CF71DEC810300CDE54D /* Atlas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Atlas.c; path = "../spine-c/spine-c/src/spine/Atlas.c"; sourceTree = ""; }; + 76F28CF81DEC810300CDE54D /* AtlasAttachmentLoader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AtlasAttachmentLoader.c; path = "../spine-c/spine-c/src/spine/AtlasAttachmentLoader.c"; sourceTree = ""; }; + 76F28CF91DEC810300CDE54D /* Attachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Attachment.c; path = "../spine-c/spine-c/src/spine/Attachment.c"; sourceTree = ""; }; + 76F28CFA1DEC810300CDE54D /* AttachmentLoader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AttachmentLoader.c; path = "../spine-c/spine-c/src/spine/AttachmentLoader.c"; sourceTree = ""; }; + 76F28CFB1DEC810300CDE54D /* Bone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Bone.c; path = "../spine-c/spine-c/src/spine/Bone.c"; sourceTree = ""; }; + 76F28CFC1DEC810300CDE54D /* BoneData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = BoneData.c; path = "../spine-c/spine-c/src/spine/BoneData.c"; sourceTree = ""; }; + 76F28CFD1DEC810300CDE54D /* BoundingBoxAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = BoundingBoxAttachment.c; path = "../spine-c/spine-c/src/spine/BoundingBoxAttachment.c"; sourceTree = ""; }; + 76F28CFE1DEC810300CDE54D /* Event.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Event.c; path = "../spine-c/spine-c/src/spine/Event.c"; sourceTree = ""; }; + 76F28CFF1DEC810300CDE54D /* EventData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = EventData.c; path = "../spine-c/spine-c/src/spine/EventData.c"; sourceTree = ""; }; + 76F28D001DEC810300CDE54D /* extension.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = extension.c; path = "../spine-c/spine-c/src/spine/extension.c"; sourceTree = ""; }; + 76F28D011DEC810300CDE54D /* IkConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = IkConstraint.c; path = "../spine-c/spine-c/src/spine/IkConstraint.c"; sourceTree = ""; }; + 76F28D021DEC810300CDE54D /* IkConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = IkConstraintData.c; path = "../spine-c/spine-c/src/spine/IkConstraintData.c"; sourceTree = ""; }; + 76F28D031DEC810300CDE54D /* Json.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Json.c; path = "../spine-c/spine-c/src/spine/Json.c"; sourceTree = ""; }; + 76F28D041DEC810300CDE54D /* Json.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Json.h; path = "../spine-c/spine-c/src/spine/Json.h"; sourceTree = ""; }; + 76F28D051DEC810300CDE54D /* kvec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = kvec.h; path = "../spine-c/spine-c/src/spine/kvec.h"; sourceTree = ""; }; + 76F28D061DEC810300CDE54D /* MeshAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = MeshAttachment.c; path = "../spine-c/spine-c/src/spine/MeshAttachment.c"; sourceTree = ""; }; + 76F28D071DEC810300CDE54D /* PathAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PathAttachment.c; path = "../spine-c/spine-c/src/spine/PathAttachment.c"; sourceTree = ""; }; + 76F28D081DEC810300CDE54D /* PathConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PathConstraint.c; path = "../spine-c/spine-c/src/spine/PathConstraint.c"; sourceTree = ""; }; + 76F28D091DEC810300CDE54D /* PathConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PathConstraintData.c; path = "../spine-c/spine-c/src/spine/PathConstraintData.c"; sourceTree = ""; }; + 76F28D0A1DEC810300CDE54D /* RegionAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = RegionAttachment.c; path = "../spine-c/spine-c/src/spine/RegionAttachment.c"; sourceTree = ""; }; + 76F28D0B1DEC810300CDE54D /* Skeleton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Skeleton.c; path = "../spine-c/spine-c/src/spine/Skeleton.c"; sourceTree = ""; }; + 76F28D0C1DEC810300CDE54D /* SkeletonBinary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonBinary.c; path = "../spine-c/spine-c/src/spine/SkeletonBinary.c"; sourceTree = ""; }; + 76F28D0D1DEC810300CDE54D /* SkeletonBounds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonBounds.c; path = "../spine-c/spine-c/src/spine/SkeletonBounds.c"; sourceTree = ""; }; + 76F28D0E1DEC810300CDE54D /* SkeletonData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonData.c; path = "../spine-c/spine-c/src/spine/SkeletonData.c"; sourceTree = ""; }; + 76F28D0F1DEC810300CDE54D /* SkeletonJson.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonJson.c; path = "../spine-c/spine-c/src/spine/SkeletonJson.c"; sourceTree = ""; }; + 76F28D101DEC810300CDE54D /* Skin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Skin.c; path = "../spine-c/spine-c/src/spine/Skin.c"; sourceTree = ""; }; + 76F28D111DEC810300CDE54D /* Slot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Slot.c; path = "../spine-c/spine-c/src/spine/Slot.c"; sourceTree = ""; }; + 76F28D121DEC810300CDE54D /* SlotData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SlotData.c; path = "../spine-c/spine-c/src/spine/SlotData.c"; sourceTree = ""; }; + 76F28D131DEC810300CDE54D /* TransformConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TransformConstraint.c; path = "../spine-c/spine-c/src/spine/TransformConstraint.c"; sourceTree = ""; }; + 76F28D141DEC810300CDE54D /* TransformConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TransformConstraintData.c; path = "../spine-c/spine-c/src/spine/TransformConstraintData.c"; sourceTree = ""; }; + 76F28D151DEC810300CDE54D /* VertexAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = VertexAttachment.c; path = "../spine-c/spine-c/src/spine/VertexAttachment.c"; sourceTree = ""; }; 76F5BD9C1D2BDE1C005917E5 /* raptor.atlas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = raptor.atlas; path = Resources/raptor.atlas; sourceTree = ""; }; 76F5BD9D1D2BDE1C005917E5 /* raptor.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = raptor.json; path = Resources/raptor.json; sourceTree = ""; }; 76F5BD9E1D2BDE1C005917E5 /* raptor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = raptor.png; path = Resources/raptor.png; sourceTree = ""; }; @@ -270,38 +273,40 @@ 43C32822170B0BC2004A9460 /* spine-c */ = { isa = PBXGroup; children = ( - 76F5BD5D1D2BDCB5005917E5 /* Animation.c */, - 76F5BD5E1D2BDCB5005917E5 /* AnimationState.c */, - 76F5BD5F1D2BDCB5005917E5 /* AnimationStateData.c */, - 76F5BD601D2BDCB5005917E5 /* Atlas.c */, - 76F5BD611D2BDCB5005917E5 /* AtlasAttachmentLoader.c */, - 76F5BD621D2BDCB5005917E5 /* Attachment.c */, - 76F5BD631D2BDCB5005917E5 /* AttachmentLoader.c */, - 76F5BD641D2BDCB5005917E5 /* Bone.c */, - 76F5BD651D2BDCB5005917E5 /* BoneData.c */, - 76F5BD661D2BDCB5005917E5 /* BoundingBoxAttachment.c */, - 76F5BD671D2BDCB5005917E5 /* Event.c */, - 76F5BD681D2BDCB5005917E5 /* EventData.c */, - 76F5BD691D2BDCB5005917E5 /* extension.c */, - 76F5BD6A1D2BDCB5005917E5 /* IkConstraint.c */, - 76F5BD6B1D2BDCB5005917E5 /* IkConstraintData.c */, - 76F5BD6C1D2BDCB5005917E5 /* Json.c */, - 76F5BD6D1D2BDCB5005917E5 /* Json.h */, - 76F5BD6E1D2BDCB5005917E5 /* MeshAttachment.c */, - 76F5BD6F1D2BDCB5005917E5 /* PathAttachment.c */, - 76F5BD701D2BDCB5005917E5 /* PathConstraint.c */, - 76F5BD711D2BDCB5005917E5 /* PathConstraintData.c */, - 76F5BD721D2BDCB5005917E5 /* RegionAttachment.c */, - 76F5BD731D2BDCB5005917E5 /* Skeleton.c */, - 76F5BD741D2BDCB5005917E5 /* SkeletonBounds.c */, - 76F5BD751D2BDCB5005917E5 /* SkeletonData.c */, - 76F5BD761D2BDCB5005917E5 /* SkeletonJson.c */, - 76F5BD771D2BDCB5005917E5 /* Skin.c */, - 76F5BD781D2BDCB5005917E5 /* Slot.c */, - 76F5BD791D2BDCB5005917E5 /* SlotData.c */, - 76F5BD7A1D2BDCB5005917E5 /* TransformConstraint.c */, - 76F5BD7B1D2BDCB5005917E5 /* TransformConstraintData.c */, - 76F5BD7C1D2BDCB5005917E5 /* VertexAttachment.c */, + 76F28CF41DEC810200CDE54D /* Animation.c */, + 76F28CF51DEC810300CDE54D /* AnimationState.c */, + 76F28CF61DEC810300CDE54D /* AnimationStateData.c */, + 76F28CF71DEC810300CDE54D /* Atlas.c */, + 76F28CF81DEC810300CDE54D /* AtlasAttachmentLoader.c */, + 76F28CF91DEC810300CDE54D /* Attachment.c */, + 76F28CFA1DEC810300CDE54D /* AttachmentLoader.c */, + 76F28CFB1DEC810300CDE54D /* Bone.c */, + 76F28CFC1DEC810300CDE54D /* BoneData.c */, + 76F28CFD1DEC810300CDE54D /* BoundingBoxAttachment.c */, + 76F28CFE1DEC810300CDE54D /* Event.c */, + 76F28CFF1DEC810300CDE54D /* EventData.c */, + 76F28D001DEC810300CDE54D /* extension.c */, + 76F28D011DEC810300CDE54D /* IkConstraint.c */, + 76F28D021DEC810300CDE54D /* IkConstraintData.c */, + 76F28D031DEC810300CDE54D /* Json.c */, + 76F28D041DEC810300CDE54D /* Json.h */, + 76F28D051DEC810300CDE54D /* kvec.h */, + 76F28D061DEC810300CDE54D /* MeshAttachment.c */, + 76F28D071DEC810300CDE54D /* PathAttachment.c */, + 76F28D081DEC810300CDE54D /* PathConstraint.c */, + 76F28D091DEC810300CDE54D /* PathConstraintData.c */, + 76F28D0A1DEC810300CDE54D /* RegionAttachment.c */, + 76F28D0B1DEC810300CDE54D /* Skeleton.c */, + 76F28D0C1DEC810300CDE54D /* SkeletonBinary.c */, + 76F28D0D1DEC810300CDE54D /* SkeletonBounds.c */, + 76F28D0E1DEC810300CDE54D /* SkeletonData.c */, + 76F28D0F1DEC810300CDE54D /* SkeletonJson.c */, + 76F28D101DEC810300CDE54D /* Skin.c */, + 76F28D111DEC810300CDE54D /* Slot.c */, + 76F28D121DEC810300CDE54D /* SlotData.c */, + 76F28D131DEC810300CDE54D /* TransformConstraint.c */, + 76F28D141DEC810300CDE54D /* TransformConstraintData.c */, + 76F28D151DEC810300CDE54D /* VertexAttachment.c */, ); name = "spine-c"; sourceTree = ""; @@ -526,46 +531,47 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 76F28D191DEC810300CDE54D /* Atlas.c in Sources */, + 76F28D1D1DEC810300CDE54D /* Bone.c in Sources */, + 76F28D201DEC810300CDE54D /* Event.c in Sources */, + 76F28D321DEC810300CDE54D /* SlotData.c in Sources */, + 76F28D291DEC810300CDE54D /* PathConstraintData.c in Sources */, + 76F28D2E1DEC810300CDE54D /* SkeletonData.c in Sources */, + 76F28D2D1DEC810300CDE54D /* SkeletonBounds.c in Sources */, + 76F28D161DEC810300CDE54D /* Animation.c in Sources */, 76F5BDAA1D2BDE67005917E5 /* RaptorExample.m in Sources */, - 76F5BD8E1D2BDCB5005917E5 /* PathAttachment.c in Sources */, + 76F28D301DEC810300CDE54D /* Skin.c in Sources */, + 76F28D251DEC810300CDE54D /* Json.c in Sources */, + 76F28D1C1DEC810300CDE54D /* AttachmentLoader.c in Sources */, + 76F28D241DEC810300CDE54D /* IkConstraintData.c in Sources */, + 76F28D1E1DEC810300CDE54D /* BoneData.c in Sources */, + 76F28D2A1DEC810300CDE54D /* RegionAttachment.c in Sources */, + 76F28D2C1DEC810300CDE54D /* SkeletonBinary.c in Sources */, 76F5BDAD1D2BDFA2005917E5 /* TankExample.m in Sources */, - 76F5BD931D2BDCB5005917E5 /* SkeletonBounds.c in Sources */, - 76F5BD871D2BDCB5005917E5 /* Event.c in Sources */, - 76F5BD8C1D2BDCB5005917E5 /* Json.c in Sources */, - 76F5BD891D2BDCB5005917E5 /* extension.c in Sources */, - 76F5BD881D2BDCB5005917E5 /* EventData.c in Sources */, - 76F5BD7F1D2BDCB5005917E5 /* AnimationStateData.c in Sources */, - 76F5BD8B1D2BDCB5005917E5 /* IkConstraintData.c in Sources */, - 76F5BD831D2BDCB5005917E5 /* AttachmentLoader.c in Sources */, - 76F5BD9A1D2BDCB5005917E5 /* TransformConstraintData.c in Sources */, - 76F5BD971D2BDCB5005917E5 /* Slot.c in Sources */, - 76F5BD861D2BDCB5005917E5 /* BoundingBoxAttachment.c in Sources */, - 76F5BD9B1D2BDCB5005917E5 /* VertexAttachment.c in Sources */, + 76F28D171DEC810300CDE54D /* AnimationState.c in Sources */, + 76F28D221DEC810300CDE54D /* extension.c in Sources */, + 76F28D231DEC810300CDE54D /* IkConstraint.c in Sources */, 43C3282F170B0C19004A9460 /* spine-cocos2d-objc.m in Sources */, - 76F5BD821D2BDCB5005917E5 /* Attachment.c in Sources */, - 76F5BD801D2BDCB5005917E5 /* Atlas.c in Sources */, - 76F5BD911D2BDCB5005917E5 /* RegionAttachment.c in Sources */, + 76F28D1F1DEC810300CDE54D /* BoundingBoxAttachment.c in Sources */, + 76F28D281DEC810300CDE54D /* PathConstraint.c in Sources */, + 76F28D2F1DEC810300CDE54D /* SkeletonJson.c in Sources */, + 76F28D311DEC810300CDE54D /* Slot.c in Sources */, 43C32A06170B0F93004A9460 /* main.m in Sources */, - 76F5BD8F1D2BDCB5005917E5 /* PathConstraint.c in Sources */, + 76F28D351DEC810300CDE54D /* VertexAttachment.c in Sources */, + 76F28D331DEC810300CDE54D /* TransformConstraint.c in Sources */, 43C32A09170B10FF004A9460 /* AppDelegate.m in Sources */, - 76F5BD981D2BDCB5005917E5 /* SlotData.c in Sources */, - 76F5BD7E1D2BDCB5005917E5 /* AnimationState.c in Sources */, 43F7FF881927F94800CA4038 /* SkeletonAnimation.m in Sources */, - 76F5BD851D2BDCB5005917E5 /* BoneData.c in Sources */, - 76F5BD7D1D2BDCB5005917E5 /* Animation.c in Sources */, - 76F5BD841D2BDCB5005917E5 /* Bone.c in Sources */, - 76F5BD901D2BDCB5005917E5 /* PathConstraintData.c in Sources */, + 76F28D271DEC810300CDE54D /* PathAttachment.c in Sources */, + 76F28D2B1DEC810300CDE54D /* Skeleton.c in Sources */, + 76F28D1B1DEC810300CDE54D /* Attachment.c in Sources */, + 76F28D261DEC810300CDE54D /* MeshAttachment.c in Sources */, + 76F28D1A1DEC810300CDE54D /* AtlasAttachmentLoader.c in Sources */, + 76F28D211DEC810300CDE54D /* EventData.c in Sources */, + 76F28D181DEC810300CDE54D /* AnimationStateData.c in Sources */, 43F7FF891927F94800CA4038 /* SkeletonRenderer.m in Sources */, - 76F5BD921D2BDCB5005917E5 /* Skeleton.c in Sources */, - 76F5BD811D2BDCB5005917E5 /* AtlasAttachmentLoader.c in Sources */, - 76F5BD961D2BDCB5005917E5 /* Skin.c in Sources */, + 76F28D341DEC810300CDE54D /* TransformConstraintData.c in Sources */, 43F7FF8E1927F96700CA4038 /* GoblinsExample.m in Sources */, - 76F5BD941D2BDCB5005917E5 /* SkeletonData.c in Sources */, - 76F5BD8A1D2BDCB5005917E5 /* IkConstraint.c in Sources */, 43F7FF8F1927F96700CA4038 /* SpineboyExample.m in Sources */, - 76F5BD951D2BDCB5005917E5 /* SkeletonJson.c in Sources */, - 76F5BD8D1D2BDCB5005917E5 /* MeshAttachment.c in Sources */, - 76F5BD991D2BDCB5005917E5 /* TransformConstraint.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -652,7 +658,7 @@ GCC_PREFIX_HEADER = "Resources-ios/Prefix.pch"; HEADER_SEARCH_PATHS = ( "\"src\"", - "\"../spine-c/include\"", + "\"../spine-c/spine-c/include\"", "\"cocos2d/cocos2d\"/**", "\"cocos2d/external/kazmath/include\"", "\"cocos2d/external/ObjectAL\"/**", @@ -679,7 +685,7 @@ GCC_PREFIX_HEADER = "Resources-ios/Prefix.pch"; HEADER_SEARCH_PATHS = ( "\"src\"", - "\"../spine-c/include\"", + "\"../spine-c/spine-c/include\"", "\"cocos2d/cocos2d\"/**", "\"cocos2d/external/kazmath/include\"", "\"cocos2d/external/ObjectAL\"/**", diff --git a/spine-cocos2dx/example/proj.android/jni/Android.mk b/spine-cocos2dx/example/proj.android/jni/Android.mk index 491b6d2dc..24b9bff63 100755 --- a/spine-cocos2dx/example/proj.android/jni/Android.mk +++ b/spine-cocos2dx/example/proj.android/jni/Android.mk @@ -25,42 +25,42 @@ LOCAL_SRC_FILES := hellocpp/main.cpp \ ../../../src/spine/SkeletonBatch.cpp \ ../../../src/spine/SkeletonRenderer.cpp \ ../../../src/spine/spine-cocos2dx.cpp \ - ../../../../spine-c/src/spine/Animation.c \ - ../../../../spine-c/src/spine/AnimationState.c \ - ../../../../spine-c/src/spine/AnimationStateData.c \ - ../../../../spine-c/src/spine/Atlas.c \ - ../../../../spine-c/src/spine/AtlasAttachmentLoader.c \ - ../../../../spine-c/src/spine/Attachment.c \ - ../../../../spine-c/src/spine/AttachmentLoader.c \ - ../../../../spine-c/src/spine/Bone.c \ - ../../../../spine-c/src/spine/BoneData.c \ - ../../../../spine-c/src/spine/BoundingBoxAttachment.c \ - ../../../../spine-c/src/spine/Event.c \ - ../../../../spine-c/src/spine/EventData.c \ - ../../../../spine-c/src/spine/IkConstraint.c \ - ../../../../spine-c/src/spine/IkConstraintData.c \ - ../../../../spine-c/src/spine/Json.c \ - ../../../../spine-c/src/spine/MeshAttachment.c \ - ../../../../spine-c/src/spine/PathAttachment.c \ - ../../../../spine-c/src/spine/PathConstraint.c \ - ../../../../spine-c/src/spine/PathConstraintData.c \ - ../../../../spine-c/src/spine/RegionAttachment.c \ - ../../../../spine-c/src/spine/Skeleton.c \ - ../../../../spine-c/src/spine/SkeletonBinary.c \ - ../../../../spine-c/src/spine/SkeletonBounds.c \ - ../../../../spine-c/src/spine/SkeletonData.c \ - ../../../../spine-c/src/spine/SkeletonJson.c \ - ../../../../spine-c/src/spine/Skin.c \ - ../../../../spine-c/src/spine/Slot.c \ - ../../../../spine-c/src/spine/SlotData.c \ - ../../../../spine-c/src/spine/TransformConstraint.c \ - ../../../../spine-c/src/spine/TransformConstraintData.c \ - ../../../../spine-c/src/spine/VertexAttachment.c \ - ../../../../spine-c/src/spine/extension.c + ../../../../spine-c/spine-c/src/spine/Animation.c \ + ../../../../spine-c/spine-c/src/spine/AnimationState.c \ + ../../../../spine-c/spine-c/src/spine/AnimationStateData.c \ + ../../../../spine-c/spine-c/src/spine/Atlas.c \ + ../../../../spine-c/spine-c/src/spine/AtlasAttachmentLoader.c \ + ../../../../spine-c/spine-c/src/spine/Attachment.c \ + ../../../../spine-c/spine-c/src/spine/AttachmentLoader.c \ + ../../../../spine-c/spine-c/src/spine/Bone.c \ + ../../../../spine-c/spine-c/src/spine/BoneData.c \ + ../../../../spine-c/spine-c/src/spine/BoundingBoxAttachment.c \ + ../../../../spine-c/spine-c/src/spine/Event.c \ + ../../../../spine-c/spine-c/src/spine/EventData.c \ + ../../../../spine-c/spine-c/src/spine/IkConstraint.c \ + ../../../../spine-c/spine-c/src/spine/IkConstraintData.c \ + ../../../../spine-c/spine-c/src/spine/Json.c \ + ../../../../spine-c/spine-c/src/spine/MeshAttachment.c \ + ../../../../spine-c/spine-c/src/spine/PathAttachment.c \ + ../../../../spine-c/spine-c/src/spine/PathConstraint.c \ + ../../../../spine-c/spine-c/src/spine/PathConstraintData.c \ + ../../../../spine-c/spine-c/src/spine/RegionAttachment.c \ + ../../../../spine-c/spine-c/src/spine/Skeleton.c \ + ../../../../spine-c/spine-c/src/spine/SkeletonBinary.c \ + ../../../../spine-c/spine-c/src/spine/SkeletonBounds.c \ + ../../../../spine-c/spine-c/src/spine/SkeletonData.c \ + ../../../../spine-c/spine-c/src/spine/SkeletonJson.c \ + ../../../../spine-c/spine-c/src/spine/Skin.c \ + ../../../../spine-c/spine-c/src/spine/Slot.c \ + ../../../../spine-c/spine-c/src/spine/SlotData.c \ + ../../../../spine-c/spine-c/src/spine/TransformConstraint.c \ + ../../../../spine-c/spine-c/src/spine/TransformConstraintData.c \ + ../../../../spine-c/spine-c/src/spine/VertexAttachment.c \ + ../../../../spine-c/spine-c/src/spine/extension.c LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \ - $(LOCAL_PATH)/../../../../spine-c/include \ + $(LOCAL_PATH)/../../../../spine-c/spine-c/include \ $(LOCAL_PATH)/../../../../spine-cocos2dx/src # _COCOS_HEADER_ANDROID_BEGIN diff --git a/spine-cocos2dx/example/proj.ios_mac/spine-cocos2d-x.xcodeproj/project.pbxproj b/spine-cocos2dx/example/proj.ios_mac/spine-cocos2d-x.xcodeproj/project.pbxproj index 857ef2602..8ad8c1153 100644 --- a/spine-cocos2dx/example/proj.ios_mac/spine-cocos2d-x.xcodeproj/project.pbxproj +++ b/spine-cocos2dx/example/proj.ios_mac/spine-cocos2d-x.xcodeproj/project.pbxproj @@ -46,8 +46,6 @@ 521A8E6519F0C34300D177D7 /* Default-736h@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 521A8E6319F0C34300D177D7 /* Default-736h@3x.png */; }; 52B47A471A53D09C004E4C60 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52B47A461A53D09B004E4C60 /* Security.framework */; }; 7602C5551D7DAA1300C7C674 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7602C5541D7DAA1300C7C674 /* CoreText.framework */; }; - 765B3E181DA283F90071C974 /* SkeletonBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = 765B3E171DA283F90071C974 /* SkeletonBinary.c */; }; - 765B3E191DA284060071C974 /* SkeletonBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = 765B3E171DA283F90071C974 /* SkeletonBinary.c */; }; 76AAA3C01D180F7C00C54FCB /* AppDelegate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76AAA3B31D180F7C00C54FCB /* AppDelegate.cpp */; }; 76AAA3C11D180F7C00C54FCB /* BatchingExample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76AAA3B61D180F7C00C54FCB /* BatchingExample.cpp */; }; 76AAA3C21D180F7C00C54FCB /* GoblinsExample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76AAA3B81D180F7C00C54FCB /* GoblinsExample.cpp */; }; @@ -87,69 +85,72 @@ 76AAA4471D1811B000C54FCB /* SpineboyExample.h in Sources */ = {isa = PBXBuildFile; fileRef = 76AAA3BF1D180F7C00C54FCB /* SpineboyExample.h */; }; 76AAA4571D18132D00C54FCB /* common in Resources */ = {isa = PBXBuildFile; fileRef = 76AAA4521D18132D00C54FCB /* common */; }; 76AAA4581D18132D00C54FCB /* common in Resources */ = {isa = PBXBuildFile; fileRef = 76AAA4521D18132D00C54FCB /* common */; }; - 76F5BD141D2BB57F005917E5 /* Animation.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCF41D2BB57F005917E5 /* Animation.c */; }; - 76F5BD151D2BB57F005917E5 /* AnimationState.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCF51D2BB57F005917E5 /* AnimationState.c */; }; - 76F5BD161D2BB57F005917E5 /* AnimationStateData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCF61D2BB57F005917E5 /* AnimationStateData.c */; }; - 76F5BD171D2BB57F005917E5 /* Atlas.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCF71D2BB57F005917E5 /* Atlas.c */; }; - 76F5BD181D2BB57F005917E5 /* AtlasAttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCF81D2BB57F005917E5 /* AtlasAttachmentLoader.c */; }; - 76F5BD191D2BB57F005917E5 /* Attachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCF91D2BB57F005917E5 /* Attachment.c */; }; - 76F5BD1A1D2BB57F005917E5 /* AttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCFA1D2BB57F005917E5 /* AttachmentLoader.c */; }; - 76F5BD1B1D2BB57F005917E5 /* Bone.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCFB1D2BB57F005917E5 /* Bone.c */; }; - 76F5BD1C1D2BB57F005917E5 /* BoneData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCFC1D2BB57F005917E5 /* BoneData.c */; }; - 76F5BD1D1D2BB57F005917E5 /* BoundingBoxAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCFD1D2BB57F005917E5 /* BoundingBoxAttachment.c */; }; - 76F5BD1E1D2BB57F005917E5 /* Event.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCFE1D2BB57F005917E5 /* Event.c */; }; - 76F5BD1F1D2BB57F005917E5 /* EventData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCFF1D2BB57F005917E5 /* EventData.c */; }; - 76F5BD201D2BB57F005917E5 /* extension.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD001D2BB57F005917E5 /* extension.c */; }; - 76F5BD211D2BB57F005917E5 /* IkConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD011D2BB57F005917E5 /* IkConstraint.c */; }; - 76F5BD221D2BB57F005917E5 /* IkConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD021D2BB57F005917E5 /* IkConstraintData.c */; }; - 76F5BD231D2BB57F005917E5 /* Json.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD031D2BB57F005917E5 /* Json.c */; }; - 76F5BD241D2BB57F005917E5 /* MeshAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD051D2BB57F005917E5 /* MeshAttachment.c */; }; - 76F5BD251D2BB57F005917E5 /* PathAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD061D2BB57F005917E5 /* PathAttachment.c */; }; - 76F5BD261D2BB57F005917E5 /* PathConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD071D2BB57F005917E5 /* PathConstraint.c */; }; - 76F5BD271D2BB57F005917E5 /* PathConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD081D2BB57F005917E5 /* PathConstraintData.c */; }; - 76F5BD281D2BB57F005917E5 /* RegionAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD091D2BB57F005917E5 /* RegionAttachment.c */; }; - 76F5BD291D2BB57F005917E5 /* Skeleton.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD0A1D2BB57F005917E5 /* Skeleton.c */; }; - 76F5BD2A1D2BB57F005917E5 /* SkeletonBounds.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD0B1D2BB57F005917E5 /* SkeletonBounds.c */; }; - 76F5BD2B1D2BB57F005917E5 /* SkeletonData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD0C1D2BB57F005917E5 /* SkeletonData.c */; }; - 76F5BD2C1D2BB57F005917E5 /* SkeletonJson.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD0D1D2BB57F005917E5 /* SkeletonJson.c */; }; - 76F5BD2D1D2BB57F005917E5 /* Skin.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD0E1D2BB57F005917E5 /* Skin.c */; }; - 76F5BD2E1D2BB57F005917E5 /* Slot.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD0F1D2BB57F005917E5 /* Slot.c */; }; - 76F5BD2F1D2BB57F005917E5 /* SlotData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD101D2BB57F005917E5 /* SlotData.c */; }; - 76F5BD301D2BB57F005917E5 /* TransformConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD111D2BB57F005917E5 /* TransformConstraint.c */; }; - 76F5BD311D2BB57F005917E5 /* TransformConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD121D2BB57F005917E5 /* TransformConstraintData.c */; }; - 76F5BD321D2BB57F005917E5 /* VertexAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD131D2BB57F005917E5 /* VertexAttachment.c */; }; - 76F5BD331D2BD4A9005917E5 /* Animation.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCF41D2BB57F005917E5 /* Animation.c */; }; - 76F5BD341D2BD4A9005917E5 /* AnimationState.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCF51D2BB57F005917E5 /* AnimationState.c */; }; - 76F5BD351D2BD4A9005917E5 /* AnimationStateData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCF61D2BB57F005917E5 /* AnimationStateData.c */; }; - 76F5BD361D2BD4A9005917E5 /* Atlas.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCF71D2BB57F005917E5 /* Atlas.c */; }; - 76F5BD371D2BD4A9005917E5 /* AtlasAttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCF81D2BB57F005917E5 /* AtlasAttachmentLoader.c */; }; - 76F5BD381D2BD4A9005917E5 /* Attachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCF91D2BB57F005917E5 /* Attachment.c */; }; - 76F5BD391D2BD4A9005917E5 /* AttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCFA1D2BB57F005917E5 /* AttachmentLoader.c */; }; - 76F5BD3A1D2BD4A9005917E5 /* Bone.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCFB1D2BB57F005917E5 /* Bone.c */; }; - 76F5BD3B1D2BD4A9005917E5 /* BoneData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCFC1D2BB57F005917E5 /* BoneData.c */; }; - 76F5BD3C1D2BD4A9005917E5 /* BoundingBoxAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCFD1D2BB57F005917E5 /* BoundingBoxAttachment.c */; }; - 76F5BD3D1D2BD4A9005917E5 /* Event.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCFE1D2BB57F005917E5 /* Event.c */; }; - 76F5BD3E1D2BD4A9005917E5 /* EventData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BCFF1D2BB57F005917E5 /* EventData.c */; }; - 76F5BD3F1D2BD4A9005917E5 /* extension.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD001D2BB57F005917E5 /* extension.c */; }; - 76F5BD401D2BD4A9005917E5 /* IkConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD011D2BB57F005917E5 /* IkConstraint.c */; }; - 76F5BD411D2BD4A9005917E5 /* IkConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD021D2BB57F005917E5 /* IkConstraintData.c */; }; - 76F5BD421D2BD4A9005917E5 /* Json.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD031D2BB57F005917E5 /* Json.c */; }; - 76F5BD431D2BD4A9005917E5 /* Json.h in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD041D2BB57F005917E5 /* Json.h */; }; - 76F5BD441D2BD4A9005917E5 /* MeshAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD051D2BB57F005917E5 /* MeshAttachment.c */; }; - 76F5BD451D2BD4A9005917E5 /* PathAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD061D2BB57F005917E5 /* PathAttachment.c */; }; - 76F5BD461D2BD4A9005917E5 /* PathConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD071D2BB57F005917E5 /* PathConstraint.c */; }; - 76F5BD471D2BD4A9005917E5 /* PathConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD081D2BB57F005917E5 /* PathConstraintData.c */; }; - 76F5BD481D2BD4A9005917E5 /* RegionAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD091D2BB57F005917E5 /* RegionAttachment.c */; }; - 76F5BD491D2BD4A9005917E5 /* Skeleton.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD0A1D2BB57F005917E5 /* Skeleton.c */; }; - 76F5BD4A1D2BD4A9005917E5 /* SkeletonBounds.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD0B1D2BB57F005917E5 /* SkeletonBounds.c */; }; - 76F5BD4B1D2BD4A9005917E5 /* SkeletonData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD0C1D2BB57F005917E5 /* SkeletonData.c */; }; - 76F5BD4C1D2BD4A9005917E5 /* SkeletonJson.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD0D1D2BB57F005917E5 /* SkeletonJson.c */; }; - 76F5BD4D1D2BD4A9005917E5 /* Skin.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD0E1D2BB57F005917E5 /* Skin.c */; }; - 76F5BD4E1D2BD4A9005917E5 /* Slot.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD0F1D2BB57F005917E5 /* Slot.c */; }; - 76F5BD4F1D2BD4A9005917E5 /* SlotData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD101D2BB57F005917E5 /* SlotData.c */; }; - 76F5BD501D2BD4A9005917E5 /* TransformConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD111D2BB57F005917E5 /* TransformConstraint.c */; }; - 76F5BD511D2BD4A9005917E5 /* TransformConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD121D2BB57F005917E5 /* TransformConstraintData.c */; }; - 76F5BD521D2BD4A9005917E5 /* VertexAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD131D2BB57F005917E5 /* VertexAttachment.c */; }; + 76F28CB11DEC7EBB00CDE54D /* Animation.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C8F1DEC7EBA00CDE54D /* Animation.c */; }; + 76F28CB21DEC7EBB00CDE54D /* AnimationState.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C901DEC7EBA00CDE54D /* AnimationState.c */; }; + 76F28CB31DEC7EBB00CDE54D /* AnimationStateData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C911DEC7EBA00CDE54D /* AnimationStateData.c */; }; + 76F28CB41DEC7EBB00CDE54D /* Atlas.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C921DEC7EBA00CDE54D /* Atlas.c */; }; + 76F28CB51DEC7EBB00CDE54D /* AtlasAttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C931DEC7EBA00CDE54D /* AtlasAttachmentLoader.c */; }; + 76F28CB61DEC7EBB00CDE54D /* Attachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C941DEC7EBA00CDE54D /* Attachment.c */; }; + 76F28CB71DEC7EBB00CDE54D /* AttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C951DEC7EBA00CDE54D /* AttachmentLoader.c */; }; + 76F28CB81DEC7EBB00CDE54D /* Bone.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C961DEC7EBA00CDE54D /* Bone.c */; }; + 76F28CB91DEC7EBB00CDE54D /* BoneData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C971DEC7EBA00CDE54D /* BoneData.c */; }; + 76F28CBA1DEC7EBB00CDE54D /* BoundingBoxAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C981DEC7EBA00CDE54D /* BoundingBoxAttachment.c */; }; + 76F28CBB1DEC7EBB00CDE54D /* Event.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C991DEC7EBA00CDE54D /* Event.c */; }; + 76F28CBC1DEC7EBB00CDE54D /* EventData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C9A1DEC7EBA00CDE54D /* EventData.c */; }; + 76F28CBD1DEC7EBB00CDE54D /* extension.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C9B1DEC7EBA00CDE54D /* extension.c */; }; + 76F28CBE1DEC7EBB00CDE54D /* IkConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C9C1DEC7EBA00CDE54D /* IkConstraint.c */; }; + 76F28CBF1DEC7EBB00CDE54D /* IkConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C9D1DEC7EBA00CDE54D /* IkConstraintData.c */; }; + 76F28CC01DEC7EBB00CDE54D /* Json.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C9E1DEC7EBA00CDE54D /* Json.c */; }; + 76F28CC11DEC7EBB00CDE54D /* MeshAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA11DEC7EBB00CDE54D /* MeshAttachment.c */; }; + 76F28CC21DEC7EBB00CDE54D /* PathAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA21DEC7EBB00CDE54D /* PathAttachment.c */; }; + 76F28CC31DEC7EBB00CDE54D /* PathConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA31DEC7EBB00CDE54D /* PathConstraint.c */; }; + 76F28CC41DEC7EBB00CDE54D /* PathConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA41DEC7EBB00CDE54D /* PathConstraintData.c */; }; + 76F28CC51DEC7EBB00CDE54D /* RegionAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA51DEC7EBB00CDE54D /* RegionAttachment.c */; }; + 76F28CC61DEC7EBB00CDE54D /* Skeleton.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA61DEC7EBB00CDE54D /* Skeleton.c */; }; + 76F28CC71DEC7EBB00CDE54D /* SkeletonBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA71DEC7EBB00CDE54D /* SkeletonBinary.c */; }; + 76F28CC81DEC7EBB00CDE54D /* SkeletonBounds.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA81DEC7EBB00CDE54D /* SkeletonBounds.c */; }; + 76F28CC91DEC7EBB00CDE54D /* SkeletonData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA91DEC7EBB00CDE54D /* SkeletonData.c */; }; + 76F28CCA1DEC7EBB00CDE54D /* SkeletonJson.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CAA1DEC7EBB00CDE54D /* SkeletonJson.c */; }; + 76F28CCB1DEC7EBB00CDE54D /* Skin.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CAB1DEC7EBB00CDE54D /* Skin.c */; }; + 76F28CCC1DEC7EBB00CDE54D /* Slot.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CAC1DEC7EBB00CDE54D /* Slot.c */; }; + 76F28CCD1DEC7EBB00CDE54D /* SlotData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CAD1DEC7EBB00CDE54D /* SlotData.c */; }; + 76F28CCE1DEC7EBB00CDE54D /* TransformConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CAE1DEC7EBB00CDE54D /* TransformConstraint.c */; }; + 76F28CCF1DEC7EBB00CDE54D /* TransformConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CAF1DEC7EBB00CDE54D /* TransformConstraintData.c */; }; + 76F28CD01DEC7EBB00CDE54D /* VertexAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CB01DEC7EBB00CDE54D /* VertexAttachment.c */; }; + 76F28CD11DEC7FFA00CDE54D /* Animation.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C8F1DEC7EBA00CDE54D /* Animation.c */; }; + 76F28CD21DEC7FFA00CDE54D /* AnimationState.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C901DEC7EBA00CDE54D /* AnimationState.c */; }; + 76F28CD31DEC7FFA00CDE54D /* AnimationStateData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C911DEC7EBA00CDE54D /* AnimationStateData.c */; }; + 76F28CD41DEC7FFA00CDE54D /* Atlas.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C921DEC7EBA00CDE54D /* Atlas.c */; }; + 76F28CD51DEC7FFA00CDE54D /* AtlasAttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C931DEC7EBA00CDE54D /* AtlasAttachmentLoader.c */; }; + 76F28CD61DEC7FFA00CDE54D /* Attachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C941DEC7EBA00CDE54D /* Attachment.c */; }; + 76F28CD71DEC7FFA00CDE54D /* AttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C951DEC7EBA00CDE54D /* AttachmentLoader.c */; }; + 76F28CD81DEC7FFA00CDE54D /* Bone.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C961DEC7EBA00CDE54D /* Bone.c */; }; + 76F28CD91DEC7FFA00CDE54D /* BoneData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C971DEC7EBA00CDE54D /* BoneData.c */; }; + 76F28CDA1DEC7FFA00CDE54D /* BoundingBoxAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C981DEC7EBA00CDE54D /* BoundingBoxAttachment.c */; }; + 76F28CDB1DEC7FFA00CDE54D /* Event.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C991DEC7EBA00CDE54D /* Event.c */; }; + 76F28CDC1DEC7FFA00CDE54D /* EventData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C9A1DEC7EBA00CDE54D /* EventData.c */; }; + 76F28CDD1DEC7FFA00CDE54D /* extension.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C9B1DEC7EBA00CDE54D /* extension.c */; }; + 76F28CDE1DEC7FFA00CDE54D /* IkConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C9C1DEC7EBA00CDE54D /* IkConstraint.c */; }; + 76F28CDF1DEC7FFA00CDE54D /* IkConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C9D1DEC7EBA00CDE54D /* IkConstraintData.c */; }; + 76F28CE01DEC7FFA00CDE54D /* Json.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C9E1DEC7EBA00CDE54D /* Json.c */; }; + 76F28CE11DEC7FFA00CDE54D /* Json.h in Sources */ = {isa = PBXBuildFile; fileRef = 76F28C9F1DEC7EBA00CDE54D /* Json.h */; }; + 76F28CE21DEC7FFA00CDE54D /* kvec.h in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA01DEC7EBB00CDE54D /* kvec.h */; }; + 76F28CE31DEC7FFA00CDE54D /* MeshAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA11DEC7EBB00CDE54D /* MeshAttachment.c */; }; + 76F28CE41DEC7FFA00CDE54D /* PathAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA21DEC7EBB00CDE54D /* PathAttachment.c */; }; + 76F28CE51DEC7FFA00CDE54D /* PathConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA31DEC7EBB00CDE54D /* PathConstraint.c */; }; + 76F28CE61DEC7FFA00CDE54D /* PathConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA41DEC7EBB00CDE54D /* PathConstraintData.c */; }; + 76F28CE71DEC7FFA00CDE54D /* RegionAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA51DEC7EBB00CDE54D /* RegionAttachment.c */; }; + 76F28CE81DEC7FFA00CDE54D /* Skeleton.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA61DEC7EBB00CDE54D /* Skeleton.c */; }; + 76F28CE91DEC7FFA00CDE54D /* SkeletonBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA71DEC7EBB00CDE54D /* SkeletonBinary.c */; }; + 76F28CEA1DEC7FFA00CDE54D /* SkeletonBounds.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA81DEC7EBB00CDE54D /* SkeletonBounds.c */; }; + 76F28CEB1DEC7FFA00CDE54D /* SkeletonData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CA91DEC7EBB00CDE54D /* SkeletonData.c */; }; + 76F28CEC1DEC7FFA00CDE54D /* SkeletonJson.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CAA1DEC7EBB00CDE54D /* SkeletonJson.c */; }; + 76F28CED1DEC7FFA00CDE54D /* Skin.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CAB1DEC7EBB00CDE54D /* Skin.c */; }; + 76F28CEE1DEC7FFA00CDE54D /* Slot.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CAC1DEC7EBB00CDE54D /* Slot.c */; }; + 76F28CEF1DEC7FFA00CDE54D /* SlotData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CAD1DEC7EBB00CDE54D /* SlotData.c */; }; + 76F28CF01DEC7FFA00CDE54D /* TransformConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CAE1DEC7EBB00CDE54D /* TransformConstraint.c */; }; + 76F28CF11DEC7FFA00CDE54D /* TransformConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CAF1DEC7EBB00CDE54D /* TransformConstraintData.c */; }; + 76F28CF21DEC7FFA00CDE54D /* VertexAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CB01DEC7EBB00CDE54D /* VertexAttachment.c */; }; 76F5BD551D2BD7D3005917E5 /* TankExample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD531D2BD7D3005917E5 /* TankExample.cpp */; }; 76F5BD561D2BD7EF005917E5 /* TankExample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD531D2BD7D3005917E5 /* TankExample.cpp */; }; 76F5BD571D2BD7EF005917E5 /* TankExample.h in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BD541D2BD7D3005917E5 /* TankExample.h */; }; @@ -246,8 +247,6 @@ 521A8E6319F0C34300D177D7 /* Default-736h@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h@3x.png"; sourceTree = ""; }; 52B47A461A53D09B004E4C60 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; 7602C5541D7DAA1300C7C674 /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/System/Library/Frameworks/CoreText.framework; sourceTree = DEVELOPER_DIR; }; - 765B3E161DA283F90071C974 /* kvec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = kvec.h; path = "../../../spine-c/src/spine/kvec.h"; sourceTree = ""; }; - 765B3E171DA283F90071C974 /* SkeletonBinary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonBinary.c; path = "../../../spine-c/src/spine/SkeletonBinary.c"; sourceTree = ""; }; 76AAA3B31D180F7C00C54FCB /* AppDelegate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AppDelegate.cpp; sourceTree = ""; }; 76AAA3B41D180F7C00C54FCB /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 76AAA3B51D180F7C00C54FCB /* AppMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppMacros.h; sourceTree = ""; }; @@ -274,38 +273,40 @@ 76AAA40A1D18106000C54FCB /* spine-cocos2dx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "spine-cocos2dx.cpp"; path = "../../src/spine/spine-cocos2dx.cpp"; sourceTree = ""; }; 76AAA40B1D18106000C54FCB /* spine-cocos2dx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "spine-cocos2dx.h"; path = "../../src/spine/spine-cocos2dx.h"; sourceTree = ""; }; 76AAA4521D18132D00C54FCB /* common */ = {isa = PBXFileReference; lastKnownFileType = folder; path = common; sourceTree = ""; }; - 76F5BCF41D2BB57F005917E5 /* Animation.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Animation.c; path = "../../../spine-c/src/spine/Animation.c"; sourceTree = ""; }; - 76F5BCF51D2BB57F005917E5 /* AnimationState.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AnimationState.c; path = "../../../spine-c/src/spine/AnimationState.c"; sourceTree = ""; }; - 76F5BCF61D2BB57F005917E5 /* AnimationStateData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AnimationStateData.c; path = "../../../spine-c/src/spine/AnimationStateData.c"; sourceTree = ""; }; - 76F5BCF71D2BB57F005917E5 /* Atlas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Atlas.c; path = "../../../spine-c/src/spine/Atlas.c"; sourceTree = ""; }; - 76F5BCF81D2BB57F005917E5 /* AtlasAttachmentLoader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AtlasAttachmentLoader.c; path = "../../../spine-c/src/spine/AtlasAttachmentLoader.c"; sourceTree = ""; }; - 76F5BCF91D2BB57F005917E5 /* Attachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Attachment.c; path = "../../../spine-c/src/spine/Attachment.c"; sourceTree = ""; }; - 76F5BCFA1D2BB57F005917E5 /* AttachmentLoader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AttachmentLoader.c; path = "../../../spine-c/src/spine/AttachmentLoader.c"; sourceTree = ""; }; - 76F5BCFB1D2BB57F005917E5 /* Bone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Bone.c; path = "../../../spine-c/src/spine/Bone.c"; sourceTree = ""; }; - 76F5BCFC1D2BB57F005917E5 /* BoneData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = BoneData.c; path = "../../../spine-c/src/spine/BoneData.c"; sourceTree = ""; }; - 76F5BCFD1D2BB57F005917E5 /* BoundingBoxAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = BoundingBoxAttachment.c; path = "../../../spine-c/src/spine/BoundingBoxAttachment.c"; sourceTree = ""; }; - 76F5BCFE1D2BB57F005917E5 /* Event.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Event.c; path = "../../../spine-c/src/spine/Event.c"; sourceTree = ""; }; - 76F5BCFF1D2BB57F005917E5 /* EventData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = EventData.c; path = "../../../spine-c/src/spine/EventData.c"; sourceTree = ""; }; - 76F5BD001D2BB57F005917E5 /* extension.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = extension.c; path = "../../../spine-c/src/spine/extension.c"; sourceTree = ""; }; - 76F5BD011D2BB57F005917E5 /* IkConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = IkConstraint.c; path = "../../../spine-c/src/spine/IkConstraint.c"; sourceTree = ""; }; - 76F5BD021D2BB57F005917E5 /* IkConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = IkConstraintData.c; path = "../../../spine-c/src/spine/IkConstraintData.c"; sourceTree = ""; }; - 76F5BD031D2BB57F005917E5 /* Json.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Json.c; path = "../../../spine-c/src/spine/Json.c"; sourceTree = ""; }; - 76F5BD041D2BB57F005917E5 /* Json.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Json.h; path = "../../../spine-c/src/spine/Json.h"; sourceTree = ""; }; - 76F5BD051D2BB57F005917E5 /* MeshAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = MeshAttachment.c; path = "../../../spine-c/src/spine/MeshAttachment.c"; sourceTree = ""; }; - 76F5BD061D2BB57F005917E5 /* PathAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PathAttachment.c; path = "../../../spine-c/src/spine/PathAttachment.c"; sourceTree = ""; }; - 76F5BD071D2BB57F005917E5 /* PathConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PathConstraint.c; path = "../../../spine-c/src/spine/PathConstraint.c"; sourceTree = ""; }; - 76F5BD081D2BB57F005917E5 /* PathConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PathConstraintData.c; path = "../../../spine-c/src/spine/PathConstraintData.c"; sourceTree = ""; }; - 76F5BD091D2BB57F005917E5 /* RegionAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = RegionAttachment.c; path = "../../../spine-c/src/spine/RegionAttachment.c"; sourceTree = ""; }; - 76F5BD0A1D2BB57F005917E5 /* Skeleton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Skeleton.c; path = "../../../spine-c/src/spine/Skeleton.c"; sourceTree = ""; }; - 76F5BD0B1D2BB57F005917E5 /* SkeletonBounds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonBounds.c; path = "../../../spine-c/src/spine/SkeletonBounds.c"; sourceTree = ""; }; - 76F5BD0C1D2BB57F005917E5 /* SkeletonData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonData.c; path = "../../../spine-c/src/spine/SkeletonData.c"; sourceTree = ""; }; - 76F5BD0D1D2BB57F005917E5 /* SkeletonJson.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonJson.c; path = "../../../spine-c/src/spine/SkeletonJson.c"; sourceTree = ""; }; - 76F5BD0E1D2BB57F005917E5 /* Skin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Skin.c; path = "../../../spine-c/src/spine/Skin.c"; sourceTree = ""; }; - 76F5BD0F1D2BB57F005917E5 /* Slot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Slot.c; path = "../../../spine-c/src/spine/Slot.c"; sourceTree = ""; }; - 76F5BD101D2BB57F005917E5 /* SlotData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SlotData.c; path = "../../../spine-c/src/spine/SlotData.c"; sourceTree = ""; }; - 76F5BD111D2BB57F005917E5 /* TransformConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TransformConstraint.c; path = "../../../spine-c/src/spine/TransformConstraint.c"; sourceTree = ""; }; - 76F5BD121D2BB57F005917E5 /* TransformConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TransformConstraintData.c; path = "../../../spine-c/src/spine/TransformConstraintData.c"; sourceTree = ""; }; - 76F5BD131D2BB57F005917E5 /* VertexAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = VertexAttachment.c; path = "../../../spine-c/src/spine/VertexAttachment.c"; sourceTree = ""; }; + 76F28C8F1DEC7EBA00CDE54D /* Animation.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Animation.c; path = "../../../spine-c/spine-c/src/spine/Animation.c"; sourceTree = ""; }; + 76F28C901DEC7EBA00CDE54D /* AnimationState.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AnimationState.c; path = "../../../spine-c/spine-c/src/spine/AnimationState.c"; sourceTree = ""; }; + 76F28C911DEC7EBA00CDE54D /* AnimationStateData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AnimationStateData.c; path = "../../../spine-c/spine-c/src/spine/AnimationStateData.c"; sourceTree = ""; }; + 76F28C921DEC7EBA00CDE54D /* Atlas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Atlas.c; path = "../../../spine-c/spine-c/src/spine/Atlas.c"; sourceTree = ""; }; + 76F28C931DEC7EBA00CDE54D /* AtlasAttachmentLoader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AtlasAttachmentLoader.c; path = "../../../spine-c/spine-c/src/spine/AtlasAttachmentLoader.c"; sourceTree = ""; }; + 76F28C941DEC7EBA00CDE54D /* Attachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Attachment.c; path = "../../../spine-c/spine-c/src/spine/Attachment.c"; sourceTree = ""; }; + 76F28C951DEC7EBA00CDE54D /* AttachmentLoader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AttachmentLoader.c; path = "../../../spine-c/spine-c/src/spine/AttachmentLoader.c"; sourceTree = ""; }; + 76F28C961DEC7EBA00CDE54D /* Bone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Bone.c; path = "../../../spine-c/spine-c/src/spine/Bone.c"; sourceTree = ""; }; + 76F28C971DEC7EBA00CDE54D /* BoneData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = BoneData.c; path = "../../../spine-c/spine-c/src/spine/BoneData.c"; sourceTree = ""; }; + 76F28C981DEC7EBA00CDE54D /* BoundingBoxAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = BoundingBoxAttachment.c; path = "../../../spine-c/spine-c/src/spine/BoundingBoxAttachment.c"; sourceTree = ""; }; + 76F28C991DEC7EBA00CDE54D /* Event.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Event.c; path = "../../../spine-c/spine-c/src/spine/Event.c"; sourceTree = ""; }; + 76F28C9A1DEC7EBA00CDE54D /* EventData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = EventData.c; path = "../../../spine-c/spine-c/src/spine/EventData.c"; sourceTree = ""; }; + 76F28C9B1DEC7EBA00CDE54D /* extension.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = extension.c; path = "../../../spine-c/spine-c/src/spine/extension.c"; sourceTree = ""; }; + 76F28C9C1DEC7EBA00CDE54D /* IkConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = IkConstraint.c; path = "../../../spine-c/spine-c/src/spine/IkConstraint.c"; sourceTree = ""; }; + 76F28C9D1DEC7EBA00CDE54D /* IkConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = IkConstraintData.c; path = "../../../spine-c/spine-c/src/spine/IkConstraintData.c"; sourceTree = ""; }; + 76F28C9E1DEC7EBA00CDE54D /* Json.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Json.c; path = "../../../spine-c/spine-c/src/spine/Json.c"; sourceTree = ""; }; + 76F28C9F1DEC7EBA00CDE54D /* Json.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Json.h; path = "../../../spine-c/spine-c/src/spine/Json.h"; sourceTree = ""; }; + 76F28CA01DEC7EBB00CDE54D /* kvec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = kvec.h; path = "../../../spine-c/spine-c/src/spine/kvec.h"; sourceTree = ""; }; + 76F28CA11DEC7EBB00CDE54D /* MeshAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = MeshAttachment.c; path = "../../../spine-c/spine-c/src/spine/MeshAttachment.c"; sourceTree = ""; }; + 76F28CA21DEC7EBB00CDE54D /* PathAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PathAttachment.c; path = "../../../spine-c/spine-c/src/spine/PathAttachment.c"; sourceTree = ""; }; + 76F28CA31DEC7EBB00CDE54D /* PathConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PathConstraint.c; path = "../../../spine-c/spine-c/src/spine/PathConstraint.c"; sourceTree = ""; }; + 76F28CA41DEC7EBB00CDE54D /* PathConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PathConstraintData.c; path = "../../../spine-c/spine-c/src/spine/PathConstraintData.c"; sourceTree = ""; }; + 76F28CA51DEC7EBB00CDE54D /* RegionAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = RegionAttachment.c; path = "../../../spine-c/spine-c/src/spine/RegionAttachment.c"; sourceTree = ""; }; + 76F28CA61DEC7EBB00CDE54D /* Skeleton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Skeleton.c; path = "../../../spine-c/spine-c/src/spine/Skeleton.c"; sourceTree = ""; }; + 76F28CA71DEC7EBB00CDE54D /* SkeletonBinary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonBinary.c; path = "../../../spine-c/spine-c/src/spine/SkeletonBinary.c"; sourceTree = ""; }; + 76F28CA81DEC7EBB00CDE54D /* SkeletonBounds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonBounds.c; path = "../../../spine-c/spine-c/src/spine/SkeletonBounds.c"; sourceTree = ""; }; + 76F28CA91DEC7EBB00CDE54D /* SkeletonData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonData.c; path = "../../../spine-c/spine-c/src/spine/SkeletonData.c"; sourceTree = ""; }; + 76F28CAA1DEC7EBB00CDE54D /* SkeletonJson.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonJson.c; path = "../../../spine-c/spine-c/src/spine/SkeletonJson.c"; sourceTree = ""; }; + 76F28CAB1DEC7EBB00CDE54D /* Skin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Skin.c; path = "../../../spine-c/spine-c/src/spine/Skin.c"; sourceTree = ""; }; + 76F28CAC1DEC7EBB00CDE54D /* Slot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Slot.c; path = "../../../spine-c/spine-c/src/spine/Slot.c"; sourceTree = ""; }; + 76F28CAD1DEC7EBB00CDE54D /* SlotData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SlotData.c; path = "../../../spine-c/spine-c/src/spine/SlotData.c"; sourceTree = ""; }; + 76F28CAE1DEC7EBB00CDE54D /* TransformConstraint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TransformConstraint.c; path = "../../../spine-c/spine-c/src/spine/TransformConstraint.c"; sourceTree = ""; }; + 76F28CAF1DEC7EBB00CDE54D /* TransformConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TransformConstraintData.c; path = "../../../spine-c/spine-c/src/spine/TransformConstraintData.c"; sourceTree = ""; }; + 76F28CB01DEC7EBB00CDE54D /* VertexAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = VertexAttachment.c; path = "../../../spine-c/spine-c/src/spine/VertexAttachment.c"; sourceTree = ""; }; 76F5BD531D2BD7D3005917E5 /* TankExample.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TankExample.cpp; sourceTree = ""; }; 76F5BD541D2BD7D3005917E5 /* TankExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TankExample.h; sourceTree = ""; }; 8262943D1AAF051F00CB7CF7 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; @@ -523,40 +524,40 @@ 76AAA3B21D180F7300C54FCB /* spine */ = { isa = PBXGroup; children = ( - 765B3E161DA283F90071C974 /* kvec.h */, - 765B3E171DA283F90071C974 /* SkeletonBinary.c */, - 76F5BCF41D2BB57F005917E5 /* Animation.c */, - 76F5BCF51D2BB57F005917E5 /* AnimationState.c */, - 76F5BCF61D2BB57F005917E5 /* AnimationStateData.c */, - 76F5BCF71D2BB57F005917E5 /* Atlas.c */, - 76F5BCF81D2BB57F005917E5 /* AtlasAttachmentLoader.c */, - 76F5BCF91D2BB57F005917E5 /* Attachment.c */, - 76F5BCFA1D2BB57F005917E5 /* AttachmentLoader.c */, - 76F5BCFB1D2BB57F005917E5 /* Bone.c */, - 76F5BCFC1D2BB57F005917E5 /* BoneData.c */, - 76F5BCFD1D2BB57F005917E5 /* BoundingBoxAttachment.c */, - 76F5BCFE1D2BB57F005917E5 /* Event.c */, - 76F5BCFF1D2BB57F005917E5 /* EventData.c */, - 76F5BD001D2BB57F005917E5 /* extension.c */, - 76F5BD011D2BB57F005917E5 /* IkConstraint.c */, - 76F5BD021D2BB57F005917E5 /* IkConstraintData.c */, - 76F5BD031D2BB57F005917E5 /* Json.c */, - 76F5BD041D2BB57F005917E5 /* Json.h */, - 76F5BD051D2BB57F005917E5 /* MeshAttachment.c */, - 76F5BD061D2BB57F005917E5 /* PathAttachment.c */, - 76F5BD071D2BB57F005917E5 /* PathConstraint.c */, - 76F5BD081D2BB57F005917E5 /* PathConstraintData.c */, - 76F5BD091D2BB57F005917E5 /* RegionAttachment.c */, - 76F5BD0A1D2BB57F005917E5 /* Skeleton.c */, - 76F5BD0B1D2BB57F005917E5 /* SkeletonBounds.c */, - 76F5BD0C1D2BB57F005917E5 /* SkeletonData.c */, - 76F5BD0D1D2BB57F005917E5 /* SkeletonJson.c */, - 76F5BD0E1D2BB57F005917E5 /* Skin.c */, - 76F5BD0F1D2BB57F005917E5 /* Slot.c */, - 76F5BD101D2BB57F005917E5 /* SlotData.c */, - 76F5BD111D2BB57F005917E5 /* TransformConstraint.c */, - 76F5BD121D2BB57F005917E5 /* TransformConstraintData.c */, - 76F5BD131D2BB57F005917E5 /* VertexAttachment.c */, + 76F28C8F1DEC7EBA00CDE54D /* Animation.c */, + 76F28C901DEC7EBA00CDE54D /* AnimationState.c */, + 76F28C911DEC7EBA00CDE54D /* AnimationStateData.c */, + 76F28C921DEC7EBA00CDE54D /* Atlas.c */, + 76F28C931DEC7EBA00CDE54D /* AtlasAttachmentLoader.c */, + 76F28C941DEC7EBA00CDE54D /* Attachment.c */, + 76F28C951DEC7EBA00CDE54D /* AttachmentLoader.c */, + 76F28C961DEC7EBA00CDE54D /* Bone.c */, + 76F28C971DEC7EBA00CDE54D /* BoneData.c */, + 76F28C981DEC7EBA00CDE54D /* BoundingBoxAttachment.c */, + 76F28C991DEC7EBA00CDE54D /* Event.c */, + 76F28C9A1DEC7EBA00CDE54D /* EventData.c */, + 76F28C9B1DEC7EBA00CDE54D /* extension.c */, + 76F28C9C1DEC7EBA00CDE54D /* IkConstraint.c */, + 76F28C9D1DEC7EBA00CDE54D /* IkConstraintData.c */, + 76F28C9E1DEC7EBA00CDE54D /* Json.c */, + 76F28C9F1DEC7EBA00CDE54D /* Json.h */, + 76F28CA01DEC7EBB00CDE54D /* kvec.h */, + 76F28CA11DEC7EBB00CDE54D /* MeshAttachment.c */, + 76F28CA21DEC7EBB00CDE54D /* PathAttachment.c */, + 76F28CA31DEC7EBB00CDE54D /* PathConstraint.c */, + 76F28CA41DEC7EBB00CDE54D /* PathConstraintData.c */, + 76F28CA51DEC7EBB00CDE54D /* RegionAttachment.c */, + 76F28CA61DEC7EBB00CDE54D /* Skeleton.c */, + 76F28CA71DEC7EBB00CDE54D /* SkeletonBinary.c */, + 76F28CA81DEC7EBB00CDE54D /* SkeletonBounds.c */, + 76F28CA91DEC7EBB00CDE54D /* SkeletonData.c */, + 76F28CAA1DEC7EBB00CDE54D /* SkeletonJson.c */, + 76F28CAB1DEC7EBB00CDE54D /* Skin.c */, + 76F28CAC1DEC7EBB00CDE54D /* Slot.c */, + 76F28CAD1DEC7EBB00CDE54D /* SlotData.c */, + 76F28CAE1DEC7EBB00CDE54D /* TransformConstraint.c */, + 76F28CAF1DEC7EBB00CDE54D /* TransformConstraintData.c */, + 76F28CB01DEC7EBB00CDE54D /* VertexAttachment.c */, ); name = spine; sourceTree = ""; @@ -720,54 +721,54 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 76F5BD221D2BB57F005917E5 /* IkConstraintData.c in Sources */, - 76F5BD1E1D2BB57F005917E5 /* Event.c in Sources */, - 76F5BD311D2BB57F005917E5 /* TransformConstraintData.c in Sources */, - 76F5BD1B1D2BB57F005917E5 /* Bone.c in Sources */, - 76F5BD171D2BB57F005917E5 /* Atlas.c in Sources */, + 76F28CCA1DEC7EBB00CDE54D /* SkeletonJson.c in Sources */, 76AAA40C1D18106000C54FCB /* AttachmentVertices.cpp in Sources */, + 76F28CC81DEC7EBB00CDE54D /* SkeletonBounds.c in Sources */, + 76F28CB71DEC7EBB00CDE54D /* AttachmentLoader.c in Sources */, 76F5BD551D2BD7D3005917E5 /* TankExample.cpp in Sources */, - 76F5BD321D2BB57F005917E5 /* VertexAttachment.c in Sources */, + 76F28CCC1DEC7EBB00CDE54D /* Slot.c in Sources */, + 76F28CB31DEC7EBB00CDE54D /* AnimationStateData.c in Sources */, + 76F28CBE1DEC7EBB00CDE54D /* IkConstraint.c in Sources */, 76AAA3C51D180F7C00C54FCB /* SpineboyExample.cpp in Sources */, - 76F5BD2C1D2BB57F005917E5 /* SkeletonJson.c in Sources */, - 76F5BD2E1D2BB57F005917E5 /* Slot.c in Sources */, - 76F5BD251D2BB57F005917E5 /* PathAttachment.c in Sources */, - 76F5BD1D1D2BB57F005917E5 /* BoundingBoxAttachment.c in Sources */, - 76F5BD161D2BB57F005917E5 /* AnimationStateData.c in Sources */, 76AAA3C11D180F7C00C54FCB /* BatchingExample.cpp in Sources */, - 76F5BD2D1D2BB57F005917E5 /* Skin.c in Sources */, + 76F28CD01DEC7EBB00CDE54D /* VertexAttachment.c in Sources */, + 76F28CBD1DEC7EBB00CDE54D /* extension.c in Sources */, + 76F28CB11DEC7EBB00CDE54D /* Animation.c in Sources */, + 76F28CC71DEC7EBB00CDE54D /* SkeletonBinary.c in Sources */, 76AAA40D1D18106000C54FCB /* Cocos2dAttachmentLoader.cpp in Sources */, + 76F28CC51DEC7EBB00CDE54D /* RegionAttachment.c in Sources */, 76AAA40F1D18106000C54FCB /* SkeletonBatch.cpp in Sources */, - 76F5BD211D2BB57F005917E5 /* IkConstraint.c in Sources */, - 76F5BD1F1D2BB57F005917E5 /* EventData.c in Sources */, - 76F5BD1A1D2BB57F005917E5 /* AttachmentLoader.c in Sources */, + 76F28CBB1DEC7EBB00CDE54D /* Event.c in Sources */, 76AAA3C31D180F7C00C54FCB /* RaptorExample.cpp in Sources */, - 76F5BD281D2BB57F005917E5 /* RegionAttachment.c in Sources */, - 76F5BD2A1D2BB57F005917E5 /* SkeletonBounds.c in Sources */, - 76F5BD201D2BB57F005917E5 /* extension.c in Sources */, + 76F28CB51DEC7EBB00CDE54D /* AtlasAttachmentLoader.c in Sources */, 76AAA3C01D180F7C00C54FCB /* AppDelegate.cpp in Sources */, + 76F28CC31DEC7EBB00CDE54D /* PathConstraint.c in Sources */, 76AAA3C41D180F7C00C54FCB /* SimpleCommand.cpp in Sources */, - 765B3E181DA283F90071C974 /* SkeletonBinary.c in Sources */, - 76F5BD261D2BB57F005917E5 /* PathConstraint.c in Sources */, 503AE10017EB989F00D1A890 /* AppController.mm in Sources */, + 76F28CC11DEC7EBB00CDE54D /* MeshAttachment.c in Sources */, + 76F28CC01DEC7EBB00CDE54D /* Json.c in Sources */, + 76F28CC21DEC7EBB00CDE54D /* PathAttachment.c in Sources */, + 76F28CBA1DEC7EBB00CDE54D /* BoundingBoxAttachment.c in Sources */, + 76F28CBC1DEC7EBB00CDE54D /* EventData.c in Sources */, + 76F28CCD1DEC7EBB00CDE54D /* SlotData.c in Sources */, 76AAA40E1D18106000C54FCB /* SkeletonAnimation.cpp in Sources */, + 76F28CB41DEC7EBB00CDE54D /* Atlas.c in Sources */, + 76F28CB21DEC7EBB00CDE54D /* AnimationState.c in Sources */, 76AAA4111D18106000C54FCB /* spine-cocos2dx.cpp in Sources */, - 76F5BD181D2BB57F005917E5 /* AtlasAttachmentLoader.c in Sources */, - 76F5BD151D2BB57F005917E5 /* AnimationState.c in Sources */, - 76F5BD2F1D2BB57F005917E5 /* SlotData.c in Sources */, - 76F5BD271D2BB57F005917E5 /* PathConstraintData.c in Sources */, - 76F5BD291D2BB57F005917E5 /* Skeleton.c in Sources */, - 76F5BD241D2BB57F005917E5 /* MeshAttachment.c in Sources */, - 76F5BD1C1D2BB57F005917E5 /* BoneData.c in Sources */, + 76F28CCF1DEC7EBB00CDE54D /* TransformConstraintData.c in Sources */, + 76F28CCE1DEC7EBB00CDE54D /* TransformConstraint.c in Sources */, + 76F28CB91DEC7EBB00CDE54D /* BoneData.c in Sources */, 76AAA3C21D180F7C00C54FCB /* GoblinsExample.cpp in Sources */, - 76F5BD141D2BB57F005917E5 /* Animation.c in Sources */, - 76F5BD2B1D2BB57F005917E5 /* SkeletonData.c in Sources */, + 76F28CC91DEC7EBB00CDE54D /* SkeletonData.c in Sources */, + 76F28CC41DEC7EBB00CDE54D /* PathConstraintData.c in Sources */, + 76F28CB81DEC7EBB00CDE54D /* Bone.c in Sources */, + 76F28CB61DEC7EBB00CDE54D /* Attachment.c in Sources */, 503AE10217EB989F00D1A890 /* RootViewController.mm in Sources */, - 76F5BD191D2BB57F005917E5 /* Attachment.c in Sources */, - 76F5BD231D2BB57F005917E5 /* Json.c in Sources */, 503AE10117EB989F00D1A890 /* main.m in Sources */, + 76F28CCB1DEC7EBB00CDE54D /* Skin.c in Sources */, + 76F28CBF1DEC7EBB00CDE54D /* IkConstraintData.c in Sources */, + 76F28CC61DEC7EBB00CDE54D /* Skeleton.c in Sources */, 76AAA4101D18106000C54FCB /* SkeletonRenderer.cpp in Sources */, - 76F5BD301D2BB57F005917E5 /* TransformConstraint.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -775,41 +776,42 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 765B3E191DA284060071C974 /* SkeletonBinary.c in Sources */, + 76F28CD11DEC7FFA00CDE54D /* Animation.c in Sources */, + 76F28CD21DEC7FFA00CDE54D /* AnimationState.c in Sources */, + 76F28CD31DEC7FFA00CDE54D /* AnimationStateData.c in Sources */, + 76F28CD41DEC7FFA00CDE54D /* Atlas.c in Sources */, + 76F28CD51DEC7FFA00CDE54D /* AtlasAttachmentLoader.c in Sources */, + 76F28CD61DEC7FFA00CDE54D /* Attachment.c in Sources */, + 76F28CD71DEC7FFA00CDE54D /* AttachmentLoader.c in Sources */, + 76F28CD81DEC7FFA00CDE54D /* Bone.c in Sources */, + 76F28CD91DEC7FFA00CDE54D /* BoneData.c in Sources */, + 76F28CDA1DEC7FFA00CDE54D /* BoundingBoxAttachment.c in Sources */, + 76F28CDB1DEC7FFA00CDE54D /* Event.c in Sources */, + 76F28CDC1DEC7FFA00CDE54D /* EventData.c in Sources */, + 76F28CDD1DEC7FFA00CDE54D /* extension.c in Sources */, + 76F28CDE1DEC7FFA00CDE54D /* IkConstraint.c in Sources */, + 76F28CDF1DEC7FFA00CDE54D /* IkConstraintData.c in Sources */, + 76F28CE01DEC7FFA00CDE54D /* Json.c in Sources */, + 76F28CE11DEC7FFA00CDE54D /* Json.h in Sources */, + 76F28CE21DEC7FFA00CDE54D /* kvec.h in Sources */, + 76F28CE31DEC7FFA00CDE54D /* MeshAttachment.c in Sources */, + 76F28CE41DEC7FFA00CDE54D /* PathAttachment.c in Sources */, + 76F28CE51DEC7FFA00CDE54D /* PathConstraint.c in Sources */, + 76F28CE61DEC7FFA00CDE54D /* PathConstraintData.c in Sources */, + 76F28CE71DEC7FFA00CDE54D /* RegionAttachment.c in Sources */, + 76F28CE81DEC7FFA00CDE54D /* Skeleton.c in Sources */, + 76F28CE91DEC7FFA00CDE54D /* SkeletonBinary.c in Sources */, + 76F28CEA1DEC7FFA00CDE54D /* SkeletonBounds.c in Sources */, + 76F28CEB1DEC7FFA00CDE54D /* SkeletonData.c in Sources */, + 76F28CEC1DEC7FFA00CDE54D /* SkeletonJson.c in Sources */, + 76F28CED1DEC7FFA00CDE54D /* Skin.c in Sources */, + 76F28CEE1DEC7FFA00CDE54D /* Slot.c in Sources */, + 76F28CEF1DEC7FFA00CDE54D /* SlotData.c in Sources */, + 76F28CF01DEC7FFA00CDE54D /* TransformConstraint.c in Sources */, + 76F28CF11DEC7FFA00CDE54D /* TransformConstraintData.c in Sources */, + 76F28CF21DEC7FFA00CDE54D /* VertexAttachment.c in Sources */, 76F5BD561D2BD7EF005917E5 /* TankExample.cpp in Sources */, 76F5BD571D2BD7EF005917E5 /* TankExample.h in Sources */, - 76F5BD331D2BD4A9005917E5 /* Animation.c in Sources */, - 76F5BD341D2BD4A9005917E5 /* AnimationState.c in Sources */, - 76F5BD351D2BD4A9005917E5 /* AnimationStateData.c in Sources */, - 76F5BD361D2BD4A9005917E5 /* Atlas.c in Sources */, - 76F5BD371D2BD4A9005917E5 /* AtlasAttachmentLoader.c in Sources */, - 76F5BD381D2BD4A9005917E5 /* Attachment.c in Sources */, - 76F5BD391D2BD4A9005917E5 /* AttachmentLoader.c in Sources */, - 76F5BD3A1D2BD4A9005917E5 /* Bone.c in Sources */, - 76F5BD3B1D2BD4A9005917E5 /* BoneData.c in Sources */, - 76F5BD3C1D2BD4A9005917E5 /* BoundingBoxAttachment.c in Sources */, - 76F5BD3D1D2BD4A9005917E5 /* Event.c in Sources */, - 76F5BD3E1D2BD4A9005917E5 /* EventData.c in Sources */, - 76F5BD3F1D2BD4A9005917E5 /* extension.c in Sources */, - 76F5BD401D2BD4A9005917E5 /* IkConstraint.c in Sources */, - 76F5BD411D2BD4A9005917E5 /* IkConstraintData.c in Sources */, - 76F5BD421D2BD4A9005917E5 /* Json.c in Sources */, - 76F5BD431D2BD4A9005917E5 /* Json.h in Sources */, - 76F5BD441D2BD4A9005917E5 /* MeshAttachment.c in Sources */, - 76F5BD451D2BD4A9005917E5 /* PathAttachment.c in Sources */, - 76F5BD461D2BD4A9005917E5 /* PathConstraint.c in Sources */, - 76F5BD471D2BD4A9005917E5 /* PathConstraintData.c in Sources */, - 76F5BD481D2BD4A9005917E5 /* RegionAttachment.c in Sources */, - 76F5BD491D2BD4A9005917E5 /* Skeleton.c in Sources */, - 76F5BD4A1D2BD4A9005917E5 /* SkeletonBounds.c in Sources */, - 76F5BD4B1D2BD4A9005917E5 /* SkeletonData.c in Sources */, - 76F5BD4C1D2BD4A9005917E5 /* SkeletonJson.c in Sources */, - 76F5BD4D1D2BD4A9005917E5 /* Skin.c in Sources */, - 76F5BD4E1D2BD4A9005917E5 /* Slot.c in Sources */, - 76F5BD4F1D2BD4A9005917E5 /* SlotData.c in Sources */, - 76F5BD501D2BD4A9005917E5 /* TransformConstraint.c in Sources */, - 76F5BD511D2BD4A9005917E5 /* TransformConstraintData.c in Sources */, - 76F5BD521D2BD4A9005917E5 /* VertexAttachment.c in Sources */, 76AAA43B1D1811B000C54FCB /* AppDelegate.cpp in Sources */, 76AAA43C1D1811B000C54FCB /* AppDelegate.h in Sources */, 76AAA43D1D1811B000C54FCB /* AppMacros.h in Sources */, @@ -993,7 +995,7 @@ "$(SRCROOT)/../cocos2d/extensions", "$(SRCROOT)/../cocos2d/external", "$(SRCROOT)/../cocos2d/external/chipmunk/include/chipmunk", - "$(SRCROOT)/../../../spine-c/include", + "$(SRCROOT)/../../../spine-c/spine-c/include", "$(SRCROOT)/../../src", ); IPHONEOS_DEPLOYMENT_TARGET = 6.0; @@ -1018,7 +1020,7 @@ "$(SRCROOT)/../cocos2d/extensions", "$(SRCROOT)/../cocos2d/external", "$(SRCROOT)/../cocos2d/external/chipmunk/include/chipmunk", - "$(SRCROOT)/../../../spine-c/include", + "$(SRCROOT)/../../../spine-c/spine-c/include", "$(SRCROOT)/../../src", ); IPHONEOS_DEPLOYMENT_TARGET = 6.0; From e37416d935eaaa2c523d3559d72720e866324858 Mon Sep 17 00:00:00 2001 From: badlogic Date: Mon, 28 Nov 2016 16:19:20 +0100 Subject: [PATCH 3/3] [cocos2dx] Fixed up Visual Studio project for new spine-c location --- .../proj.win32/spine-cocos2d-x.vcxproj | 99 +++--- .../spine-cocos2d-x.vcxproj.filters | 291 ++++++------------ 2 files changed, 137 insertions(+), 253 deletions(-) diff --git a/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj b/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj index 95dfbbf27..9c3f07100 100644 --- a/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj +++ b/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj @@ -72,7 +72,7 @@ Disabled - $(EngineRoot)external;$(EngineRoot)cocos\audio\include;$(EngineRoot)external\chipmunk\include\chipmunk;$(EngineRoot)extensions;..\Classes;..;%(AdditionalIncludeDirectories);$(_COCOS_HEADER_WIN32_BEGIN);$(_COCOS_HEADER_WIN32_END);$(SolutionDir)..\..\..\spine-c\include;$(SolutionDir)..\..\src;$(IncludePath) + $(EngineRoot)external;$(EngineRoot)cocos\audio\include;$(EngineRoot)external\chipmunk\include\chipmunk;$(EngineRoot)extensions;..\Classes;..;%(AdditionalIncludeDirectories);$(_COCOS_HEADER_WIN32_BEGIN);$(_COCOS_HEADER_WIN32_END);$(SolutionDir)..\..\..\spine-c\spine-c\include;$(SolutionDir)..\..\src;$(IncludePath) WIN32;_DEBUG;_WINDOWS;_USE_MATH_DEFINES;GL_GLEXT_PROTOTYPES;CC_ENABLE_CHIPMUNK_INTEGRATION=1;COCOS2D_DEBUG=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) false EnableFastChecks @@ -145,37 +145,38 @@ xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -192,38 +193,8 @@ xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj.filters b/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj.filters index 406bf581a..ec02b77cb 100644 --- a/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj.filters +++ b/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj.filters @@ -57,102 +57,105 @@ spine-cocos2dx - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - src + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + + + spine + @@ -197,105 +200,15 @@ spine-cocos2dx - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - - - spine - src + + spine + + + spine +