[c] 4.0 porting, atlas parsing.

This commit is contained in:
badlogic 2021-04-08 20:56:58 +02:00
parent 9795ef1a1d
commit 5d50d8f28e
3 changed files with 115 additions and 83 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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();