Subversion Repositories eduke32

Rev

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