Subversion Repositories eduke32

Rev

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