Subversion Repositories eduke32

Rev

Rev 1632 | Rev 1643 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
241 terminx 1
#include "compat.h"
2
#include "baselayer.h"
3
 
4
#include "scriptfile.h"
5
#include "cache1d.h"
6
#include "crc32.h"
7
 
8
#include "duke3d.h"
9
#include "grpscan.h"
10
 
335 terminx 11
struct grpfile grpfiles[numgrpfiles] =
559 terminx 12
{
13
    { "Duke Nukem 3D",                                              0xBBC9CE44, 26524524, GAMEDUKE, NULL },
14
    { "Duke Nukem 3D: Atomic Edition",              0xF514A6AC, 44348015, GAMEDUKE, NULL },
15
    { "Duke Nukem 3D: Atomic Edition",              0xFD3DCFF1, 44356548, GAMEDUKE, NULL },
16
    { "Duke Nukem 3D Shareware",                        0x983AD923, 11035779, GAMEDUKE, NULL },
17
    { "Duke Nukem 3D Mac Shareware",            0xC5F71561, 10444391, GAMEDUKE, NULL },
18
    { "NAM",                                            0x75C1F07B, 43448927, GAMENAM,  NULL },
19
    { "Napalm",                                         0x3DE1589A, 44365728, GAMENAM,  NULL },
20
    { "WW2GI",                                          0x907B82BF, 77939508, GAMEWW2,  NULL },
21
};
241 terminx 22
struct grpfile *foundgrps = NULL;
23
 
24
#define GRPCACHEFILE "grpfiles.cache"
335 terminx 25
static struct grpcache
26
{
241 terminx 27
    struct grpcache *next;
1205 terminx 28
    int32_t size;
29
    int32_t mtime;
30
    int32_t crcval;
1457 terminx 31
    char name[BMAX_PATH];
335 terminx 32
}
33
*grpcache = NULL, *usedgrpcache = NULL;
241 terminx 34
 
1205 terminx 35
static int32_t LoadGroupsCache(void)
241 terminx 36
{
37
    struct grpcache *fg;
38
 
1205 terminx 39
    int32_t fsize, fmtime, fcrcval;
241 terminx 40
    char *fname;
41
 
42
    scriptfile *script;
43
 
44
    script = scriptfile_fromfile(GRPCACHEFILE);
45
    if (!script) return -1;
46
 
335 terminx 47
    while (!scriptfile_eof(script))
48
    {
241 terminx 49
        if (scriptfile_getstring(script, &fname)) break;        // filename
50
        if (scriptfile_getnumber(script, &fsize)) break;        // filesize
51
        if (scriptfile_getnumber(script, &fmtime)) break;       // modification time
52
        if (scriptfile_getnumber(script, &fcrcval)) break;      // crc checksum
53
 
808 terminx 54
        fg = Bcalloc(1, sizeof(struct grpcache));
241 terminx 55
        fg->next = grpcache;
56
        grpcache = fg;
57
 
1221 terminx 58
        Bstrncpy(fg->name, fname, BMAX_PATH);
241 terminx 59
        fg->size = fsize;
60
        fg->mtime = fmtime;
61
        fg->crcval = fcrcval;
62
    }
63
 
64
    scriptfile_close(script);
65
    return 0;
66
}
67
 
68
static void FreeGroupsCache(void)
69
{
70
    struct grpcache *fg;
71
 
335 terminx 72
    while (grpcache)
73
    {
241 terminx 74
        fg = grpcache->next;
1527 terminx 75
        Bfree(grpcache);
241 terminx 76
        grpcache = fg;
77
    }
78
}
79
 
