mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-16 01:11:28 +00:00
67ed6945fd
NAM and Napalm can now share their con, def, and rts files if the one for their respective game is not present because the con and rts files are identical. Also, decapitalize two string literals missed in r2540. git-svn-id: https://svn.eduke32.com/eduke32@2726 1a8010ca-5511-0410-912e-c29ae57300e0
243 lines
6.8 KiB
C
243 lines
6.8 KiB
C
//-------------------------------------------------------------------------
|
|
/*
|
|
Copyright (C) 2010 EDuke32 developers and contributors
|
|
|
|
This file is part of EDuke32.
|
|
|
|
EDuke32 is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License version 2
|
|
as published by the Free Software Foundation.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
//-------------------------------------------------------------------------
|
|
|
|
#include "compat.h"
|
|
#include "baselayer.h"
|
|
|
|
#include "scriptfile.h"
|
|
#include "cache1d.h"
|
|
#include "crc32.h"
|
|
|
|
#include "duke3d.h"
|
|
#include "common_game.h"
|
|
#include "grpscan.h"
|
|
|
|
struct grpfile grpfiles[NUMGRPFILES] =
|
|
{
|
|
{ "Duke Nukem 3D", 0xBBC9CE44, 26524524, GAMEFLAG_DUKE, NULL },
|
|
{ "Duke Nukem 3D: Atomic Edition", 0xF514A6AC, 44348015, GAMEFLAG_DUKE, NULL },
|
|
{ "Duke Nukem 3D: Atomic Edition", 0xFD3DCFF1, 44356548, GAMEFLAG_DUKE, NULL },
|
|
{ "Duke Nukem 3D Shareware", 0x983AD923, 11035779, GAMEFLAG_DUKE, NULL },
|
|
{ "Duke Nukem 3D Mac Shareware", 0xC5F71561, 10444391, GAMEFLAG_DUKE, NULL },
|
|
{ "NAM", 0x75C1F07B, 43448927, GAMEFLAG_NAM, NULL },
|
|
{ "Napalm", 0x3DE1589A, 44365728, GAMEFLAG_NAM|GAMEFLAG_NAPALM, NULL },
|
|
{ "WWII GI", 0x907B82BF, 77939508, GAMEFLAG_WW2GI|GAMEFLAG_NAM, NULL },
|
|
};
|
|
struct grpfile *foundgrps = NULL;
|
|
|
|
#define GRPCACHEFILE "grpfiles.cache"
|
|
static struct grpcache
|
|
{
|
|
struct grpcache *next;
|
|
int32_t size;
|
|
int32_t mtime;
|
|
int32_t crcval;
|
|
char name[BMAX_PATH];
|
|
}
|
|
*grpcache = NULL, *usedgrpcache = NULL;
|
|
|
|
static int32_t LoadGroupsCache(void)
|
|
{
|
|
struct grpcache *fg;
|
|
|
|
int32_t fsize, fmtime, fcrcval;
|
|
char *fname;
|
|
|
|
scriptfile *script;
|
|
|
|
script = scriptfile_fromfile(GRPCACHEFILE);
|
|
if (!script) return -1;
|
|
|
|
while (!scriptfile_eof(script))
|
|
{
|
|
if (scriptfile_getstring(script, &fname)) break; // filename
|
|
if (scriptfile_getnumber(script, &fsize)) break; // filesize
|
|
if (scriptfile_getnumber(script, &fmtime)) break; // modification time
|
|
if (scriptfile_getnumber(script, &fcrcval)) break; // crc checksum
|
|
|
|
fg = Bcalloc(1, sizeof(struct grpcache));
|
|
fg->next = grpcache;
|
|
grpcache = fg;
|
|
|
|
Bstrncpy(fg->name, fname, BMAX_PATH);
|
|
fg->size = fsize;
|
|
fg->mtime = fmtime;
|
|
fg->crcval = fcrcval;
|
|
}
|
|
|
|
scriptfile_close(script);
|
|
return 0;
|
|
}
|
|
|
|
static void FreeGroupsCache(void)
|
|
{
|
|
struct grpcache *fg;
|
|
|
|
while (grpcache)
|
|
{
|
|
fg = grpcache->next;
|
|
Bfree(grpcache);
|
|
grpcache = fg;
|
|
}
|
|
}
|
|
|
|
int32_t ScanGroups(void)
|
|
{
|
|
CACHE1D_FIND_REC *srch, *sidx;
|
|
struct grpcache *fg, *fgg;
|
|
struct grpfile *grp;
|
|
char *fn;
|
|
struct Bstat st;
|
|
#define BUFFER_SIZE (1024 * 1024 * 8)
|
|
uint8_t *buf = Bmalloc(BUFFER_SIZE);
|
|
|
|
if (!buf)
|
|
{
|
|
initprintf("Error allocating %d byte buffer to scan GRPs!\n", BUFFER_SIZE);
|
|
return 0;
|
|
}
|
|
|
|
initprintf("Searching for game data...\n");
|
|
|
|
LoadGroupsCache();
|
|
|
|
srch = klistpath("/", "*.grp", CACHE1D_FIND_FILE);
|
|
|
|
for (sidx = srch; sidx; sidx = sidx->next)
|
|
{
|
|
for (fg = grpcache; fg; fg = fg->next)
|
|
{
|
|
if (!Bstrcmp(fg->name, sidx->name)) break;
|
|
}
|
|
|
|
if (fg)
|
|
{
|
|
if (findfrompath(sidx->name, &fn)) continue; // failed to resolve the filename
|
|
if (Bstat(fn, &st))
|
|
{
|
|
Bfree(fn);
|
|
continue;
|
|
} // failed to stat the file
|
|
Bfree(fn);
|
|
if (fg->size == st.st_size && fg->mtime == st.st_mtime)
|
|
{
|
|
grp = (struct grpfile *)Bcalloc(1, sizeof(struct grpfile));
|
|
grp->name = Bstrdup(sidx->name);
|
|
grp->crcval = fg->crcval;
|
|
grp->size = fg->size;
|
|
grp->next = foundgrps;
|
|
foundgrps = grp;
|
|
|
|
fgg = (struct grpcache *)Bcalloc(1, sizeof(struct grpcache));
|
|
strcpy(fgg->name, fg->name);
|
|
fgg->size = fg->size;
|
|
fgg->mtime = fg->mtime;
|
|
fgg->crcval = fg->crcval;
|
|
fgg->next = usedgrpcache;
|
|
usedgrpcache = fgg;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
{
|
|
int32_t b, fh;
|
|
int32_t crcval;
|
|
|
|
fh = openfrompath(sidx->name, BO_RDONLY|BO_BINARY, BS_IREAD);
|
|
if (fh < 0) continue;
|
|
if (fstat(fh, &st)) continue;
|
|
|
|
initprintf(" Checksumming %s...", sidx->name);
|
|
crc32init((uint32_t *)&crcval);
|
|
do
|
|
{
|
|
b = read(fh, buf, BUFFER_SIZE);
|
|
if (b > 0) crc32block((uint32_t *)&crcval, (uint8_t *)buf, b);
|
|
}
|
|
while (b == BUFFER_SIZE);
|
|
crc32finish((uint32_t *)&crcval);
|
|
close(fh);
|
|
initprintf(" Done\n");
|
|
|
|
grp = (struct grpfile *)Bcalloc(1, sizeof(struct grpfile));
|
|
grp->name = Bstrdup(sidx->name);
|
|
grp->crcval = crcval;
|
|
grp->size = st.st_size;
|
|
grp->next = foundgrps;
|
|
foundgrps = grp;
|
|
|
|
fgg = (struct grpcache *)Bcalloc(1, sizeof(struct grpcache));
|
|
Bstrncpy(fgg->name, sidx->name, BMAX_PATH);
|
|
fgg->size = st.st_size;
|
|
fgg->mtime = st.st_mtime;
|
|
fgg->crcval = crcval;
|
|
fgg->next = usedgrpcache;
|
|
usedgrpcache = fgg;
|
|
}
|
|
}
|
|
|
|
klistfree(srch);
|
|
FreeGroupsCache();
|
|
|
|
if (usedgrpcache)
|
|
{
|
|
int32_t i = 0;
|
|
FILE *fp;
|
|
fp = fopen(GRPCACHEFILE, "wt");
|
|
if (fp)
|
|
{
|
|
for (fg = usedgrpcache; fg; fg=fgg)
|
|
{
|
|
fgg = fg->next;
|
|
fprintf(fp, "\"%s\" %d %d %d\n", fg->name, fg->size, fg->mtime, fg->crcval);
|
|
Bfree(fg);
|
|
i++;
|
|
}
|
|
fclose(fp);
|
|
}
|
|
// initprintf("Found %d recognized GRP %s.\n",i,i>1?"files":"file");
|
|
if (buf)
|
|
Bfree(buf);
|
|
return 0;
|
|
}
|
|
|
|
initprintf("Found no recognized game data!\n");
|
|
|
|
if (buf)
|
|
Bfree(buf);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void FreeGroups(void)
|
|
{
|
|
struct grpfile *fg;
|
|
|
|
while (foundgrps)
|
|
{
|
|
fg = foundgrps->next;
|
|
Bfree((char *)foundgrps->name);
|
|
Bfree(foundgrps);
|
|
foundgrps = fg;
|
|
}
|
|
}
|
|
|