Эх сурвалжийг харах

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

NathanSweet 12 жил өмнө
parent
commit
a398fe6201

+ 26 - 2
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 <spine/extension.h>
 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);

+ 4 - 2
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);
 

+ 1 - 1
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);
 

+ 29 - 5
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;
 }
 

+ 2 - 2
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];

+ 2 - 2
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();

+ 1 - 1
spine-sfml/data/spineboy.atlas

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

+ 2 - 2
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);
 }