From a398fe620135c1e4e4a842b9578d3e3cf7ba22c3 Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Wed, 3 Apr 2013 03:37:52 +0200 Subject: [PATCH] Atlas now prefixes images referenced in the atlas file with the directory containing the atlas file. --- spine-c/example/main.c | 28 +++++++++++++-- spine-c/include/spine/Atlas.h | 6 ++-- spine-c/include/spine/extension.h | 2 +- spine-c/src/spine/Atlas.c | 34 ++++++++++++++++--- .../src/spine/spine-cocos2d-iphone.m | 4 +-- spine-cocos2dx/src/spine/spine-cocos2dx.cpp | 4 +-- spine-sfml/data/spineboy.atlas | 2 +- spine-sfml/src/spine/spine-sfml.cpp | 4 +-- 8 files changed, 67 insertions(+), 17 deletions(-) diff --git a/spine-c/example/main.c b/spine-c/example/main.c index 5ff0e1763..3d169f550 100644 --- a/spine-c/example/main.c +++ b/spine-c/example/main.c @@ -22,7 +22,7 @@ void _ExampleAtlasPage_dispose (AtlasPage* page) { FREE(self); } -AtlasPage* AtlasPage_create (const char* name) { +AtlasPage* AtlasPage_create (const char* name, const char* path) { ExampleAtlasPage* self = NEW(ExampleAtlasPage); _AtlasPage_init(SUPER(self), name); VTABLE(AtlasPage, self) ->dispose = _ExampleAtlasPage_dispose; @@ -97,8 +97,32 @@ char* _Util_readFile (const char* path, int* length) { } /**/ - +#include int main (void) { + const char* path = "/moo.atlas"; + + char* lastForwardSlash = strrchr(path, '/'); + char* lastBackwardSlash = strrchr(path, '\\'); + char* lastSlash = lastForwardSlash > lastBackwardSlash ? lastForwardSlash : lastBackwardSlash; + if (lastSlash == path) lastSlash++; // Never drop starting slash. + int dirLength = lastSlash ? lastSlash - path : 0; + char* dir = MALLOC(char, dirLength + 1); + memcpy(dir, path, dirLength); + dir[dirLength] = '\0'; + + dirLength = strlen(dir); + int needsSlash = dirLength > 0 && dir[dirLength - 1] != '/' && dir[dirLength - 1] != '\\'; + const char* name = "cow.png"; + char* imagePath = MALLOC(char, dirLength + strlen(name) + needsSlash + 1); + memcpy(imagePath, dir, dirLength); + if (needsSlash) imagePath[dirLength] = '/'; + strcpy(imagePath + dirLength + needsSlash, name); + + printf("'%s'", imagePath); + return 0; + + //const char* dir = MALLOC(char, strlen(path) - separator + 1); + Atlas* atlas = Atlas_readAtlasFile("data/spineboy.atlas"); printf("First region name: %s, x: %d, y: %d\n", atlas->regions->name, atlas->regions->x, atlas->regions->y); printf("First page name: %s, extraData: %d\n", atlas->pages->name, ((ExampleAtlasPage*)atlas->pages)->extraData); diff --git a/spine-c/include/spine/Atlas.h b/spine-c/include/spine/Atlas.h index b4cacce28..e58d5250b 100644 --- a/spine-c/include/spine/Atlas.h +++ b/spine-c/include/spine/Atlas.h @@ -60,7 +60,7 @@ struct AtlasPage { const void* const vtable; }; -AtlasPage* AtlasPage_create (const char* name); +AtlasPage* AtlasPage_create (const char* name, const char* path); void AtlasPage_dispose (AtlasPage* self); /**/ @@ -90,7 +90,9 @@ typedef struct { AtlasRegion* regions; } Atlas; -Atlas* Atlas_readAtlas (const char* data, unsigned long length); +/* Image files referenced in the atlas file will be prefixed dir. */ +Atlas* Atlas_readAtlas (const char* data, int length, const char* dir); +/* Image files referenced in the atlas file will be prefixed with the directory containing the atlas file. */ Atlas* Atlas_readAtlasFile (const char* path); void Atlas_dispose (Atlas* atlas); diff --git a/spine-c/include/spine/extension.h b/spine-c/include/spine/extension.h index 98a39172a..798298565 100644 --- a/spine-c/include/spine/extension.h +++ b/spine-c/include/spine/extension.h @@ -98,7 +98,7 @@ extern "C" { RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region); -AtlasPage* AtlasPage_create (const char* name); +AtlasPage* AtlasPage_create (const char* name, const char* path); char* _Util_readFile (const char* path, int* length); diff --git a/spine-c/src/spine/Atlas.c b/spine-c/src/spine/Atlas.c index 16b011f23..22caf3ca8 100644 --- a/spine-c/src/spine/Atlas.c +++ b/spine-c/src/spine/Atlas.c @@ -33,7 +33,7 @@ namespace spine { void _AtlasPage_init (AtlasPage* self, const char* name) { CONST_CAST(_AtlasPageVtable*, self->vtable) = NEW(_AtlasPageVtable); - self->name = name; /* name is guaranteed to be memory we allocated. */ + MALLOC_STR(self->name, name); } void _AtlasPage_deinit (AtlasPage* self) { @@ -172,8 +172,10 @@ static const char* formatNames[] = {"Alpha", "Intensity", "LuminanceAlpha", "RGB static const char* textureFilterNames[] = {"Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest", "MipMapNearestLinear", "MipMapLinearLinear"}; -Atlas* Atlas_readAtlas (const char* begin, unsigned long length) { +Atlas* Atlas_readAtlas (const char* begin, int length, const char* dir) { const char* end = begin + length; + int dirLength = strlen(dir); + int needsSlash = dirLength > 0 && dir[dirLength - 1] != '/' && dir[dirLength - 1] != '\\'; Atlas* self = NEW(Atlas); @@ -187,13 +189,22 @@ Atlas* Atlas_readAtlas (const char* begin, unsigned long length) { if (str.end - str.begin == 0) { page = 0; } else if (!page) { - page = AtlasPage_create(mallocString(&str)); + char* name = mallocString(&str); + char* path = MALLOC(char, dirLength + needsSlash + strlen(name) + 1); + memcpy(path, dir, dirLength); + if (needsSlash) path[dirLength] = '/'; + strcpy(path + dirLength + needsSlash, name); + + page = AtlasPage_create(name, path); if (lastPage) lastPage->next = page; else self->pages = page; lastPage = page; + FREE(name); + FREE(path); + if (!readValue(end, &str)) return abortAtlas(self); page->format = (AtlasFormat)indexOf(formatNames, 7, &str); @@ -265,11 +276,24 @@ Atlas* Atlas_readAtlas (const char* begin, unsigned long length) { } Atlas* Atlas_readAtlasFile (const char* path) { + Atlas* atlas = 0; + + // Get directory from atlas path. + const char* lastForwardSlash = strrchr(path, '/'); + const char* lastBackwardSlash = strrchr(path, '\\'); + const char* lastSlash = lastForwardSlash > lastBackwardSlash ? lastForwardSlash : lastBackwardSlash; + if (lastSlash == path) lastSlash++; // Never drop starting slash. + int dirLength = lastSlash ? lastSlash - path : 0; + char* dir = MALLOC(char, dirLength + 1); + memcpy(dir, path, dirLength); + dir[dirLength] = '\0'; + int length; const char* data = _Util_readFile(path, &length); - if (!data) return 0; - Atlas* atlas = Atlas_readAtlas(data, length); + if (data) atlas = Atlas_readAtlas(data, length, dir); + FREE(data); + FREE(dir); return atlas; } diff --git a/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.m b/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.m index ac178aae3..c4c9a7ae4 100644 --- a/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.m +++ b/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.m @@ -36,12 +36,12 @@ void _Cocos2dAtlasPage_dispose (AtlasPage* page) { FREE(page); } -AtlasPage* AtlasPage_create (const char* name) { +AtlasPage* AtlasPage_create (const char* name, const char* path) { Cocos2dAtlasPage* self = NEW(Cocos2dAtlasPage); _AtlasPage_init(SUPER(self), name); VTABLE(AtlasPage, self) ->dispose = _Cocos2dAtlasPage_dispose; - self->texture = [[CCTextureCache sharedTextureCache] addImage:@(name)]; + self->texture = [[CCTextureCache sharedTextureCache] addImage:@(path)]; [self->texture retain]; self->atlas = [[CCTextureAtlas alloc] initWithTexture:self->texture capacity:4]; [self->atlas retain]; diff --git a/spine-cocos2dx/src/spine/spine-cocos2dx.cpp b/spine-cocos2dx/src/spine/spine-cocos2dx.cpp index 628bfb07b..b3d585845 100644 --- a/spine-cocos2dx/src/spine/spine-cocos2dx.cpp +++ b/spine-cocos2dx/src/spine/spine-cocos2dx.cpp @@ -39,12 +39,12 @@ void _Cocos2dxAtlasPage_dispose (AtlasPage* page) { FREE(page); } -AtlasPage* AtlasPage_create (const char* name) { +AtlasPage* AtlasPage_create (const char* name, const char* path) { Cocos2dxAtlasPage* self = NEW(Cocos2dxAtlasPage); _AtlasPage_init(SUPER(self), name); VTABLE(AtlasPage, self) ->dispose = _Cocos2dxAtlasPage_dispose; - self->texture = CCTextureCache::sharedTextureCache()->addImage(name); + self->texture = CCTextureCache::sharedTextureCache()->addImage(path); self->texture->retain(); self->atlas = CCTextureAtlas::createWithTexture(self->texture, 4); self->atlas->retain(); diff --git a/spine-sfml/data/spineboy.atlas b/spine-sfml/data/spineboy.atlas index ac19de904..88fb3e0b5 100644 --- a/spine-sfml/data/spineboy.atlas +++ b/spine-sfml/data/spineboy.atlas @@ -1,5 +1,5 @@ -../data/spineboy.png +spineboy.png format: RGBA8888 filter: Nearest,Nearest repeat: none diff --git a/spine-sfml/src/spine/spine-sfml.cpp b/spine-sfml/src/spine/spine-sfml.cpp index 10aaecdf0..201f32120 100644 --- a/spine-sfml/src/spine/spine-sfml.cpp +++ b/spine-sfml/src/spine/spine-sfml.cpp @@ -50,13 +50,13 @@ void _SfmlAtlasPage_dispose (AtlasPage* page) { FREE(page); } -AtlasPage* AtlasPage_create (const char* name) { +AtlasPage* AtlasPage_create (const char* name, const char* path) { SfmlAtlasPage* self = NEW(SfmlAtlasPage); _AtlasPage_init(SUPER(self), name); VTABLE(AtlasPage, self) ->dispose = _SfmlAtlasPage_dispose; self->texture = new Texture(); - self->texture->loadFromFile(name); + self->texture->loadFromFile(path); return SUPER(self); }