1205 terminx 80
int32_t ScanGroups(void)
241 terminx 81
{
82
    CACHE1D_FIND_REC *srch, *sidx;
83
    struct grpcache *fg, *fgg;
84
    struct grpfile *grp;
85
    char *fn;
86
    struct Bstat st;
1430 terminx 87
#define BUFFER_SIZE (1024 * 1024 * 8)
88
    uint8_t *buf = Bmalloc(BUFFER_SIZE);
241 terminx 89
 
1431 terminx 90
    if (!buf)
1430 terminx 91
    {
92
        initprintf("Error allocating %d byte buffer to scan GRPs!\n", BUFFER_SIZE);
93
        return 0;
94
    }
95
 
1642 terminx 96
    initprintf("Scanning for game data...\n");
241 terminx 97
 
98
    LoadGroupsCache();
99
 
100
    srch = klistpath("/", "*.grp", CACHE1D_FIND_FILE);
101
 
335 terminx 102
    for (sidx = srch; sidx; sidx = sidx->next)
103
    {
104
        for (fg = grpcache; fg; fg = fg->next)
105
        {
241 terminx 106
            if (!Bstrcmp(fg->name, sidx->name)) break;
107
        }
108
 
335 terminx 109
        if (fg)
110
        {
241 terminx 111
            if (findfrompath(sidx->name, &fn)) continue;        // failed to resolve the filename
335 terminx 112
            if (Bstat(fn, &st))
113
            {
1527 terminx 114
                Bfree(fn);
335 terminx 115
                continue;
116
            }   // failed to stat the file
1527 terminx 117
            Bfree(fn);
335 terminx 118
            if (fg->size == st.st_size && fg->mtime == st.st_mtime)
119
            {
808 terminx 120
                grp = (struct grpfile *)Bcalloc(1, sizeof(struct grpfile));
1527 terminx 121
                grp->name = Bstrdup(sidx->name);
241 terminx 122
                grp->crcval = fg->crcval;
123
                grp->size = fg->size;
124
                grp->next = foundgrps;
125
                foundgrps = grp;
126
 
808 terminx 127
                fgg = (struct grpcache *)Bcalloc(1, sizeof(struct grpcache));
241 terminx 128
                strcpy(fgg->name, fg->name);
129
                fgg->size = fg->size;
130
                fgg->mtime = fg->mtime;
131
                fgg->crcval = fg->crcval;
132
                fgg->next = usedgrpcache;
133
                usedgrpcache = fgg;
134
                continue;
135
            }
136
        }
137
 
138
        {
1205 terminx 139
            int32_t b, fh;
140
            int32_t crcval;
241 terminx 141
 
142
            fh = openfrompath(sidx->name, BO_RDONLY|BO_BINARY, BS_IREAD);
143
            if (fh < 0) continue;
144
            if (fstat(fh, &st)) continue;
145
 
146
            initprintf(" Checksumming %s...", sidx->name);
1205 terminx 147
            crc32init((uint32_t *)&crcval);
335 terminx 148
            do
149
            {
1430 terminx 150
                b = read(fh, buf, BUFFER_SIZE);
1205 terminx 151
                if (b > 0) crc32block((uint32_t *)&crcval, (uint8_t *)buf, b);
335 terminx 152
            }
1430 terminx 153
            while (b == BUFFER_SIZE);
1205 terminx 154
            crc32finish((uint32_t *)&crcval);
241 terminx 155
            close(fh);
156
            initprintf(" Done\n");
157
 
808 terminx 158
            grp = (struct grpfile *)Bcalloc(1, sizeof(struct grpfile));
1527 terminx 159
            grp->name = Bstrdup(sidx->name);
241 terminx 160
            grp->crcval = crcval;
161
            grp->size = st.st_size;
162
            grp->next = foundgrps;
163
            foundgrps = grp;
164
 
808 terminx 165
            fgg = (struct grpcache *)Bcalloc(1, sizeof(struct grpcache));
1221 terminx 166
            Bstrncpy(fgg->name, sidx->name, BMAX_PATH);
241 terminx 167
            fgg->size = st.st_size;
168
            fgg->mtime = st.st_mtime;
169
            fgg->crcval = crcval;
170
            fgg->next = usedgrpcache;
171
            usedgrpcache = fgg;
172
        }
173
    }
174
 
175
    klistfree(srch);
176
    FreeGroupsCache();
177
 
335 terminx 178
    if (usedgrpcache)
179
    {
1205 terminx 180
        int32_t i = 0;
241 terminx 181
        FILE *fp;
182
        fp = fopen(GRPCACHEFILE, "wt");
335 terminx 183
        if (fp)
184
        {
185
            for (fg = usedgrpcache; fg; fg=fgg)
186
            {
241 terminx 187
                fgg = fg->next;
188
                fprintf(fp, "\"%s\" %d %d %d\n", fg->name, fg->size, fg->mtime, fg->crcval);
1527 terminx 189
                Bfree(fg);
1000 terminx 190
                i++;
241 terminx 191
            }
192
            fclose(fp);
193
        }
1178 terminx 194
//        initprintf("Found %d recognized GRP %s.\n",i,i>1?"files":"file");
1430 terminx 195
        if (buf)
196
            Bfree(buf);
1000 terminx 197
        return 0;
241 terminx 198
    }
1642 terminx 199
 
200
    initprintf("Found no recognized game data!\n");
201
 
1430 terminx 202
    if (buf)
203
        Bfree(buf);
1642 terminx 204
 
241 terminx 205
    return 0;
206
}
207
 
208
void FreeGroups(void)
209
{
210
    struct grpfile *fg;
211
 
335 terminx 212
    while (foundgrps)
213
    {
241 terminx 214
        fg = foundgrps->next;
1527 terminx 215
        Bfree((char*)foundgrps->name);
216
        Bfree(foundgrps);
241 terminx 217
        foundgrps = fg;
218
    }
219
}
220