2002-10-22 14:53:18 +00:00
|
|
|
/*
|
|
|
|
idstuff.c
|
2001-02-24 06:58:54 +00:00
|
|
|
|
2002-10-22 14:53:18 +00:00
|
|
|
qcc compatable output stuff
|
2001-02-24 06:58:54 +00:00
|
|
|
|
2002-10-22 14:53:18 +00:00
|
|
|
Copyright (C) 2002 Bill Currie <bill@taniwha.org>
|
|
|
|
Copyright (C) 1996-1997 Id Software, Inc.
|
2001-02-24 06:58:54 +00:00
|
|
|
|
2002-10-22 14:53:18 +00:00
|
|
|
Author: Bill Currie <bill@taniwha.org>
|
|
|
|
Date: 2002/06/04
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
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:
|
|
|
|
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
59 Temple Place - Suite 330
|
|
|
|
Boston, MA 02111-1307, USA
|
2001-02-24 06:58:54 +00:00
|
|
|
|
|
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
2003-01-15 15:31:36 +00:00
|
|
|
|
2002-06-01 04:41:25 +00:00
|
|
|
#ifdef HAVE_STRING_H
|
|
|
|
# include <string.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_STRINGS_H
|
|
|
|
# include <strings.h>
|
|
|
|
#endif
|
2001-02-24 06:58:54 +00:00
|
|
|
|
2002-06-04 04:36:57 +00:00
|
|
|
#include <QF/crc.h>
|
|
|
|
#include <QF/dstring.h>
|
2012-05-02 14:39:49 +00:00
|
|
|
#include <QF/quakeio.h>
|
2001-06-04 02:41:45 +00:00
|
|
|
|
2020-06-21 14:15:17 +00:00
|
|
|
#include "tools/qfcc/include/def.h"
|
|
|
|
#include "tools/qfcc/include/defspace.h"
|
|
|
|
#include "tools/qfcc/include/diagnostic.h"
|
|
|
|
#include "tools/qfcc/include/qfcc.h"
|
|
|
|
#include "tools/qfcc/include/expr.h"
|
|
|
|
#include "tools/qfcc/include/idstuff.h"
|
|
|
|
#include "tools/qfcc/include/options.h"
|
|
|
|
#include "tools/qfcc/include/strpool.h"
|
|
|
|
#include "tools/qfcc/include/symtab.h"
|
|
|
|
#include "tools/qfcc/include/type.h"
|
2002-06-04 18:44:03 +00:00
|
|
|
|
|
|
|
#define MAX_SOUNDS 1024
|
|
|
|
#define MAX_MODELS 1024
|
|
|
|
#define MAX_FILES 1024
|
|
|
|
#define MAX_DATA_PATH 64
|
2001-02-24 06:58:54 +00:00
|
|
|
|
2002-06-04 04:36:57 +00:00
|
|
|
static char precache_sounds[MAX_SOUNDS][MAX_DATA_PATH];
|
|
|
|
static int precache_sounds_block[MAX_SOUNDS];
|
|
|
|
static int numsounds;
|
|
|
|
|
|
|
|
static char precache_models[MAX_MODELS][MAX_DATA_PATH];
|
|
|
|
static int precache_models_block[MAX_SOUNDS];
|
|
|
|
static int nummodels;
|
|
|
|
|
|
|
|
static char precache_files[MAX_FILES][MAX_DATA_PATH];
|
|
|
|
static int precache_files_block[MAX_SOUNDS];
|
|
|
|
static int numfiles;
|
|
|
|
|
2001-02-24 06:58:54 +00:00
|
|
|
void
|
2011-01-19 13:19:26 +00:00
|
|
|
PrecacheSound (const char *n, int ch)
|
2001-02-24 06:58:54 +00:00
|
|
|
{
|
2001-12-06 19:49:40 +00:00
|
|
|
int i;
|
2001-02-24 06:58:54 +00:00
|
|
|
|
|
|
|
for (i = 0; i < numsounds; i++) {
|
|
|
|
if (!strcmp (n, precache_sounds[i])) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-01 04:41:25 +00:00
|
|
|
if (numsounds == MAX_SOUNDS) {
|
|
|
|
error (0, "PrecacheSound: numsounds == MAX_SOUNDS");
|
|
|
|
return;
|
|
|
|
}
|
2001-02-24 06:58:54 +00:00
|
|
|
|
|
|
|
strcpy (precache_sounds[i], n);
|
|
|
|
if (ch >= '1' && ch <= '9')
|
|
|
|
precache_sounds_block[i] = ch - '0';
|
|
|
|
else
|
|
|
|
precache_sounds_block[i] = 1;
|
|
|
|
|
|
|
|
numsounds++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2011-01-19 13:19:26 +00:00
|
|
|
PrecacheModel (const char *n, int ch)
|
2001-02-24 06:58:54 +00:00
|
|
|
{
|
2001-12-06 19:49:40 +00:00
|
|
|
int i;
|
2001-02-24 06:58:54 +00:00
|
|
|
|
|
|
|
for (i = 0; i < nummodels; i++) {
|
|
|
|
if (!strcmp (n, precache_models[i])) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-01 04:41:25 +00:00
|
|
|
if (nummodels == MAX_MODELS) {
|
|
|
|
error (0, "PrecacheModels: nummodels == MAX_MODELS");
|
|
|
|
return;
|
|
|
|
}
|
2001-02-24 06:58:54 +00:00
|
|
|
|
|
|
|
strcpy (precache_models[i], n);
|
|
|
|
if (ch >= '1' && ch <= '9')
|
|
|
|
precache_models_block[i] = ch - '0';
|
|
|
|
else
|
|
|
|
precache_models_block[i] = 1;
|
|
|
|
|
|
|
|
nummodels++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2011-01-19 13:19:26 +00:00
|
|
|
PrecacheFile (const char *n, int ch)
|
2001-02-24 06:58:54 +00:00
|
|
|
{
|
2001-12-06 19:49:40 +00:00
|
|
|
int i;
|
2001-02-24 06:58:54 +00:00
|
|
|
|
|
|
|
for (i = 0; i < numfiles; i++) {
|
|
|
|
if (!strcmp (n, precache_files[i])) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-01 04:41:25 +00:00
|
|
|
if (numfiles == MAX_FILES) {
|
|
|
|
error (0, "PrecacheFile: numfiles == MAX_FILES");
|
|
|
|
return;
|
|
|
|
}
|
2001-02-24 06:58:54 +00:00
|
|
|
|
|
|
|
strcpy (precache_files[i], n);
|
|
|
|
if (ch >= '1' && ch <= '9')
|
|
|
|
precache_files_block[i] = ch - '0';
|
|
|
|
else
|
|
|
|
precache_files_block[i] = 1;
|
|
|
|
|
|
|
|
numfiles++;
|
|
|
|
}
|
2002-06-04 04:36:57 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
WriteFiles
|
|
|
|
|
|
|
|
Generates files.dat, which contains all of the data files actually used by
|
|
|
|
the game, to be processed by qfiles
|
|
|
|
*/
|
2002-06-25 21:36:10 +00:00
|
|
|
int
|
2002-06-04 04:36:57 +00:00
|
|
|
WriteFiles (const char *sourcedir)
|
|
|
|
{
|
|
|
|
FILE *f;
|
|
|
|
int i;
|
|
|
|
dstring_t *filename = dstring_newstr ();
|
|
|
|
|
|
|
|
dsprintf (filename, "%s%cfiles.dat", sourcedir, PATH_SEPARATOR);
|
2007-04-07 10:24:34 +00:00
|
|
|
f = fopen (filename->str, "wb");
|
2002-06-25 21:36:10 +00:00
|
|
|
if (!f) {
|
|
|
|
fprintf (stderr, "Couldn't open %s", filename->str);
|
|
|
|
return 1;
|
|
|
|
}
|
2002-06-04 04:36:57 +00:00
|
|
|
|
|
|
|
fprintf (f, "%i\n", numsounds);
|
|
|
|
for (i = 0; i < numsounds; i++)
|
|
|
|
fprintf (f, "%i %s\n", precache_sounds_block[i], precache_sounds[i]);
|
|
|
|
|
|
|
|
fprintf (f, "%i\n", nummodels);
|
|
|
|
for (i = 0; i < nummodels; i++)
|
|
|
|
fprintf (f, "%i %s\n", precache_models_block[i], precache_models[i]);
|
|
|
|
|
|
|
|
fprintf (f, "%i\n", numfiles);
|
|
|
|
for (i = 0; i < numfiles; i++)
|
|
|
|
fprintf (f, "%i %s\n", precache_files_block[i], precache_files[i]);
|
|
|
|
|
|
|
|
fclose (f);
|
|
|
|
dstring_delete (filename);
|
2002-06-25 21:36:10 +00:00
|
|
|
return 0;
|
2002-06-04 04:36:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2002-06-09 04:30:02 +00:00
|
|
|
WriteProgdefs
|
2002-06-04 04:36:57 +00:00
|
|
|
|
|
|
|
Writes the global and entity structures out.
|
|
|
|
Returns a crc of the header, to be stored in the progs file for comparison
|
|
|
|
at load time.
|
|
|
|
*/
|
|
|
|
int
|
2011-03-02 11:51:00 +00:00
|
|
|
WriteProgdefs (dprograms_t *progs, const char *filename)
|
2002-06-04 04:36:57 +00:00
|
|
|
{
|
2012-05-02 13:44:45 +00:00
|
|
|
ddef_t *def;
|
|
|
|
ddef_t *fdef;
|
2012-05-02 14:39:49 +00:00
|
|
|
dstring_t *dstr;
|
|
|
|
QFile *f;
|
2002-06-04 04:36:57 +00:00
|
|
|
unsigned short crc;
|
2012-05-02 13:44:45 +00:00
|
|
|
unsigned i, j;
|
2011-03-02 11:51:00 +00:00
|
|
|
const char *strings;
|
|
|
|
const char *name;
|
2002-06-04 04:36:57 +00:00
|
|
|
|
|
|
|
if (options.verbosity >= 1)
|
2012-05-02 14:39:49 +00:00
|
|
|
printf ("Calculating CRC\n");
|
|
|
|
|
|
|
|
dstr = dstring_newstr();
|
2002-06-04 04:36:57 +00:00
|
|
|
|
|
|
|
// print global vars until the first field is defined
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "\n/* file generated by qcc, do not modify */"
|
|
|
|
"\n\ntypedef struct\n{\tint\tpad[%i];\n",
|
2002-06-04 04:36:57 +00:00
|
|
|
RESERVED_OFS);
|
2011-02-24 05:08:42 +00:00
|
|
|
|
2011-03-02 11:51:00 +00:00
|
|
|
strings = (char *) progs + progs->ofs_strings;
|
|
|
|
for (i = 0; i < progs->numglobaldefs; i++) {
|
2012-05-02 13:44:45 +00:00
|
|
|
def = (ddef_t *) ((char *) progs + progs->ofs_globaldefs) + i;
|
2021-12-31 06:02:31 +00:00
|
|
|
name = strings + def->name;
|
2011-03-02 11:51:00 +00:00
|
|
|
if (!strcmp (name, "end_sys_globals"))
|
2002-06-04 04:36:57 +00:00
|
|
|
break;
|
2012-05-02 13:44:45 +00:00
|
|
|
if (!def->ofs)
|
2002-09-13 15:42:07 +00:00
|
|
|
continue;
|
2011-03-02 11:51:00 +00:00
|
|
|
if (*name == '.' || !*name)
|
2003-04-22 15:29:32 +00:00
|
|
|
continue;
|
2002-06-04 04:36:57 +00:00
|
|
|
|
2012-05-02 13:44:45 +00:00
|
|
|
switch (def->type & ~DEF_SAVEGLOBAL) {
|
2002-06-04 04:36:57 +00:00
|
|
|
case ev_float:
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "\tfloat\t%s;\n", name);
|
2002-06-04 04:36:57 +00:00
|
|
|
break;
|
|
|
|
case ev_vector:
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "\tvec3_t\t%s;\n", name);
|
2002-06-04 04:36:57 +00:00
|
|
|
break;
|
2004-04-08 03:32:14 +00:00
|
|
|
case ev_quat:
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "\tquat_t\t%s;\n", name);
|
2004-04-08 03:32:14 +00:00
|
|
|
break;
|
2002-06-04 04:36:57 +00:00
|
|
|
case ev_string:
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "\tstring_t\t%s;\n", name);
|
2002-06-04 04:36:57 +00:00
|
|
|
break;
|
|
|
|
case ev_func:
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "\tfunc_t\t%s;\n", name);
|
2002-06-04 04:36:57 +00:00
|
|
|
break;
|
|
|
|
case ev_entity:
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "\tint\t%s;\n", name);
|
2002-06-04 04:36:57 +00:00
|
|
|
break;
|
|
|
|
default:
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "\tint\t%s;\n", name);
|
2002-06-04 04:36:57 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "} globalvars_t;\n\n");
|
2002-06-04 04:36:57 +00:00
|
|
|
|
|
|
|
// print all fields
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "typedef struct\n{\n");
|
2012-05-02 13:44:45 +00:00
|
|
|
for (i = 0, j = 0; i < progs->numglobaldefs; i++) {
|
|
|
|
def = (ddef_t *) ((char *) progs + progs->ofs_globaldefs) + i;
|
2021-12-31 06:02:31 +00:00
|
|
|
name = strings + def->name;
|
2011-03-02 11:51:00 +00:00
|
|
|
if (!strcmp (name, "end_sys_fields"))
|
2002-06-04 04:36:57 +00:00
|
|
|
break;
|
|
|
|
|
2012-05-02 13:44:45 +00:00
|
|
|
if (!def->ofs)
|
|
|
|
continue;
|
|
|
|
if (def->type != ev_field)
|
2002-06-04 04:36:57 +00:00
|
|
|
continue;
|
2013-01-17 07:10:17 +00:00
|
|
|
if (!strcmp (name, ".imm"))
|
|
|
|
continue;
|
2002-06-04 04:36:57 +00:00
|
|
|
|
2012-05-02 13:44:45 +00:00
|
|
|
fdef = (ddef_t *) ((char *) progs + progs->ofs_fielddefs) + j++;
|
2021-12-31 06:02:31 +00:00
|
|
|
if (fdef->name != def->name)
|
2012-05-02 13:44:45 +00:00
|
|
|
internal_error (0, "def and field order messup");
|
|
|
|
|
|
|
|
switch (fdef->type) {
|
2002-06-04 04:36:57 +00:00
|
|
|
case ev_float:
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "\tfloat\t%s;\n", name);
|
2002-06-04 04:36:57 +00:00
|
|
|
break;
|
|
|
|
case ev_vector:
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "\tvec3_t\t%s;\n", name);
|
2002-06-04 04:36:57 +00:00
|
|
|
break;
|
|
|
|
case ev_string:
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "\tstring_t\t%s;\n", name);
|
2002-06-04 04:36:57 +00:00
|
|
|
break;
|
|
|
|
case ev_func:
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "\tfunc_t\t%s;\n", name);
|
2002-06-04 04:36:57 +00:00
|
|
|
break;
|
|
|
|
case ev_entity:
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "\tint\t%s;\n", name);
|
2002-06-04 04:36:57 +00:00
|
|
|
break;
|
|
|
|
default:
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "\tint\t%s;\n", name);
|
2002-06-04 04:36:57 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "} entvars_t;\n\n");
|
2011-02-24 05:08:42 +00:00
|
|
|
|
2012-05-02 14:39:49 +00:00
|
|
|
// do a crc of the structs
|
|
|
|
crc = CRC_Block ((byte *) dstr->str, dstr->size - 1);
|
2002-06-04 04:36:57 +00:00
|
|
|
|
2012-05-02 14:39:49 +00:00
|
|
|
dasprintf (dstr, "#define PROGHEADER_CRC %u\n", crc);
|
2020-03-01 08:28:33 +00:00
|
|
|
dstring_insertstr (dstr, 0, "/* Actually, generated by qfcc, but one must "
|
2012-05-02 14:39:49 +00:00
|
|
|
"maintain formalities */");
|
2002-06-04 04:36:57 +00:00
|
|
|
|
2012-05-02 14:39:49 +00:00
|
|
|
if (filename) {
|
|
|
|
if (options.verbosity >= 1)
|
|
|
|
printf ("writing %s\n", filename);
|
|
|
|
f = Qopen (filename, "wt");
|
|
|
|
Qwrite (f, dstr->str, dstr->size - 1);
|
|
|
|
Qclose (f);
|
|
|
|
}
|
2002-06-04 04:36:57 +00:00
|
|
|
|
|
|
|
return crc;
|
|
|
|
}
|