Subversion Repositories eduke32

Rev

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

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