Atlas now prefixes images referenced in the atlas file with the directory containing the atlas file.

This commit is contained in:
NathanSweet 2013-04-03 03:37:52 +02:00
parent 4bf3dde6c3
commit a398fe6201
8 changed files with 67 additions and 17 deletions

View File

@ -22,7 +22,7 @@ void _ExampleAtlasPage_dispose (AtlasPage* page) {
FREE(self); FREE(self);
} }
AtlasPage* AtlasPage_create (const char* name) { AtlasPage* AtlasPage_create (const char* name, const char* path) {
ExampleAtlasPage* self = NEW(ExampleAtlasPage); ExampleAtlasPage* self = NEW(ExampleAtlasPage);
_AtlasPage_init(SUPER(self), name); _AtlasPage_init(SUPER(self), name);
VTABLE(AtlasPage, self) ->dispose = _ExampleAtlasPage_dispose; VTABLE(AtlasPage, self) ->dispose = _ExampleAtlasPage_dispose;
@ -97,8 +97,32 @@ char* _Util_readFile (const char* path, int* length) {
} }
/**/ /**/
#include <spine/extension.h>
int main (void) { 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"); 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 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); printf("First page name: %s, extraData: %d\n", atlas->pages->name, ((ExampleAtlasPage*)atlas->pages)->extraData);

View File

@ -60,7 +60,7 @@ struct AtlasPage {
const void* const vtable; const void* const vtable;
}; };
AtlasPage* AtlasPage_create (const char* name); AtlasPage* AtlasPage_create (const char* name, const char* path);
void AtlasPage_dispose (AtlasPage* self); void AtlasPage_dispose (AtlasPage* self);
/**/ /**/
@ -90,7 +90,9 @@ typedef struct {
AtlasRegion* regions; AtlasRegion* regions;
} Atlas; } 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); Atlas* Atlas_readAtlasFile (const char* path);
void Atlas_dispose (Atlas* atlas); void Atlas_dispose (Atlas* atlas);

View File

@ -98,7 +98,7 @@ extern "C" {
RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region); 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); char* _Util_readFile (const char* path, int* length);

View File

@ -33,7 +33,7 @@ namespace spine {
void _AtlasPage_init (AtlasPage* self, const char* name) { void _AtlasPage_init (AtlasPage* self, const char* name) {
CONST_CAST(_AtlasPageVtable*, self->vtable) = NEW(_AtlasPageVtable); 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) { 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", static const char* textureFilterNames[] = {"Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest",
"MipMapNearestLinear", "MipMapLinearLinear"}; "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; const char* end = begin + length;
int dirLength = strlen(dir);
int needsSlash = dirLength > 0 && dir[dirLength - 1] != '/' && dir[dirLength - 1] != '\\';
Atlas* self = NEW(Atlas); Atlas* self = NEW(Atlas);
@ -187,13 +189,22 @@ Atlas* Atlas_readAtlas (const char* begin, unsigned long length) {
if (str.end - str.begin == 0) { if (str.end - str.begin == 0) {
page = 0; page = 0;
} else if (!page) { } 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) if (lastPage)
lastPage->next = page; lastPage->next = page;
else else
self->pages = page; self->pages = page;
lastPage = page; lastPage = page;
FREE(name);
FREE(path);
if (!readValue(end, &str)) return abortAtlas(self); if (!readValue(end, &str)) return abortAtlas(self);
page->format = (AtlasFormat)indexOf(formatNames, 7, &str); 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_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; int length;
const char* data = _Util_readFile(path, &length); const char* data = _Util_readFile(path, &length);
if (!data) return 0; if (data) atlas = Atlas_readAtlas(data, length, dir);
Atlas* atlas = Atlas_readAtlas(data, length);
FREE(data); FREE(data);
FREE(dir);
return atlas; return atlas;
} }

View File

@ -36,12 +36,12 @@ void _Cocos2dAtlasPage_dispose (AtlasPage* page) {
FREE(page); FREE(page);
} }
AtlasPage* AtlasPage_create (const char* name) { AtlasPage* AtlasPage_create (const char* name, const char* path) {
Cocos2dAtlasPage* self = NEW(Cocos2dAtlasPage); Cocos2dAtlasPage* self = NEW(Cocos2dAtlasPage);
_AtlasPage_init(SUPER(self), name); _AtlasPage_init(SUPER(self), name);
VTABLE(AtlasPage, self) ->dispose = _Cocos2dAtlasPage_dispose; VTABLE(AtlasPage, self) ->dispose = _Cocos2dAtlasPage_dispose;
self->texture = [[CCTextureCache sharedTextureCache] addImage:@(name)]; self->texture = [[CCTextureCache sharedTextureCache] addImage:@(path)];
[self->texture retain]; [self->texture retain];
self->atlas = [[CCTextureAtlas alloc] initWithTexture:self->texture capacity:4]; self->atlas = [[CCTextureAtlas alloc] initWithTexture:self->texture capacity:4];
[self->atlas retain]; [self->atlas retain];

View File

@ -39,12 +39,12 @@ void _Cocos2dxAtlasPage_dispose (AtlasPage* page) {
FREE(page); FREE(page);
} }
AtlasPage* AtlasPage_create (const char* name) { AtlasPage* AtlasPage_create (const char* name, const char* path) {
Cocos2dxAtlasPage* self = NEW(Cocos2dxAtlasPage); Cocos2dxAtlasPage* self = NEW(Cocos2dxAtlasPage);
_AtlasPage_init(SUPER(self), name); _AtlasPage_init(SUPER(self), name);
VTABLE(AtlasPage, self) ->dispose = _Cocos2dxAtlasPage_dispose; VTABLE(AtlasPage, self) ->dispose = _Cocos2dxAtlasPage_dispose;
self->texture = CCTextureCache::sharedTextureCache()->addImage(name); self->texture = CCTextureCache::sharedTextureCache()->addImage(path);
self->texture->retain(); self->texture->retain();
self->atlas = CCTextureAtlas::createWithTexture(self->texture, 4); self->atlas = CCTextureAtlas::createWithTexture(self->texture, 4);
self->atlas->retain(); self->atlas->retain();

View File

@ -1,5 +1,5 @@
../data/spineboy.png spineboy.png
format: RGBA8888 format: RGBA8888
filter: Nearest,Nearest filter: Nearest,Nearest
repeat: none repeat: none

View File

@ -50,13 +50,13 @@ void _SfmlAtlasPage_dispose (AtlasPage* page) {
FREE(page); FREE(page);
} }
AtlasPage* AtlasPage_create (const char* name) { AtlasPage* AtlasPage_create (const char* name, const char* path) {
SfmlAtlasPage* self = NEW(SfmlAtlasPage); SfmlAtlasPage* self = NEW(SfmlAtlasPage);
_AtlasPage_init(SUPER(self), name); _AtlasPage_init(SUPER(self), name);
VTABLE(AtlasPage, self) ->dispose = _SfmlAtlasPage_dispose; VTABLE(AtlasPage, self) ->dispose = _SfmlAtlasPage_dispose;
self->texture = new Texture(); self->texture = new Texture();
self->texture->loadFromFile(name); self->texture->loadFromFile(path);
return SUPER(self); return SUPER(self);
} }