Subversion Repositories eduke32

Rev

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