mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
Getting there!
This commit is contained in:
parent
b50496fe05
commit
91225fe9e3
@ -32,6 +32,7 @@
|
|||||||
#define Spine_Atlas_h
|
#define Spine_Atlas_h
|
||||||
|
|
||||||
#include <spine/Vector.h>
|
#include <spine/Vector.h>
|
||||||
|
#include <spine/Extension.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -77,12 +78,14 @@ namespace Spine
|
|||||||
TextureWrap vWrap;
|
TextureWrap vWrap;
|
||||||
void* rendererObject;
|
void* rendererObject;
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
|
AtlasPage(std::string inName) : name(inName) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class AtlasRegion
|
class AtlasRegion
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AtlasPage page;
|
AtlasPage* page;
|
||||||
std::string name;
|
std::string name;
|
||||||
int x, y, width, height;
|
int x, y, width, height;
|
||||||
float u, v, u2, v2;
|
float u, v, u2, v2;
|
||||||
@ -94,14 +97,70 @@ namespace Spine
|
|||||||
Vector<int> pads;
|
Vector<int> pads;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TextureLoader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void load(AtlasPage page, std::string path) = 0;
|
||||||
|
virtual void unload(void* texture) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class Atlas
|
class Atlas
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Returns the first region found with the specified name. This method uses string comparison to find the region, so the result
|
Atlas(const char* path, TextureLoader& textureLoader);
|
||||||
|
|
||||||
|
Atlas(const char* data, int length, const char* dir, TextureLoader& textureLoader);
|
||||||
|
|
||||||
|
~Atlas();
|
||||||
|
|
||||||
|
void flipV();
|
||||||
|
|
||||||
|
/// Returns the first region found with the specified name. This method uses std::string comparison to find the region, so the result
|
||||||
/// should be cached rather than calling this method multiple times.
|
/// should be cached rather than calling this method multiple times.
|
||||||
/// @return The region, or NULL.
|
/// @return The region, or NULL.
|
||||||
AtlasRegion* findRegion(std::string name);
|
AtlasRegion* findRegion(std::string name);
|
||||||
|
|
||||||
|
void dispose();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vector<AtlasPage*> _pages;
|
||||||
|
Vector<AtlasRegion*> _regions;
|
||||||
|
TextureLoader& _textureLoader;
|
||||||
|
|
||||||
|
void load(const char* begin, int length, const char* dir);
|
||||||
|
|
||||||
|
class Str
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const char* begin;
|
||||||
|
const char* end;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void trim(Str* str);
|
||||||
|
|
||||||
|
/// Tokenize string without modification. Returns 0 on failure
|
||||||
|
static int readLine(const char** begin, const char* end, Str* str);
|
||||||
|
|
||||||
|
/// Moves str->begin past the first occurence of c. Returns 0 on failure
|
||||||
|
static int beginPast(Str* str, char c);
|
||||||
|
|
||||||
|
/// Returns 0 on failure
|
||||||
|
static int readValue(const char** begin, const char* end, Str* str);
|
||||||
|
|
||||||
|
/// Returns the number of tuple values read (1, 2, 4, or 0 for failure)
|
||||||
|
static int readTuple(const char** begin, const char* end, Str tuple[]);
|
||||||
|
|
||||||
|
static char* mallocString(Str* str);
|
||||||
|
|
||||||
|
static int indexOf(const char** array, int count, Str* str);
|
||||||
|
|
||||||
|
static int equals(Str* str, const char* other);
|
||||||
|
|
||||||
|
static int toInt(Str* str);
|
||||||
|
|
||||||
|
static Atlas* abortAtlas(Atlas* atlas);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_Atlas_h */
|
#endif /* Spine_Atlas_h */
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include <spine/Vector.h>
|
#include <spine/Vector.h>
|
||||||
#include <spine/HashMap.h>
|
#include <spine/HashMap.h>
|
||||||
|
#include <spine/Extension.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -124,23 +125,13 @@ namespace Spine
|
|||||||
for (size_t i = 0; i < items.size(); )
|
for (size_t i = 0; i < items.size(); )
|
||||||
{
|
{
|
||||||
T* item = items[i];
|
T* item = items[i];
|
||||||
delete item;
|
|
||||||
|
FREE(item);
|
||||||
|
|
||||||
items.erase(i);
|
items.erase(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T, typename H>
|
|
||||||
static void cleanUpHashMapOfPointers(HashMap<K, T*, H>& hashMap)
|
|
||||||
{
|
|
||||||
for (typename HashMap<K, T*, H>::Iterator i = hashMap.begin(); i != hashMap.end(); )
|
|
||||||
{
|
|
||||||
delete i.second();
|
|
||||||
|
|
||||||
i = hashMap.erase(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// ctor, copy ctor, and assignment should be private in a Singleton
|
// ctor, copy ctor, and assignment should be private in a Singleton
|
||||||
ContainerUtil();
|
ContainerUtil();
|
||||||
|
|||||||
56
spine-cpp/spine-cpp/include/spine/Extension.h
Normal file
56
spine-cpp/spine-cpp/include/spine/Extension.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Spine Runtimes Software License v2.5
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2016, Esoteric Software
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||||
|
* non-transferable license to use, install, execute, and perform the Spine
|
||||||
|
* Runtimes software and derivative works solely for personal or internal
|
||||||
|
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||||
|
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||||
|
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||||
|
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||||
|
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||||
|
* or other intellectual property or proprietary rights notices on or in the
|
||||||
|
* Software, including any copy thereof. Redistributions in binary or source
|
||||||
|
* form must include this license and terms.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||||
|
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef Spine_Extension_h
|
||||||
|
#define Spine_Extension_h
|
||||||
|
|
||||||
|
/* All allocation uses these. */
|
||||||
|
#define MALLOC(TYPE,COUNT) ((TYPE*)spineAlloc(sizeof(TYPE) * (COUNT), __FILE__, __LINE__))
|
||||||
|
#define REALLOC(PTR,TYPE,COUNT) ((TYPE*)spineRealloc(PTR, sizeof(TYPE) * (COUNT), __FILE__, __LINE__))
|
||||||
|
|
||||||
|
/* Frees memory. Can be used on const types. */
|
||||||
|
#define FREE(VALUE) spineFree((void*)VALUE)
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
namespace Spine
|
||||||
|
{
|
||||||
|
/// Implement this function to use your own memory allocator.
|
||||||
|
void* spineAlloc(size_t size, const char* file, int line);
|
||||||
|
|
||||||
|
void* spineRealloc(void* ptr, size_t size, const char* file, int line);
|
||||||
|
|
||||||
|
/// If you implement spineAlloc, you should also implement this function.
|
||||||
|
void spineFree(void* mem);
|
||||||
|
|
||||||
|
char* spineReadFile(const char* path, int* length);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Spine_Extension_h */
|
||||||
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include <spine/Vector.h>
|
#include <spine/Vector.h>
|
||||||
#include <spine/ContainerUtil.h>
|
#include <spine/ContainerUtil.h>
|
||||||
|
#include <spine/Extension.h>
|
||||||
|
|
||||||
namespace Spine
|
namespace Spine
|
||||||
{
|
{
|
||||||
@ -61,7 +62,10 @@ namespace Spine
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new T();
|
T* ret = MALLOC(T, 1);
|
||||||
|
new (ret) T();
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,8 @@
|
|||||||
#ifndef Spine_Vector_h
|
#ifndef Spine_Vector_h
|
||||||
#define Spine_Vector_h
|
#define Spine_Vector_h
|
||||||
|
|
||||||
|
#include <spine/Extension.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -149,7 +151,7 @@ namespace Spine
|
|||||||
size_t newCapacity = inCapacity > 0 ? inCapacity : _capacity > 0 ? _capacity * 2 : 1;
|
size_t newCapacity = inCapacity > 0 ? inCapacity : _capacity > 0 ? _capacity * 2 : 1;
|
||||||
if (newCapacity > _capacity)
|
if (newCapacity > _capacity)
|
||||||
{
|
{
|
||||||
_buffer = static_cast<T*>(realloc(_buffer, newCapacity * sizeof(T)));
|
_buffer = REALLOC(_buffer, T, newCapacity);
|
||||||
_capacity = newCapacity;
|
_capacity = newCapacity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,10 +175,11 @@ namespace Spine
|
|||||||
{
|
{
|
||||||
assert(n > 0);
|
assert(n > 0);
|
||||||
|
|
||||||
void* ptr = malloc(n * sizeof(T));
|
T* ptr = MALLOC(T, n);
|
||||||
|
|
||||||
assert(ptr);
|
assert(ptr);
|
||||||
|
|
||||||
return static_cast<T*>(ptr);
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocate(T* buffer)
|
void deallocate(T* buffer)
|
||||||
|
|||||||
@ -1,39 +1,399 @@
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Spine Runtimes Software License v2.5
|
* Spine Runtimes Software License v2.5
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2016, Esoteric Software
|
* Copyright (c) 2013-2016, Esoteric Software
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||||
* non-transferable license to use, install, execute, and perform the Spine
|
* non-transferable license to use, install, execute, and perform the Spine
|
||||||
* Runtimes software and derivative works solely for personal or internal
|
* Runtimes software and derivative works solely for personal or internal
|
||||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||||
* or other intellectual property or proprietary rights notices on or in the
|
* or other intellectual property or proprietary rights notices on or in the
|
||||||
* Software, including any copy thereof. Redistributions in binary or source
|
* Software, including any copy thereof. Redistributions in binary or source
|
||||||
* form must include this license and terms.
|
* form must include this license and terms.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <spine/Atlas.h>
|
#include <spine/Atlas.h>
|
||||||
|
|
||||||
|
#include <spine/ContainerUtil.h>
|
||||||
|
|
||||||
namespace Spine
|
namespace Spine
|
||||||
{
|
{
|
||||||
|
Atlas::Atlas(const char* path, TextureLoader& textureLoader) : _textureLoader(textureLoader)
|
||||||
|
{
|
||||||
|
int dirLength;
|
||||||
|
char *dir;
|
||||||
|
int length;
|
||||||
|
const char* data;
|
||||||
|
|
||||||
|
/* Get directory from atlas path. */
|
||||||
|
const char* lastForwardSlash = strrchr(path, '/');
|
||||||
|
const char* lastBackwardSlash = strrchr(path, '\\');
|
||||||
|
const char* lastSlash = lastForwardSlash > lastBackwardSlash ? lastForwardSlash : lastBackwardSlash;
|
||||||
|
if (lastSlash == path) lastSlash++; /* Never drop starting slash. */
|
||||||
|
dirLength = (int)(lastSlash ? lastSlash - path : 0);
|
||||||
|
dir = MALLOC(char, dirLength + 1);
|
||||||
|
memcpy(dir, path, dirLength);
|
||||||
|
dir[dirLength] = '\0';
|
||||||
|
|
||||||
|
data = spineReadFile(path, &length);
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
load(data, length, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
FREE(data);
|
||||||
|
FREE(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
Atlas::Atlas(const char* data, int length, const char* dir, TextureLoader& textureLoader) : _textureLoader(textureLoader)
|
||||||
|
{
|
||||||
|
load(data, length, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
Atlas::~Atlas()
|
||||||
|
{
|
||||||
|
ContainerUtil::cleanUpVectorOfPointers(_pages);
|
||||||
|
ContainerUtil::cleanUpVectorOfPointers(_regions);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Atlas::flipV()
|
||||||
|
{
|
||||||
|
for (size_t i = 0, n = _regions.size(); i < n; ++i)
|
||||||
|
{
|
||||||
|
AtlasRegion* regionP = _regions[i];
|
||||||
|
AtlasRegion region = *regionP;
|
||||||
|
region.v = 1 - region.v;
|
||||||
|
region.v2 = 1 - region.v2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AtlasRegion* Atlas::findRegion(std::string name)
|
AtlasRegion* Atlas::findRegion(std::string name)
|
||||||
{
|
{
|
||||||
|
for (size_t i = 0, n = _regions.size(); i < n; ++i)
|
||||||
|
{
|
||||||
|
if (_regions[i]->name == name)
|
||||||
|
{
|
||||||
|
return _regions[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Atlas::dispose()
|
||||||
|
{
|
||||||
|
for (size_t i = 0, n = _pages.size(); i < n; ++i)
|
||||||
|
{
|
||||||
|
_textureLoader.unload(_pages[i]->rendererObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Atlas::load(const char* begin, int length, const char* dir)
|
||||||
|
{
|
||||||
|
static const char* formatNames[] = { "", "Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888", "RGBA8888" };
|
||||||
|
static const char* textureFilterNames[] = { "", "Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest",
|
||||||
|
"MipMapNearestLinear", "MipMapLinearLinear" };
|
||||||
|
|
||||||
|
int count;
|
||||||
|
const char* end = begin + length;
|
||||||
|
int dirLength = (int)strlen(dir);
|
||||||
|
int needsSlash = dirLength > 0 && dir[dirLength - 1] != '/' && dir[dirLength - 1] != '\\';
|
||||||
|
|
||||||
|
AtlasPage *page = 0;
|
||||||
|
Str str;
|
||||||
|
Str tuple[4];
|
||||||
|
|
||||||
|
while (readLine(&begin, end, &str))
|
||||||
|
{
|
||||||
|
if (str.end - str.begin == 0)
|
||||||
|
{
|
||||||
|
page = 0;
|
||||||
|
}
|
||||||
|
else if (!page)
|
||||||
|
{
|
||||||
|
char* name = mallocString(&str);
|
||||||
|
char* path = MALLOC(char, dirLength + needsSlash + strlen(name) + 1);
|
||||||
|
memcpy(path, dir, dirLength);
|
||||||
|
if (needsSlash)
|
||||||
|
{
|
||||||
|
path[dirLength] = '/';
|
||||||
|
}
|
||||||
|
strcpy(path + dirLength + needsSlash, name);
|
||||||
|
|
||||||
|
AtlasPage* page = MALLOC(AtlasPage, 1);
|
||||||
|
new (page) AtlasPage(std::string(name));
|
||||||
|
|
||||||
|
FREE(name);
|
||||||
|
|
||||||
|
assert(readTuple(&begin, end, tuple) == 2);
|
||||||
|
|
||||||
|
/* size is only optional for an atlas packed with an old TexturePacker. */
|
||||||
|
page->width = toInt(tuple);
|
||||||
|
page->height = toInt(tuple + 1);
|
||||||
|
assert(readTuple(&begin, end, tuple));
|
||||||
|
|
||||||
|
page->format = (Format)indexOf(formatNames, 8, tuple);
|
||||||
|
|
||||||
|
assert(readTuple(&begin, end, tuple));
|
||||||
|
page->minFilter = (TextureFilter)indexOf(textureFilterNames, 8, tuple);
|
||||||
|
page->magFilter = (TextureFilter)indexOf(textureFilterNames, 8, tuple + 1);
|
||||||
|
|
||||||
|
assert(readValue(&begin, end, &str));
|
||||||
|
|
||||||
|
page->uWrap = TextureWrap_ClampToEdge;
|
||||||
|
page->vWrap = TextureWrap_ClampToEdge;
|
||||||
|
if (!equals(&str, "none"))
|
||||||
|
{
|
||||||
|
if (str.end - str.begin == 1)
|
||||||
|
{
|
||||||
|
if (*str.begin == 'x')
|
||||||
|
{
|
||||||
|
page->uWrap = TextureWrap_Repeat;
|
||||||
|
}
|
||||||
|
else if (*str.begin == 'y')
|
||||||
|
{
|
||||||
|
page->vWrap = TextureWrap_Repeat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (equals(&str, "xy"))
|
||||||
|
{
|
||||||
|
page->uWrap = TextureWrap_Repeat;
|
||||||
|
page->vWrap = TextureWrap_Repeat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_textureLoader.load(*page, std::string(path));
|
||||||
|
|
||||||
|
FREE(path);
|
||||||
|
|
||||||
|
_pages.push_back(page);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AtlasRegion* region = MALLOC(AtlasRegion, 1);
|
||||||
|
new (region) AtlasRegion();
|
||||||
|
|
||||||
|
region->page = page;
|
||||||
|
region->name = mallocString(&str);
|
||||||
|
|
||||||
|
assert(readValue(&begin, end, &str));
|
||||||
|
region->rotate = equals(&str, "true");
|
||||||
|
|
||||||
|
assert(readTuple(&begin, end, tuple) == 2);
|
||||||
|
region->x = toInt(tuple);
|
||||||
|
region->y = toInt(tuple + 1);
|
||||||
|
|
||||||
|
assert(readTuple(&begin, end, tuple) == 2);
|
||||||
|
region->width = toInt(tuple);
|
||||||
|
region->height = toInt(tuple + 1);
|
||||||
|
|
||||||
|
region->u = region->x / (float)page->width;
|
||||||
|
region->v = region->y / (float)page->height;
|
||||||
|
if (region->rotate)
|
||||||
|
{
|
||||||
|
region->u2 = (region->x + region->height) / (float)page->width;
|
||||||
|
region->v2 = (region->y + region->width) / (float)page->height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
region->u2 = (region->x + region->width) / (float)page->width;
|
||||||
|
region->v2 = (region->y + region->height) / (float)page->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
count = readTuple(&begin, end, tuple);
|
||||||
|
assert(count);
|
||||||
|
|
||||||
|
if (count == 4)
|
||||||
|
{
|
||||||
|
/* split is optional */
|
||||||
|
region->splits.reserve(4);
|
||||||
|
region->splits[0] = toInt(tuple);
|
||||||
|
region->splits[1] = toInt(tuple + 1);
|
||||||
|
region->splits[2] = toInt(tuple + 2);
|
||||||
|
region->splits[3] = toInt(tuple + 3);
|
||||||
|
|
||||||
|
count = readTuple(&begin, end, tuple);
|
||||||
|
assert(count);
|
||||||
|
|
||||||
|
if (count == 4)
|
||||||
|
{
|
||||||
|
/* pad is optional, but only present with splits */
|
||||||
|
region->pads.reserve(4);
|
||||||
|
region->pads[0] = toInt(tuple);
|
||||||
|
region->pads[1] = toInt(tuple + 1);
|
||||||
|
region->pads[2] = toInt(tuple + 2);
|
||||||
|
region->pads[3] = toInt(tuple + 3);
|
||||||
|
|
||||||
|
assert(readTuple(&begin, end, tuple));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
region->originalWidth = toInt(tuple);
|
||||||
|
region->originalHeight = toInt(tuple + 1);
|
||||||
|
|
||||||
|
readTuple(&begin, end, tuple);
|
||||||
|
region->offsetX = toInt(tuple);
|
||||||
|
region->offsetY = toInt(tuple + 1);
|
||||||
|
|
||||||
|
assert(readValue(&begin, end, &str));
|
||||||
|
|
||||||
|
region->index = toInt(&str);
|
||||||
|
|
||||||
|
_regions.push_back(region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Atlas::trim(Str* str)
|
||||||
|
{
|
||||||
|
while (isspace((unsigned char)*str->begin) && str->begin < str->end)
|
||||||
|
{
|
||||||
|
(str->begin)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str->begin == str->end)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
str->end--;
|
||||||
|
|
||||||
|
while (isspace((unsigned char)*str->end) && str->end >= str->begin)
|
||||||
|
{
|
||||||
|
str->end--;
|
||||||
|
}
|
||||||
|
|
||||||
|
str->end++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Atlas::readLine(const char** begin, const char* end, Str* str)
|
||||||
|
{
|
||||||
|
if (*begin == end) return 0;
|
||||||
|
str->begin = *begin;
|
||||||
|
|
||||||
|
/* Find next delimiter. */
|
||||||
|
while (*begin != end && **begin != '\n')
|
||||||
|
{
|
||||||
|
(*begin)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
str->end = *begin;
|
||||||
|
trim(str);
|
||||||
|
|
||||||
|
if (*begin != end)
|
||||||
|
{
|
||||||
|
(*begin)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Atlas::beginPast(Str* str, char c)
|
||||||
|
{
|
||||||
|
const char* begin = str->begin;
|
||||||
|
while (1) {
|
||||||
|
char lastSkippedChar = *begin;
|
||||||
|
if (begin == str->end)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
begin++;
|
||||||
|
if (lastSkippedChar == c)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
str->begin = begin;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Atlas::readValue(const char** begin, const char* end, Str* str)
|
||||||
|
{
|
||||||
|
readLine(begin, end, str);
|
||||||
|
if (!beginPast(str, ':'))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
trim(str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Atlas::readTuple(const char** begin, const char* end, Str tuple[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Str str = { NULL, NULL };
|
||||||
|
readLine(begin, end, &str);
|
||||||
|
if (!beginPast(&str, ':'))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
tuple[i].begin = str.begin;
|
||||||
|
if (!beginPast(&str, ','))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tuple[i].end = str.begin - 2;
|
||||||
|
trim(&tuple[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
tuple[i].begin = str.begin;
|
||||||
|
tuple[i].end = str.end;
|
||||||
|
trim(&tuple[i]);
|
||||||
|
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* Atlas::mallocString(Str* str)
|
||||||
|
{
|
||||||
|
int length = (int)(str->end - str->begin);
|
||||||
|
char* string = MALLOC(char, length + 1);
|
||||||
|
memcpy(string, str->begin, length);
|
||||||
|
string[length] = '\0';
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Atlas::indexOf(const char** array, int count, Str* str)
|
||||||
|
{
|
||||||
|
int length = (int)(str->end - str->begin);
|
||||||
|
int i;
|
||||||
|
for (i = count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (strncmp(array[i], str->begin, length) == 0)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Atlas::equals(Str* str, const char* other)
|
||||||
|
{
|
||||||
|
return strncmp(other, str->begin, str->end - str->begin) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Atlas::toInt(Str* str)
|
||||||
|
{
|
||||||
|
return (int)strtol(str->begin, (char**)&str->end, 10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
73
spine-cpp/spine-cpp/src/spine/Extension.cpp
Normal file
73
spine-cpp/spine-cpp/src/spine/Extension.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Spine Runtimes Software License v2.5
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2016, Esoteric Software
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||||
|
* non-transferable license to use, install, execute, and perform the Spine
|
||||||
|
* Runtimes software and derivative works solely for personal or internal
|
||||||
|
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||||
|
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||||
|
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||||
|
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||||
|
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||||
|
* or other intellectual property or proprietary rights notices on or in the
|
||||||
|
* Software, including any copy thereof. Redistributions in binary or source
|
||||||
|
* form must include this license and terms.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||||
|
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <spine/Extension.h>
|
||||||
|
|
||||||
|
//#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
namespace Spine
|
||||||
|
{
|
||||||
|
void* spineAlloc(size_t size, const char* file, int line)
|
||||||
|
{
|
||||||
|
//printf("spineAlloc size: %lu, file: %s, line: %d \n", size, file, line);
|
||||||
|
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* spineRealloc(void* ptr, size_t size, const char* file, int line)
|
||||||
|
{
|
||||||
|
//printf("spineRealloc size: %lu, file: %s, line: %d \n", size, file, line);
|
||||||
|
|
||||||
|
return realloc(ptr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void spineFree(void* mem)
|
||||||
|
{
|
||||||
|
free(mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* spineReadFile(const char* path, int* length)
|
||||||
|
{
|
||||||
|
char *data;
|
||||||
|
FILE *file = fopen(path, "rb");
|
||||||
|
if (!file) return 0;
|
||||||
|
|
||||||
|
fseek(file, 0, SEEK_END);
|
||||||
|
*length = (int)ftell(file);
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
|
data = MALLOC(char, *length);
|
||||||
|
fread(data, 1, *length, file);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -50,6 +50,7 @@
|
|||||||
#include <spine/PathAttachment.h>
|
#include <spine/PathAttachment.h>
|
||||||
|
|
||||||
#include <spine/ContainerUtil.h>
|
#include <spine/ContainerUtil.h>
|
||||||
|
#include <spine/Extension.h>
|
||||||
|
|
||||||
namespace Spine
|
namespace Spine
|
||||||
{
|
{
|
||||||
@ -74,12 +75,14 @@ namespace Spine
|
|||||||
Bone* bone;
|
Bone* bone;
|
||||||
if (data->getParent() == NULL)
|
if (data->getParent() == NULL)
|
||||||
{
|
{
|
||||||
bone = new Bone(*data, *this, NULL);
|
bone = MALLOC(Bone, 1);
|
||||||
|
new (bone) Bone(*data, *this, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Bone* parent = _bones[data->getParent()->getIndex()];
|
Bone* parent = _bones[data->getParent()->getIndex()];
|
||||||
bone = new Bone(*data, *this, parent);
|
bone = MALLOC(Bone, 1);
|
||||||
|
new (bone) Bone(*data, *this, parent);
|
||||||
parent->getChildren().push_back(bone);
|
parent->getChildren().push_back(bone);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +96,8 @@ namespace Spine
|
|||||||
SlotData* data = (*i);
|
SlotData* data = (*i);
|
||||||
|
|
||||||
Bone* bone = _bones[data->getBoneData().getIndex()];
|
Bone* bone = _bones[data->getBoneData().getIndex()];
|
||||||
Slot* slot = new Slot(*data, *bone);
|
Slot* slot = MALLOC(Slot, 1);
|
||||||
|
new (slot) Slot(*data, *bone);
|
||||||
|
|
||||||
_slots.push_back(slot);
|
_slots.push_back(slot);
|
||||||
_drawOrder.push_back(slot);
|
_drawOrder.push_back(slot);
|
||||||
@ -104,7 +108,10 @@ namespace Spine
|
|||||||
{
|
{
|
||||||
IkConstraintData* data = (*i);
|
IkConstraintData* data = (*i);
|
||||||
|
|
||||||
_ikConstraints.push_back(new IkConstraint(*data, *this));
|
IkConstraint* constraint = MALLOC(IkConstraint, 1);
|
||||||
|
new (constraint) IkConstraint(*data, *this);
|
||||||
|
|
||||||
|
_ikConstraints.push_back(constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
_transformConstraints.reserve(_data.getTransformConstraints().size());
|
_transformConstraints.reserve(_data.getTransformConstraints().size());
|
||||||
@ -112,7 +119,10 @@ namespace Spine
|
|||||||
{
|
{
|
||||||
TransformConstraintData* data = (*i);
|
TransformConstraintData* data = (*i);
|
||||||
|
|
||||||
_transformConstraints.push_back(new TransformConstraint(*data, *this));
|
TransformConstraint* constraint = MALLOC(TransformConstraint, 1);
|
||||||
|
new (constraint) TransformConstraint(*data, *this);
|
||||||
|
|
||||||
|
_transformConstraints.push_back(constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
_pathConstraints.reserve(_data.getPathConstraints().size());
|
_pathConstraints.reserve(_data.getPathConstraints().size());
|
||||||
@ -120,7 +130,10 @@ namespace Spine
|
|||||||
{
|
{
|
||||||
PathConstraintData* data = (*i);
|
PathConstraintData* data = (*i);
|
||||||
|
|
||||||
_pathConstraints.push_back(new PathConstraint(*data, *this));
|
PathConstraint* constraint = MALLOC(PathConstraint, 1);
|
||||||
|
new (constraint) PathConstraint(*data, *this);
|
||||||
|
|
||||||
|
_pathConstraints.push_back(constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCache();
|
updateCache();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user