diff options
Diffstat (limited to 'src/gfile/gfile_fs_rom.c')
-rw-r--r-- | src/gfile/gfile_fs_rom.c | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/src/gfile/gfile_fs_rom.c b/src/gfile/gfile_fs_rom.c new file mode 100644 index 00000000..6b7719c7 --- /dev/null +++ b/src/gfile/gfile_fs_rom.c @@ -0,0 +1,178 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/******************************************************** + * The ROM file-system + ********************************************************/ + +#include "gfx.h" + +#if GFX_USE_GFILE && GFILE_NEED_ROMFS + +#include "gfile_fs.h" + +#include <string.h> + +// What directory file formats do we understand +#define ROMFS_DIR_VER_MAX 0x0000 + +// Compression Formats +#define ROMFS_CMP_UNCOMPRESSED 0 + +typedef struct ROMFS_DIRENTRY { + uint16_t ver; // Directory Entry Version + uint16_t cmp; // Compression format + const struct ROMFS_DIRENTRY * next; // The next entry + const char * name; // The file name + long int size; // The file size + const char * file; // The file data +} ROMFS_DIRENTRY; + +#define ROMFS_DIRENTRY_HEAD 0 +#include "romfs_files.h" +static const ROMFS_DIRENTRY const *FsROMHead = ROMFS_DIRENTRY_HEAD; + +typedef struct ROMFileList { + gfileList fl; + const ROMFS_DIRENTRY *pdir; +} ROMFileList; + + +static bool_t ROMExists(const char *fname); +static long int ROMFilesize(const char *fname); +static bool_t ROMOpen(GFILE *f, const char *fname); +static void ROMClose(GFILE *f); +static int ROMRead(GFILE *f, void *buf, int size); +static bool_t ROMSetpos(GFILE *f, long int pos); +static long int ROMGetsize(GFILE *f); +static bool_t ROMEof(GFILE *f); +#if GFILE_NEED_FILELISTS + static gfileList *ROMFlOpen(const char *path, bool_t dirs); + static const char *ROMFlRead(gfileList *pfl); + static void ROMFlClose(gfileList *pfl); +#endif + +const GFILEVMT FsROMVMT = { + GFSFLG_CASESENSITIVE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags + 'S', // prefix + 0, ROMExists, ROMFilesize, 0, + ROMOpen, ROMClose, ROMRead, 0, + ROMSetpos, ROMGetsize, ROMEof, + 0, 0, 0, + #if GFILE_NEED_FILELISTS + ROMFlOpen, ROMFlRead, ROMFlClose + #endif +}; + +static const ROMFS_DIRENTRY *ROMFindFile(const char *fname) +{ + const ROMFS_DIRENTRY *p; + + for(p = FsROMHead; p; p = p->next) { + if (p->ver <= ROMFS_DIR_VER_MAX && p->cmp == ROMFS_CMP_UNCOMPRESSED && !strcmp(p->name, fname)) + break; + } + return p; +} + +static bool_t ROMExists(const char *fname) +{ + return ROMFindFile(fname) != 0; +} + +static long int ROMFilesize(const char *fname) +{ + const ROMFS_DIRENTRY *p; + + if (!(p = ROMFindFile(fname))) return -1; + return p->size; +} + +static bool_t ROMOpen(GFILE *f, const char *fname) +{ + const ROMFS_DIRENTRY *p; + + if (!(p = ROMFindFile(fname))) return FALSE; + f->obj = (void *)p; + return TRUE; +} + +static void ROMClose(GFILE *f) +{ + (void)f; +} + +static int ROMRead(GFILE *f, void *buf, int size) +{ + const ROMFS_DIRENTRY *p; + + p = (const ROMFS_DIRENTRY *)f->obj; + if (p->size - f->pos < size) + size = p->size - f->pos; + if (size <= 0) return 0; + memcpy(buf, p->file+f->pos, size); + return size; +} + +static bool_t ROMSetpos(GFILE *f, long int pos) +{ + return pos <= ((const ROMFS_DIRENTRY *)f->obj)->size; +} + +static long int ROMGetsize(GFILE *f) +{ + return ((const ROMFS_DIRENTRY *)f->obj)->size; +} + +static bool_t ROMEof(GFILE *f) +{ + return f->pos >= ((const ROMFS_DIRENTRY *)f->obj)->size; +} + +#if GFILE_NEED_FILELISTS + static gfileList *ROMFlOpen(const char *path, bool_t dirs) { + ROMFileList * p; + (void) path; + + // We don't support directories or path searching + if (dirs) + return 0; + + // Allocate the list buffer + if (!(p = gfxAlloc(sizeof(ROMFileList)))) + return 0; + + // Initialize it and return it. + p->pdir = 0; + return &p->fl; + } + + static const char *ROMFlRead(gfileList *pfl) { + #define rfl ((ROMFileList *)pfl) + + // Is it the first entry + if (!rfl->pdir) { + rfl->pdir = FsROMHead; + return FsROMHead->name; + } + + // Is it not the last entry + if (rfl->pdir->next) { + rfl->pdir = rfl->pdir->next; + return rfl->pdir->name; + } + + return 0; + #undef rfl + } + + static void ROMFlClose(gfileList *pfl) { + gfxFree(pfl); + } +#endif + +#endif //GFX_USE_GFILE && GFILE_NEED_ROMFS |