1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
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.io/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 gBool ROMExists(const char *fname);
static long int ROMFilesize(const char *fname);
static gBool ROMOpen(GFILE *f, const char *fname);
static void ROMClose(GFILE *f);
static int ROMRead(GFILE *f, void *buf, int size);
static gBool ROMSetpos(GFILE *f, long int pos);
static long int ROMGetsize(GFILE *f);
static gBool ROMEof(GFILE *f);
#if GFILE_NEED_FILELISTS
static gfileList *ROMFlOpen(const char *path, gBool 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 gBool 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 gBool ROMOpen(GFILE *f, const char *fname)
{
const ROMFS_DIRENTRY *p;
if (!(p = ROMFindFile(fname))) return gFalse;
f->obj = (void *)p;
return gTrue;
}
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 gBool 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 gBool ROMEof(GFILE *f)
{
return f->pos >= ((const ROMFS_DIRENTRY *)f->obj)->size;
}
#if GFILE_NEED_FILELISTS
static gfileList *ROMFlOpen(const char *path, gBool 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
|