void *stringtableOpen(const char *fname) { FILESYSTEM_FILE *fp; int i; STRINGTABLE_FILE_MAIN stfm; STRINGTABLE *st; if ((st = malloc(sizeof(STRINGTABLE))) == NULL) return NULL; if ((fp = fsFileOpen(fname, "rb")) == NULL) { free(st); return NULL; } fsFileRead(&stfm, sizeof(STRINGTABLE_FILE_MAIN), fp); if (ntohl(stfm.magic) != STRINGTABLE_MAGIC) { fsFileClose(fp); free(st); return NULL; } st->sections = ntohl(stfm.sections); st->fp = fp; st->sec_list.name = malloc(sizeof(char *) * st->sections); st->section = malloc(sizeof(STRINGTABLE_SECTION) * st->sections); if (!st->section || !st->sec_list.name) { free(st->section); free(st->sec_list.name); fsFileClose(fp); free(st); return NULL; } st->sec_list.names = st->sections; for (i = 0; i < st->sections; i++) { fsFileRead(&st->section[i].sec, sizeof(STRINGTABLE_FILE_SECTION), fp); st->section[i].sec.zlen = ntohl(st->section[i].sec.zlen); st->section[i].sec.strings = ntohl(st->section[i].sec.strings); st->section[i].sec.len = ntohl(st->section[i].sec.len); st->section[i].sec.stringz = ntohl(st->section[i].sec.stringz); st->section[i].file_pos = fsFileTell(fp); st->section[i].string = NULL; st->section[i].strings = 0; st->section[i].string_data = NULL; st->section[i].name_comp = utilStringSum(st->section[i].sec.name); st->sec_list.name[i] = st->section[i].sec.name; fsFileSeek(fp, st->section[i].sec.zlen + st->section[i].sec.stringz, SEEK_CUR); } return st; }
int stringtableLoadSection(STRINGTABLE *st, const char *section) { STRINGTABLE_FILE_ENTRY *fe; int i, sec; void *data, *zdata, *fez; char *str; if (st == NULL) return -1; if ((sec = stringtableFindSection(st, section)) == -1) return -1; if (st->section[sec].strings != 0) return 0; fsFileSeek(st->fp, st->section[sec].file_pos, SEEK_SET); zdata = malloc(st->section[sec].sec.zlen); data = malloc(st->section[sec].sec.len); fez = malloc(st->section[sec].sec.stringz); fe = malloc(st->section[sec].sec.strings * sizeof(STRINGTABLE_FILE_ENTRY)); st->section[sec].string = malloc(st->section[sec].sec.strings * sizeof(STRINGTABLE_ENTRY)); if (zdata == NULL || data == NULL || fez == NULL || fe == NULL || st->section[sec].string == NULL) { free(st->section[sec].string); free(zdata); free(data); free(fez); free(fe); return -1; } fsFileRead(zdata, st->section[sec].sec.zlen, st->fp); fsFileRead(fez, st->section[sec].sec.stringz, st->fp); stbi_zlib_decode_buffer(data, st->section[sec].sec.len, zdata, st->section[sec].sec.zlen); stbi_zlib_decode_buffer((void *) fe, st->section[sec].sec.strings * sizeof(STRINGTABLE_FILE_ENTRY), fez, st->section[sec].sec.stringz); free(zdata); free(fez); str = data; for (i = 0; i < st->section[sec].sec.strings; i++) { st->section[sec].string[i].name = &str[ntohl(fe[i].pos)]; st->section[sec].string[i].value = &str[ntohl(fe[i].val)]; st->section[sec].string[i].key = utilStringSum(st->section[sec].string[i].name); } st->section[sec].string_data = data; st->section[sec].strings = st->section[sec].sec.strings; free(fe); return 0; }
int fsMount(const char *name) { struct FILESYSTEM_IMAGE *img; FILESYSTEM_IMG_HEADER header; int i = 0; if ((img = malloc(sizeof(struct FILESYSTEM_IMAGE))) == NULL) return -1; if ((img->file = fsFileOpen(name, "rb")) == NULL) { free(img); return -1; } img->offset = 0; read_header: fsFileReadInts((unsigned int *) &header, sizeof(header) >> 2, img->file); if (header.magic != DARNIT_FS_IMG_MAGIC || header.version != DARNIT_FS_IMG_VERSION) { fsFileSeek(img->file, -4, SEEK_END); fsFileReadInts((unsigned int *) &i, 1, img->file); if (i == DARNIT_FS_IMG_MAGIC && !img->offset) { fsFileSeek(img->file, -8, SEEK_END); fsFileReadInts((unsigned int *) &i, 1, img->file); img->offset = fsFileTell(img->file) - i - 4; if (img->offset <= 0) { fsFileClose(img->file); free(img); return -1; } fsFileSeek(img->file, img->offset, SEEK_SET); goto read_header; } fsFileClose(img->file); free(img); return -1; } img->dir_ents = header.files; if ((img->dir = malloc(sizeof(FILESYSTEM_IMAGE_FILE) * img->dir_ents)) == NULL) { fsFileClose(img->file); free(img); return -1; } for (i = 0; i < img->dir_ents; i++) { fsFileRead(img->dir[i].name, 128, img->file); fsFileReadInts(&img->dir[i].pos, 3, img->file); img->dir[i].comp = utilStringSum(img->dir[i].name); img->dir[i].pos += (12 + 140 * img->dir_ents) + img->offset; } img->next = d->fs.mount; d->fs.mount = img; return 0; }
void fsFileSkipWhitespace(FILESYSTEM_FILE *file) { char c; do { fsFileRead(&c, 1, file); if (fsFileEOF(file)) break; } while (c == ' ' || c == '\t'); fsFileSeek(file, -1, SEEK_CUR); return; }
size_t fsFileReadInts(unsigned int *buffer, size_t ints, FILESYSTEM_FILE *file) { int bytes; if (file == NULL) return 0; bytes = fsFileRead(buffer, ints<<2, file); bytes >>= 2; utilBlockToHostEndian(buffer, bytes); return bytes; }
void *textLoadFont(const char *fname, int size, int tex_w, int tex_h) { TEXT_FONT *font; FILESYSTEM_FILE *fp; int flen, asc, desc, linegap; if ((font = malloc(sizeof(TEXT_FONT))) == NULL) { return NULL; } if ((fp = fsFileOpen(fname, "rb")) == NULL) { fprintf(stderr, "Unable to open file %s\n", fname); free(font); return NULL; } fsFileSeek(fp, 0, SEEK_END); flen = fsFileTell(fp); fsFileSeek(fp, 0, SEEK_SET); if ((font->font_data = malloc(flen)) == NULL) { fsFileClose(fp); free(font); return NULL; } fsFileRead(font->font_data, flen, fp); font->font_data_len = flen; fsFileClose(fp); if (stbtt_InitFont(&font->face, font->font_data, 0) == 0) { free(font->font_data); free(font); return NULL; } font->cache = NULL; font->font_height = size; font->tex_w = bitwiseRoundUpToPow2(tex_w); font->tex_h = bitwiseRoundUpToPow2(tex_h); font->scale = stbtt_ScaleForPixelHeight(&font->face, font->font_height); stbtt_GetFontVMetrics(&font->face, &asc, &desc, &linegap); font->line_gap = font->scale * linegap; font->ascent = font->scale * asc; font->descent = font->scale * desc; return font; }
FILESYSTEM_FILE *fsGetRealFile(const char *path_src) { FILESYSTEM_FILE *file, *dest; char *new_file, *real_file, buff[4096]; if (!(file = fsFileOpen(path_src, "rb"))) return NULL; if (file->offset) { /* File is in a container */ #ifndef _WIN32 new_file = tempnam(NULL, d->fs.directory_suffix); real_file = malloc(strlen(new_file) + 1 + 10); sprintf(real_file, "%s.%i", new_file, d->fs.temp_counter); free(new_file); new_file = real_file; #else char path[MAX_PATH]; new_file = malloc(MAX_PATH); GetTempPath(MAX_PATH, path); if (!GetTempFileName(path, d->fs.directory_suffix, 0, new_file)) { fsFileClose(file); free(new_file); return NULL; } #endif /* Here, the new file needs to be created */ if (!(dest = fsFileOpen(new_file, "wb"))) { free(new_file); return NULL; } /* Ugly, I know... */ for (; !fsFileEOF(file); fsFileWrite(buff, fsFileRead(buff, 4096, file), dest)); dest->temporary = 1; fsFileClose(file); fflush(dest->fp); return dest; } else { return file; } return NULL; }
void spriteLoadText(FILESYSTEM_FILE *fp, SPRITE_ENTRY *se) { unsigned int i, j; char c, buf[512]; fsFileSeek(fp, 0, SEEK_SET); fsFileGets(buf, 512, fp); sscanf(buf, "%s %i %i\n", se->tilesheet, &se->wsq, &se->hsq); j = i = 0; while (!fsFileEOF(fp)) { fsFileRead(&c, 1, fp); switch (c) { case 'D': fsFileGets(buf, 512, fp); j = 0; break; case 'T': fsFileGets(buf, 512, fp); sscanf(buf, "%i %i\n", &se->spr[i].tile[j].time, &se->spr[i].tile[j].tile); j++; break; case 'E': se->spr[i].tiles = j; j = 0; i++; break; case '\n': break; default: fsFileGets(buf, 512, fp); break; } } return; }
size_t EXPORT_THIS d_file_read(void *buffer, size_t bytes, FILESYSTEM_FILE *file) { return fsFileRead(buffer, bytes, file); }
int main(int argc, char **argv) { printf("fsPathExists 0 : %s\n", PASSFAIL(fsPathExists("/") == true)); printf("fsPathExists 1 : %s\n", PASSFAIL(fsPathExists("/fakePath") == false)); char *pathTestFile = "fileSystem.test.file"; char *pathTestDir = "fileSystem.test.dir" ; fsFileDelete(pathTestFile, NULL, NULL); //don't care... printf("fsPathExists 2 : %s\n", PASSFAIL(fsPathExists(pathTestFile) == false)); printf("fsPathIsFile 3 : %s\n", PASSFAIL(fsPathIsFile(pathTestFile) == false)); printf("fsFileCreate 4 : %s\n", PASSFAIL(fsFileCreate(pathTestFile, NULL, NULL) == true)); printf("fsPathExists 5 : %s\n", PASSFAIL(fsPathExists(pathTestFile) == true)); printf("fsPathIsFile 6 : %s\n", PASSFAIL(fsPathIsFile(pathTestFile) == true)); printf("fsPathIsDirectory 7 : %s\n", PASSFAIL(fsPathIsDirectory(pathTestFile) == false)); printf("fsFileMove 8 : %s\n", PASSFAIL(fsFileMove(pathTestFile, "fileSystem.file.test", NULL, NULL) == true)); printf("fsPathIsFile 9 : %s\n", PASSFAIL(fsPathIsFile(pathTestFile) == false)); printf("fsPathIsFile 10 : %s\n", PASSFAIL(fsPathIsFile("fileSystem.file.test") == true)); printf("fsFileMove 11 : %s\n", PASSFAIL(fsFileMove("fileSystem.file.test", pathTestFile, NULL, NULL) == true)); printf("fsPathIsFile 12 : %s\n", PASSFAIL(fsPathIsFile(pathTestFile) == true)); printf("fsPathIsFile 13 : %s\n", PASSFAIL(fsPathIsFile("fileSystem.file.test") == false)); fsDirectoryDelete(pathTestDir, NULL, NULL); //don't care printf("fsPathExists 14 : %s\n", PASSFAIL(fsPathExists(pathTestDir) == false)); printf("fsPathIsDirectory 15 : %s\n", PASSFAIL(fsPathIsDirectory(pathTestDir) == false)); printf("fsDirectoryCreate 16 : %s\n", PASSFAIL(fsDirectoryCreate(pathTestDir, NULL, NULL) == true)); printf("fsPathExists 17 : %s\n", PASSFAIL(fsPathExists(pathTestDir) == true)); printf("fsPathIsDirectory 18 : %s\n", PASSFAIL(fsPathIsDirectory(pathTestDir) == true)); printf("fsPathIsFile 19 : %s\n", PASSFAIL(fsPathIsFile(pathTestDir) == false)); printf("fsDirectoryMove 20 : %s\n", PASSFAIL(fsDirectoryMove(pathTestDir, "fileSystem.dir.test", NULL, NULL) == true)); printf("fsPathIsDirectory 21 : %s\n", PASSFAIL(fsPathIsDirectory(pathTestDir) == false)); printf("fsPathIsDirectory 22 : %s\n", PASSFAIL(fsPathIsDirectory("fileSystem.dir.test") == true)); printf("fsDirectoryMove 23 : %s\n", PASSFAIL(fsDirectoryMove("fileSystem.dir.test", pathTestDir, NULL, NULL) == true)); printf("fsPathIsDirectory 24 : %s\n", PASSFAIL(fsPathIsDirectory(pathTestDir) == true)); printf("fsPathIsDirectory 25 : %s\n", PASSFAIL(fsPathIsDirectory("fileSystem.dir.test") == false)); char *cwd = fsPathCurrent(), *home = fsPathHome(); printf("fsPathCurrent 26 : %s\n", cwd); printf("fsPathHome 27 : %s\n", home); char *base = fsPathBase(cwd), *parent = fsPathParent(cwd); printf("fsPathBase 28 : %s\n", base); printf("fsPathParent 29 : %s\n", parent); char *normal; normal = fsPathNormalize("test/bin"); printf("fsPathNormalize 30 : %s\n", normal); free(normal); normal = fsPathNormalize("./test/bin"); printf("fsPathNormalize 31 : %s\n", normal); free(normal); normal = fsPathNormalize("~/test/bin"); printf("fsPathNormalize 32 : %s\n", normal); free(normal); normal = fsPathNormalize("~"); printf("fsPathNormalize 33 : %s\n", PASSFAIL(strcmp(normal, home) == 0)); free(normal); normal = fsPathNormalize("/"); printf("fsPathNormalize 34 : %s\n", PASSFAIL(strcmp(normal, "/" ) == 0)); free(normal); normal = fsPathNormalize("/test1/test1/test1/.././../test2/./test3"); printf("fsPathNormalize 35 : %s\n", PASSFAIL(strcmp(normal, "/test1/test2/test3") == 0)); free(normal); free(cwd); free(home); free(base); free(parent); char *rwTestData = "Hello\nfileSystem\r\nWord!"; u32 rwTestLength = strlen(rwTestData); printf("fsFileSize 36 : %s\n", PASSFAIL(fsFileSize(pathTestFile) == 0)); printf("fsFileWrite 37 : %s\n", PASSFAIL(fsFileWrite(pathTestFile, rwTestData, rwTestLength, NULL, NULL) == true)); printf("fsFileSize 38 : %s\n", PASSFAIL(fsFileSize(pathTestFile) == rwTestLength)); char *rwTestBuff = fsFileRead(pathTestFile, NULL, NULL); printf("fsFileRead 39 : %s\n", PASSFAIL(strncmp(rwTestData, rwTestBuff, rwTestLength) == 0)); free(rwTestBuff); printf("fsFileDelete 40 : %s\n", PASSFAIL(fsFileDelete(pathTestFile, NULL, NULL) == true)); printf("fsDirectoryCreate 41 : %s\n", PASSFAIL(fsDirectoryCreate("fileSystem.test.dir/subA/subB", NULL, NULL) == true)); printf("fsFileCreate 42 : %s\n", PASSFAIL(fsFileCreate("fileSystem.test.dir/file0", NULL, NULL) == true)); printf("fsFileCreate 43 : %s\n", PASSFAIL(fsFileCreate("fileSystem.test.dir/file1", NULL, NULL) == true)); list *dirStuff = fsDirectoryList(pathTestDir, FS_DIRLIST_DIRSFIRST, NULL); listItem *dirEntry = dirStuff->origin; for(u32 i=0; i<dirStuff->count; i++) { fsDirectoryItem *fsdi = (fsDirectoryItem *)dirEntry->data; printf("fsDirectoryList %02d : (%c) %s\n", 44+i, (fsdi->isDirectory ? 'd' : 'f'), fsdi->name); dirEntry = dirEntry->next; } listFree(&dirStuff); printf("fsDirectoryDelete xx : %s\n", PASSFAIL(fsDirectoryDelete(pathTestDir, NULL, NULL) == true)); return 0; }
LDMZ_MAP *mapLoadReal(const char *fname, int tile_w, int tile_h) { LDMZ_MAP *map; LDMZ_FILE_MAP map_h; LDMZ_FILE_STRTABLE_REF *map_r; LDMZ_FILE_LAYER *map_l; LDMZ_FILE_OBJECT *object; FILESYSTEM_FILE *file; void *buff, *tmp; char *stringdata; int i, iso, tile_h_inc; map_h.magic = map_h.version = 0; if ((file = fsFileOpen(fname, "rb")) == NULL) return NULL; fsFileReadInts((unsigned int *) &map_h, sizeof(LDMZ_FILE_MAP) >> 2, file); if (map_h.magic != LDMZ_MAGIC) { fsFileClose(file); return NULL; } if (map_h.version != LDMZ_VERSION && map_h.version != LDMZ_VERSION_ISOM) { fsFileClose(file); return NULL; } if ((buff = malloc(map_h.strtable_zlen)) == NULL) { fsFileClose(file); return NULL; } iso = (map_h.version == LDMZ_VERSION) ? 0 : 1; stringdata = malloc(map_h.strtable_len); map = malloc(sizeof(LDMZ_MAP)); map->stringrefs = malloc(sizeof(LDMZ_REF) * (map_h.strtable_refs_len / sizeof(LDMZ_FILE_STRTABLE_REF))); map_r = malloc(map_h.strtable_refs_len); map_l = malloc(sizeof(LDMZ_FILE_LAYER) * map_h.layers); object = malloc(map_h.objects * sizeof(LDMZ_OBJECT)); map->object = malloc(sizeof(LDMZ_OBJECT) * (map_h.objects)); map->layer = malloc(sizeof(LDMZ_LAYER) * map_h.layers); map->isometric = !(map_h.version == LDMZ_VERSION); map->stringdata = stringdata; map->cam_x = map->cam_y = 0; map->layers = map_h.layers; map->objects = map_h.objects; if (!map || (!stringdata && map_h.strtable_len > 0) || (!map->stringrefs && map_h.strtable_refs_len > 0) || (!map->object && map_h.objects) || (!map->layer && map_h.layers) || (!map_r && map_h.strtable_refs_len) || (!object && map_h.objects) || (!map_l)) goto error; /* Down at the bottom of the function */ /**** STRINGS ****/ fsFileRead(buff, map_h.strtable_zlen, file); stbi_zlib_decode_buffer(stringdata, map_h.strtable_len, buff, map_h.strtable_zlen); /**** REFS ****/ if ((tmp = realloc(buff, map_h.strtable_refs_zlen)) == NULL) goto error; /* Down at the bottom of the function */ buff = tmp; fsFileRead(buff, map_h.strtable_refs_zlen, file); stbi_zlib_decode_buffer((void *) map_r, map_h.strtable_refs_len, buff, map_h.strtable_refs_zlen); utilBlockToHostEndian((unsigned int *) map_r, map_h.strtable_refs_len / 4); for (i = 0; i < (map_h.strtable_refs_len / sizeof(LDMZ_FILE_STRTABLE_REF)); i++) { if (map_r[i].key != -1) { map->stringrefs[i].key = &stringdata[map_r[i].key]; map->stringrefs[i].value = &stringdata[map_r[i].value]; } else { map->stringrefs[i].key = NULL; map->stringrefs[i].value = NULL; } } free(map_r); map_r = NULL; map->prop = &map->stringrefs[map_h.main_ref]; /**** OBJECTS ****/ if ((tmp = realloc(buff, map_h.object_zlen)) == NULL && map_h.objects > 0) { goto error; /* Down at the bottom of the function */ } buff = tmp; fsFileRead(buff, map_h.object_zlen, file); stbi_zlib_decode_buffer((void *) object, sizeof(LDMZ_OBJECT) * map_h.objects, buff, map_h.object_zlen); utilBlockToHostEndian((unsigned int *) object, (sizeof(LDMZ_OBJECT) * map_h.objects) >> 2); for (i = 0; i < map_h.objects; i++) { map->object[i].ref = &map->stringrefs[object[i].ref]; map->object[i].x = object[i].x; map->object[i].y = object[i].y; map->object[i].l = object[i].l; } free(object); object = NULL; /**** MAP LAYER ****/ if ((tmp = realloc(buff, map_h.layer_zlen)) == NULL) goto error; /* Down at the bottom of the function */ buff = tmp; fsFileRead(buff, map_h.layer_zlen, file); stbi_zlib_decode_buffer((void *)map_l, sizeof(LDMZ_FILE_LAYER) * map_h.layers, buff, map_h.layer_zlen); utilBlockToHostEndian((unsigned int *) map_l, (sizeof(LDMZ_FILE_LAYER) * map_h.layers) >> 2); for (i = 0; i < map_h.layers; i++) { map->layer[i].tilemap = NULL; map->layer[i].ts = NULL; } for (i = 0; i < map_h.layers; i++) { map->layer[i].tile_w = (tile_w > 0) ? tile_w : map_l[i].tile_w; map->layer[i].tile_h = (tile_h > 0) ? tile_h : map_l[i].tile_h; if (iso && tile_h > 0) { tile_h_inc = (tile_h << 16) / (map_l[i].tile_h); map_l[i].layer_offset_x *= tile_h_inc; map_l[i].layer_offset_x >>= 16; } map_l[i].tile_w = 0; map_l[i].tile_h = 0; map->layer[i].offset_x = map_l[i].layer_offset_x; map->layer[i].offset_y = map_l[i].layer_offset_y; map->layer[i].ref = &map->stringrefs[map_l[i].prop_ref]; if ((tmp = realloc(buff, map_l[i].layer_zlen)) == NULL) goto error; /* Down at the bottom of the function */ buff = tmp; if (strcmp(mapLayerPropGet(map, i, "tileset"), "NO SUCH KEY") == 0) { if (strcmp(mapPropGet(map, "tileset"), "NO SUCH KEY") == 0) goto error; /* Down at the bottom of the function */ else { if (iso) { if ((map->layer[i].ts = renderTilesheetLoadIsometric(mapPropGet(map, "tileset"), map->layer[i].tile_w, map->layer[i].tile_h, PFORMAT_RGB5A1)) == NULL) goto error; /* Down at the bottom of the function */ } else { if ((map->layer[i].ts = renderTilesheetLoad(mapPropGet(map, "tileset"), map->layer[i].tile_w, map->layer[i].tile_h, PFORMAT_RGB5A1)) == NULL) goto error; /* Down at the bottom of the function */ } } if (strcmp(mapPropGet(map, "animation"), "NO SUCH KEY")) renderTilesheetAnimationApply(map->layer[i].ts, mapPropGet(map, "animation")); } else { if (iso) { if ((map->layer[i].ts = renderTilesheetLoadIsometric(mapPropGet(map, "tileset"), map->layer[i].tile_w, map->layer[i].tile_h, PFORMAT_RGB5A1)) == NULL) goto error; /* Down at the bottom of the function */ } else { if ((map->layer[i].ts = renderTilesheetLoad(mapPropGet(map, "tileset"), map->layer[i].tile_w, map->layer[i].tile_h, PFORMAT_RGB5A1)) == NULL) goto error; /* Down at the bottom of the function */ } if (strcmp(mapLayerPropGet(map, i, "animation"), "NO SUCH KEY")) renderTilesheetAnimationApply(map->layer[i].ts, mapLayerPropGet(map, i, "animation")); } if (iso) { if ((map->layer[i].tilemap = tilemapNew(TILEMAP_DEFAULT_INV_DIV, map->layer[i].ts, TILEMAP_DEFAULT_INV_DIV, map_l[i].layer_w, map_l[i].layer_h, map_l[i].layer_offset_x)) == NULL) goto error; /* Down at the bottom of the function */ } else { if ((map->layer[i].tilemap = tilemapNew(TILEMAP_DEFAULT_INV_DIV, map->layer[i].ts, TILEMAP_DEFAULT_INV_DIV, map_l[i].layer_w, map_l[i].layer_h, 0)) == NULL) goto error; /* Down at the bottom of the function */ } if (!iso) renderTilemapCameraMove(map->layer[i].tilemap->render, map->cam_x + map->layer[i].offset_x, map->cam_y + map->layer[i].offset_y); else renderTilemapCameraMove(map->layer[i].tilemap->render, 0, 0); fsFileRead(buff, map_l[i].layer_zlen, file); stbi_zlib_decode_buffer((void *) map->layer[i].tilemap->data, map_l[i].layer_w * map_l[i].layer_h * 4, buff, map_l[i].layer_zlen); utilBlockToHostEndian(map->layer[i].tilemap->data, map_l[i].layer_w * map_l[i].layer_h); renderTilemapForceRecalc(map->layer[i].tilemap->render); }
int renderTilesheetAnimationApply(TILESHEET *ts, const char *fname) { unsigned int i, j, k, tiles, frames, pos, a, b, cc, d, e; unsigned int *newdata; char c, buf[512]; FILESYSTEM_FILE *fp; IMGLOAD_DATA img; TS_FRAME *frame; if (ts == NULL) return -1; if (ts->animation.tiles > 0) return -1; if ((fp = fsFileOpen(fname, "rb")) == NULL) return -1; fsFileGetLine(buf, 512, fp); pos = fsFileTell(fp); img = imgloadLoad(buf); if (img.img_data == NULL) { fsFileClose(fp); return -1; } if (img.w != ts->wsq) { if (!(newdata = malloc(sizeof(unsigned int) * ts->wsq * ts->hsq * (img.w / ts->wsq * img.h / ts->hsq)))) { fsFileClose(fp); free(img.img_data); return -1; } a = img.w / ts->wsq; b = img.h / ts->hsq; cc = ts->wsq * ts->hsq; for (i = 0; i < a; i++) { for (j = 0; j < b; j++) for (k = 0; k < cc; k++) { /* Skip all the lines before us */ d = (a * j * cc) + (k / ts->wsq * img.w); /* Skip all the cols before us */ e = i * ts->wsq + k % ts->wsq; newdata[(j*a + i) * cc + k] = img.img_data[d + e]; } } free(img.img_data); img.img_data = newdata; img.w = ts->wsq; img.h = ts->hsq * a * b; } ts->animation.animation_tiles = img.h / ts->hsq; tiles = frames = 0; while (!fsFileEOF(fp)) { fsFileRead(&c, 1, fp); switch (c) { case 'T': fsFileGets(buf, 512, fp); break; case 'F': fsFileGets(buf, 512, fp); frames++; break; case 'E': fsFileGets(buf, 512, fp); tiles++; break; case '\n': break; default: fsFileGets(buf, 512, fp); break; } } i = j = 0; fsFileSeek(fp, pos, SEEK_SET); frame = malloc(sizeof(TS_FRAME) * frames); ts->animation.tile = malloc(sizeof(TS_TILE) * tiles); if (frame == NULL || ts->animation.tile == NULL) { fsFileClose(fp); free(img.img_data); free(frame); free(ts->animation.tile); ts->animation.tile = NULL; return -1; } ts->animation.tiles = tiles; ts->animation.tile_skip = ts->wsq * ts->hsq; ts->animation.data = img.img_data; ts->animation.frame_data = frame; frames = 0; while (!fsFileEOF(fp)) { fsFileRead(&c, 1, fp); switch (c) { case 'T': fsFileGets(buf, 512, fp); ts->animation.tile[i].frame = &frame[frames]; ts->animation.tile[i].frame_at = 0; ts->animation.tile[i].time_rest = 0; j = 0; break; case 'F': fsFileGets(buf, 512, fp); sscanf(buf, "%i %i %i\n", &ts->animation.tile[i].frame[j].tile_src, &ts->animation.tile[i].frame[j].tile_dst, &ts->animation.tile[i].frame[j].time); j++; break; case 'E': fsFileGets(buf, 512, fp); ts->animation.tile[i].frames = j; j = 0; i++; break; case '\n': break; default: fsFileGets(buf, 512, fp); break; } } ts->animation.tiles = i; fsFileClose(fp); return 0; }