mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
[c] 4.0 porting, atlas parsing.
This commit is contained in:
parent
9795ef1a1d
commit
5d50d8f28e
@ -76,6 +76,7 @@ struct spAtlasPage {
|
|||||||
|
|
||||||
void* rendererObject;
|
void* rendererObject;
|
||||||
int width, height;
|
int width, height;
|
||||||
|
int /*boolean*/ pma;
|
||||||
|
|
||||||
spAtlasPage* next;
|
spAtlasPage* next;
|
||||||
};
|
};
|
||||||
@ -84,7 +85,6 @@ SP_API spAtlasPage* spAtlasPage_create (spAtlas* atlas, const char* name);
|
|||||||
SP_API void spAtlasPage_dispose (spAtlasPage* self);
|
SP_API void spAtlasPage_dispose (spAtlasPage* self);
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
typedef struct spAtlasRegion spAtlasRegion;
|
typedef struct spAtlasRegion spAtlasRegion;
|
||||||
struct spAtlasRegion {
|
struct spAtlasRegion {
|
||||||
const char* name;
|
const char* name;
|
||||||
@ -93,11 +93,12 @@ struct spAtlasRegion {
|
|||||||
int offsetX, offsetY;
|
int offsetX, offsetY;
|
||||||
int originalWidth, originalHeight;
|
int originalWidth, originalHeight;
|
||||||
int index;
|
int index;
|
||||||
int/*bool*/rotate;
|
|
||||||
int degrees;
|
int degrees;
|
||||||
int/*bool*/flip;
|
|
||||||
int* splits;
|
int* splits;
|
||||||
int* pads;
|
int* pads;
|
||||||
|
char** names;
|
||||||
|
float* values;
|
||||||
|
int numValues;
|
||||||
|
|
||||||
spAtlasPage* page;
|
spAtlasPage* page;
|
||||||
|
|
||||||
|
|||||||
@ -51,107 +51,136 @@ spAtlasRegion* spAtlasRegion_create() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void spAtlasRegion_dispose(spAtlasRegion* self) {
|
void spAtlasRegion_dispose(spAtlasRegion* self) {
|
||||||
|
int i, n;
|
||||||
FREE(self->name);
|
FREE(self->name);
|
||||||
FREE(self->splits);
|
FREE(self->splits);
|
||||||
FREE(self->pads);
|
FREE(self->pads);
|
||||||
|
for (i = 0, n = self->numValues; i < n; i++) {
|
||||||
|
FREE(self->names[i]);
|
||||||
|
}
|
||||||
|
FREE(self->names);
|
||||||
|
FREE(self->values);
|
||||||
FREE(self);
|
FREE(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct SimpleString {
|
||||||
const char* begin;
|
char *start;
|
||||||
const char* end;
|
char* end;
|
||||||
} Str;
|
int length;
|
||||||
|
} SimpleString;
|
||||||
|
|
||||||
static void trim(Str* str) {
|
static SimpleString *ss_trim(SimpleString *self) {
|
||||||
while (isspace((unsigned char)*str->begin) && str->begin < str->end)
|
while (isspace((unsigned char) *self->start) && self->start < self->end)
|
||||||
(str->begin)++;
|
self->start++;
|
||||||
if (str->begin == str->end) return;
|
if (self->start == self->end) return self;
|
||||||
str->end--;
|
self->end--;
|
||||||
while (((unsigned char)*str->end == '\r') && str->end >= str->begin)
|
while (((unsigned char)*self->end == '\r') && self->end >= self->start)
|
||||||
str->end--;
|
self->end--;
|
||||||
str->end++;
|
self->end++;
|
||||||
|
self->length = self->end - self->start;
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tokenize string without modification. Returns 0 on failure. */
|
static int ss_indexOf(SimpleString *self, char needle) {
|
||||||
static int readLine(const char** begin, const char* end, Str* str) {
|
char *c = self->start;
|
||||||
if (*begin == end) return 0;
|
while (c < self->end) {
|
||||||
str->begin = *begin;
|
if (*c == needle) return c - self->start;
|
||||||
|
c++;
|
||||||
/* Find next delimiter. */
|
}
|
||||||
while (*begin != end && **begin != '\n')
|
return -1;
|
||||||
(*begin)++;
|
|
||||||
|
|
||||||
str->end = *begin;
|
|
||||||
trim(str);
|
|
||||||
|
|
||||||
if (*begin != end) (*begin)++;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Moves str->begin past the first occurence of c. Returns 0 on failure. */
|
static int ss_indexOf2(SimpleString *self, char needle, int at) {
|
||||||
static int beginPast(Str* str, char c) {
|
char *c = self->start + at;
|
||||||
const char* begin = str->begin;
|
while (c < self->end) {
|
||||||
while (1) {
|
if (*c == needle) return c - self->start;
|
||||||
char lastSkippedChar = *begin;
|
c++;
|
||||||
if (begin == str->end) return 0;
|
}
|
||||||
begin++;
|
return -1;
|
||||||
if (lastSkippedChar == c) break;
|
|
||||||
}
|
|
||||||
str->begin = begin;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns 0 on failure. */
|
static SimpleString ss_substr(SimpleString *self, int s, int e) {
|
||||||
static int readValue(const char** begin, const char* end, Str* str) {
|
SimpleString result;
|
||||||
readLine(begin, end, str);
|
e = s + e;
|
||||||
if (!beginPast(str, ':')) return 0;
|
result.start = self->start + s;
|
||||||
trim(str);
|
result.end = self->start + e;
|
||||||
return 1;
|
result.length = e - s;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns the number of tuple values read (1, 2, 4, or 0 for failure). */
|
static SimpleString ss_substr2(SimpleString *self, int s) {
|
||||||
static int readTuple(const char** begin, const char* end, Str tuple[]) {
|
SimpleString result;
|
||||||
int i;
|
result.start = self->start + s;
|
||||||
Str str = { NULL, NULL };
|
result.end = self->end;
|
||||||
readLine(begin, end, &str);
|
result.length = result.end - result.start;
|
||||||
if (!beginPast(&str, ':')) return 0;
|
return result;
|
||||||
|
}
|
||||||
for (i = 0; i < 3; ++i) {
|
static int /*boolean*/ ss_equals(SimpleString *self, const char *str) {
|
||||||
tuple[i].begin = str.begin;
|
int i;
|
||||||
if (!beginPast(&str, ',')) break;
|
int otherLen = strlen(str);
|
||||||
tuple[i].end = str.begin - 2;
|
if (self->length != otherLen) return 0;
|
||||||
trim(&tuple[i]);
|
for (i = 0; i < self->length; i++) {
|
||||||
}
|
if (self->start[i] != str[i]) return 0;
|
||||||
tuple[i].begin = str.begin;
|
}
|
||||||
tuple[i].end = str.end;
|
return -1;
|
||||||
trim(&tuple[i]);
|
|
||||||
return i + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* mallocString(Str* str) {
|
static char *ss_copy(SimpleString *self) {
|
||||||
int length = (int)(str->end - str->begin);
|
char *string = CALLOC(char, self->length + 1);
|
||||||
char* string = MALLOC(char, length + 1);
|
memcpy(string, self->start, self->length);
|
||||||
memcpy(string, str->begin, length);
|
string[self->length] = '\0';
|
||||||
string[length] = '\0';
|
return string;
|
||||||
return string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int indexOf(const char** array, int count, Str* str) {
|
static int ss_toInt(SimpleString *self) {
|
||||||
int length = (int)(str->end - str->begin);
|
return (int) strtol(self->start, &self->end, 10);
|
||||||
int i;
|
|
||||||
for (i = count - 1; i >= 0; i--)
|
|
||||||
if (strncmp(array[i], str->begin, length) == 0) return i;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int equals(Str* str, const char* other) {
|
typedef struct AtlasInput {
|
||||||
return strncmp(other, str->begin, str->end - str->begin) == 0;
|
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) {
|
static int ai_readEntry(SimpleString entry[5], SimpleString *line) {
|
||||||
return (int)strtol(str->begin, (char**)&str->end, 10);
|
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) {
|
static spAtlas* abortAtlas(spAtlas* self) {
|
||||||
@ -159,9 +188,11 @@ static spAtlas* abortAtlas(spAtlas* self) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* formatNames[] = { "", "Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888", "RGBA8888" };
|
static const char *formatNames[] = {"", "Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888",
|
||||||
static const char* textureFilterNames[] = { "", "Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest",
|
"RGBA8888"};
|
||||||
"MipMapNearestLinear", "MipMapLinearLinear" };
|
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* spAtlas_create(const char* begin, int length, const char* dir, void* rendererObject) {
|
||||||
spAtlas* self;
|
spAtlas* self;
|
||||||
|
|||||||
@ -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));
|
page = new(__FILE__, __LINE__) AtlasPage(String(name, true));
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
line = line = reader.readLine();
|
line = reader.readLine();
|
||||||
if (reader.readEntry(entry, line) == 0) break;
|
if (reader.readEntry(entry, line) == 0) break;
|
||||||
if (entry[0].equals("size")) {
|
if (entry[0].equals("size")) {
|
||||||
page->width = entry[1].toInt();
|
page->width = entry[1].toInt();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user