From 5d50d8f28e32856ad16c237e55f2ac764bc6b3d8 Mon Sep 17 00:00:00 2001 From: badlogic Date: Thu, 8 Apr 2021 20:56:58 +0200 Subject: [PATCH] [c] 4.0 porting, atlas parsing. --- spine-c/spine-c/include/spine/Atlas.h | 7 +- spine-c/spine-c/src/spine/Atlas.c | 189 ++++++++++++++---------- spine-cpp/spine-cpp/src/spine/Atlas.cpp | 2 +- 3 files changed, 115 insertions(+), 83 deletions(-) diff --git a/spine-c/spine-c/include/spine/Atlas.h b/spine-c/spine-c/include/spine/Atlas.h index 36dbafc8b..d950a9c64 100644 --- a/spine-c/spine-c/include/spine/Atlas.h +++ b/spine-c/spine-c/include/spine/Atlas.h @@ -76,6 +76,7 @@ struct spAtlasPage { void* rendererObject; int width, height; + int /*boolean*/ pma; spAtlasPage* next; }; @@ -84,7 +85,6 @@ SP_API spAtlasPage* spAtlasPage_create (spAtlas* atlas, const char* name); SP_API void spAtlasPage_dispose (spAtlasPage* self); /**/ - typedef struct spAtlasRegion spAtlasRegion; struct spAtlasRegion { const char* name; @@ -93,11 +93,12 @@ struct spAtlasRegion { int offsetX, offsetY; int originalWidth, originalHeight; int index; - int/*bool*/rotate; int degrees; - int/*bool*/flip; int* splits; int* pads; + char** names; + float* values; + int numValues; spAtlasPage* page; diff --git a/spine-c/spine-c/src/spine/Atlas.c b/spine-c/spine-c/src/spine/Atlas.c index 1a196bf10..b73c1f59e 100644 --- a/spine-c/spine-c/src/spine/Atlas.c +++ b/spine-c/spine-c/src/spine/Atlas.c @@ -51,107 +51,136 @@ spAtlasRegion* spAtlasRegion_create() { } void spAtlasRegion_dispose(spAtlasRegion* self) { + int i, n; FREE(self->name); FREE(self->splits); FREE(self->pads); + for (i = 0, n = self->numValues; i < n; i++) { + FREE(self->names[i]); + } + FREE(self->names); + FREE(self->values); FREE(self); } /**/ -typedef struct { - const char* begin; - const char* end; -} Str; +typedef struct SimpleString { + char *start; + char* end; + int length; +} SimpleString; -static void trim(Str* str) { - while (isspace((unsigned char)*str->begin) && str->begin < str->end) - (str->begin)++; - if (str->begin == str->end) return; - str->end--; - while (((unsigned char)*str->end == '\r') && str->end >= str->begin) - str->end--; - str->end++; +static SimpleString *ss_trim(SimpleString *self) { + while (isspace((unsigned char) *self->start) && self->start < self->end) + self->start++; + if (self->start == self->end) return self; + self->end--; + while (((unsigned char)*self->end == '\r') && self->end >= self->start) + self->end--; + self->end++; + self->length = self->end - self->start; + return self; } -/* Tokenize string without modification. Returns 0 on failure. */ -static int 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; +static int ss_indexOf(SimpleString *self, char needle) { + char *c = self->start; + while (c < self->end) { + if (*c == needle) return c - self->start; + c++; + } + return -1; } -/* Moves str->begin past the first occurence of c. Returns 0 on failure. */ -static int 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; +static int ss_indexOf2(SimpleString *self, char needle, int at) { + char *c = self->start + at; + while (c < self->end) { + if (*c == needle) return c - self->start; + c++; + } + return -1; } -/* Returns 0 on failure. */ -static int readValue(const char** begin, const char* end, Str* str) { - readLine(begin, end, str); - if (!beginPast(str, ':')) return 0; - trim(str); - return 1; +static SimpleString ss_substr(SimpleString *self, int s, int e) { + SimpleString result; + e = s + e; + result.start = self->start + s; + result.end = self->start + e; + result.length = e - s; + return result; } -/* 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[]) { - 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; +static SimpleString ss_substr2(SimpleString *self, int s) { + SimpleString result; + result.start = self->start + s; + result.end = self->end; + result.length = result.end - result.start; + return result; +} +static int /*boolean*/ ss_equals(SimpleString *self, const char *str) { + int i; + int otherLen = strlen(str); + if (self->length != otherLen) return 0; + for (i = 0; i < self->length; i++) { + if (self->start[i] != str[i]) return 0; + } + return -1; } -static char* 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; +static char *ss_copy(SimpleString *self) { + char *string = CALLOC(char, self->length + 1); + memcpy(string, self->start, self->length); + string[self->length] = '\0'; + return string; } -static int 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; +static int ss_toInt(SimpleString *self) { + return (int) strtol(self->start, &self->end, 10); } -static int equals(Str* str, const char* other) { - return strncmp(other, str->begin, str->end - str->begin) == 0; +typedef struct AtlasInput { + const char *start; + const char *end; + char *index; + int length; + SimpleString line; +} AtlasInput; + +static SimpleString *ai_readLine(AtlasInput *self) { + if (self->index >= self->end) return 0; + self->line.start = self->index; + while (self->index < self->end && *self->index != '\n') + self->index++; + self->line.end = self->index; + if (self->index != self->end) self->index++; + self->line = *ss_trim(&self->line); + self->line.length = self->end - self->start; + return &self->line; } -static int toInt(Str* str) { - return (int)strtol(str->begin, (char**)&str->end, 10); +static int ai_readEntry(SimpleString entry[5], SimpleString *line) { + int colon, i, lastMatch; + SimpleString substr; + if (line == NULL) return 0; + ss_trim(line); + if (line->length == 0) return 0; + + colon = ss_indexOf(line, ':'); + if (colon == -1) return 0; + substr = ss_substr(line, 0, colon); + entry[0] = *ss_trim(&substr); + for (i = 1, lastMatch = colon + 1;; i++) { + int comma = ss_indexOf2(line, ',', lastMatch); + if (comma == -1) { + substr = ss_substr2(line, lastMatch); + entry[i] = *ss_trim(&substr); + return i; + } + substr = ss_substr(line, lastMatch, comma - lastMatch); + entry[i] = *ss_trim(&substr); + lastMatch = comma + 1; + if (i == 4) return 4; + } } static spAtlas* abortAtlas(spAtlas* self) { @@ -159,9 +188,11 @@ static spAtlas* abortAtlas(spAtlas* self) { return 0; } -static const char* formatNames[] = { "", "Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888", "RGBA8888" }; -static const char* textureFilterNames[] = { "", "Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest", -"MipMapNearestLinear", "MipMapLinearLinear" }; +static const char *formatNames[] = {"", "Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888", + "RGBA8888"}; +static const char *textureFilterNames[] = {"", "Nearest", "Linear", "MipMap", "MipMapNearestNearest", + "MipMapLinearNearest", + "MipMapNearestLinear", "MipMapLinearLinear"}; spAtlas* spAtlas_create(const char* begin, int length, const char* dir, void* rendererObject) { spAtlas* self; diff --git a/spine-cpp/spine-cpp/src/spine/Atlas.cpp b/spine-cpp/spine-cpp/src/spine/Atlas.cpp index 5b39ec491..1f2a1ec96 100644 --- a/spine-cpp/spine-cpp/src/spine/Atlas.cpp +++ b/spine-cpp/spine-cpp/src/spine/Atlas.cpp @@ -260,7 +260,7 @@ void Atlas::load(const char *begin, int length, const char *dir, bool createText page = new(__FILE__, __LINE__) AtlasPage(String(name, true)); while (true) { - line = line = reader.readLine(); + line = reader.readLine(); if (reader.readEntry(entry, line) == 0) break; if (entry[0].equals("size")) { page->width = entry[1].toInt();