start of my properties work. doesn't seem to have broken anything :)

This commit is contained in:
Bill Currie 2004-01-27 08:31:34 +00:00
parent 2ea155dc53
commit 9abe3b29e0
9 changed files with 330 additions and 114 deletions

View file

@ -1,3 +1,3 @@
AUTOMAKE_OPTIONS= foreign
EXTRA_DIST= entities.h light.h options.h threads.h
EXTRA_DIST= entities.h light.h noise.h options.h properties.h threads.h

View file

@ -63,7 +63,7 @@ typedef struct entity_s {
vec_t lightradius;
vec_t subbrightness;
vec_t lightoffset;
vec3_t color;
vec3_t color, color2;
vec3_t spotdir;
vec_t spotcone;
unsigned short visbyte, visbit; // which byte and bit to look at in

View file

@ -44,6 +44,7 @@ typedef struct {
vec_t noise;
vec_t cutoff;
const char *lightsfilename;
const char *properties_filename;
} options_t;
extern options_t options;

View file

@ -0,0 +1,9 @@
float parse_float (const char *str);
void parse_color (const char *str, vec3_t color);
float parse_light (const char *str, vec3_t color);
int parse_attenuation (const char *arg);
int parse_noise (const char *arg);
struct plitem_s;
void set_properties (entity_t *ent, struct plitem_s *dict);
void LoadProperties (const char *filename);

View file

@ -17,7 +17,10 @@ endif
bin_PROGRAMS= $(qflight)
EXTRA_PROGRAMS= qflight
qflight_SOURCES= entities.c ltface.c noise.c options.c qflight.c threads.c trace.c vis.c
qflight_SOURCES=\
entities.c ltface.c noise.c options.c properties.c qflight.c \
threads.c trace.c vis.c
qflight_LDFLAGS= $(PTHREAD_LDFLAGS)
qflight_LDADD= $(QFLIGHT_LIBS)

View file

@ -51,6 +51,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/dstring.h"
#include "QF/idparse.h"
#include "QF/mathlib.h"
#include "QF/qfplist.h"
#include "QF/qtypes.h"
#include "QF/quakefs.h"
#include "QF/sys.h"
@ -59,6 +60,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "threads.h"
#include "entities.h"
#include "options.h"
#include "properties.h"
entity_t *entities;
int num_entities;
@ -168,12 +170,11 @@ LoadEntities (void)
const char *data;
const char *key;
double vec[4];
double temp, color2[3];
entity_t *entity;
epair_t *epair;
int i;
float cutoff_range;
float intensity;
plitem_t *dict;
data = bsp->entdata;
@ -200,12 +201,14 @@ LoadEntities (void)
memset (entity, 0, sizeof (*entity));
entity->color[0] = entity->color[1] = entity->color[2] = 1.0f;
color2[0] = color2[1] = color2[2] = 1.0f;
VectorCopy (entity->color, entity->color2);
entity->falloff = DEFAULTFALLOFF * DEFAULTFALLOFF;
entity->lightradius = 0;
entity->lightoffset = LIGHTDISTBIAS;
entity->attenuation = options.attenuation;
dict = PL_NewDictionary ();
// go through all the keys in this entity
while (1) {
int c;
@ -232,6 +235,9 @@ LoadEntities (void)
epair->next = entity->epairs;
entity->epairs = epair;
PL_D_AddObject (dict, PL_NewString (key),
PL_NewString (com_token));
if (!strcmp (key, "classname"))
entity->classname = epair->value;
else if (!strcmp (key, "target"))
@ -244,93 +250,9 @@ LoadEntities (void)
if (sscanf (com_token, "%lf %lf %lf",
&vec[0], &vec[1], &vec[2]) != 3)
fprintf (stderr, "LoadEntities: not 3 values for origin");
VectorCopy (vec, entity->origin);
} else if (!strncmp (key, "light", 5) || !strcmp (key, "_light")) {
i = sscanf (com_token, "%lf %lf %lf %lf",
&vec[0], &vec[1], &vec[2], &vec[3]);
switch (i) {
case 4: // HalfLife light
entity->light = vec[3];
entity->color[0] = vec[0] * (1.0f / 255.0f);
entity->color[1] = vec[1] * (1.0f / 255.0f);
entity->color[2] = vec[2] * (1.0f / 255.0f);
break;
case 3:
entity->light = 1;
entity->color[0] = vec[0];
entity->color[1] = vec[1];
entity->color[2] = vec[2];
break;
case 1:
entity->light = vec[0];
entity->color[0] = 1.0f;
entity->color[1] = 1.0f;
entity->color[2] = 1.0f;
break;
default:
Sys_Error ("LoadEntities: _light (or light) key must "
"be 1 (Quake), 4 (HalfLife), or 3 (HLight) "
"values, \"%s\" is not valid\n", com_token);
}
} else if (!strcmp (key, "wait")) {
entity->falloff = atof (com_token);
entity->falloff *= entity->falloff; // presquared
} else if (!strcmp (key, "_lightradius")) {
entity->lightradius = atof (com_token);
} else if (!strcmp (key, "style")) {
entity->style = atof (com_token);
if ((unsigned) entity->style > 254)
fprintf (stderr, "Bad light style %i (must be 0-254)",
entity->style);
} else if (!strcmp (key, "angle")) {
entity->angle = atof(com_token);
} else if (!strcmp (key, "color") || !strcmp (key, "_color")) {
if (sscanf (com_token, "%lf %lf %lf",
&vec[0], &vec[1], &vec[2]) != 3)
Sys_Error ("LoadEntities: not 3 values for color");
// scale the color to have at least one component at 1.0
temp = vec[0];
if (vec[1] > temp)
temp = vec[1];
if (vec[2] > temp)
temp = vec[2];
if (temp != 0.0)
temp = 1.0 / temp;
VectorScale (vec, temp, color2);
else
VectorCopy (vec, entity->origin);
}
// Open Quartz - new keys
else if (!strcmp(key, "_attenuation")) {
if (!strcmp(com_token, "linear"))
entity->attenuation = LIGHT_LINEAR;
else if (!strcmp(com_token, "radius"))
entity->attenuation = LIGHT_RADIUS;
else if (!strcmp(com_token, "inverse"))
entity->attenuation = LIGHT_INVERSE;
else if (!strcmp(com_token, "realistic"))
entity->attenuation = LIGHT_REALISTIC;
else if (!strcmp(com_token, "none"))
entity->attenuation = LIGHT_NO_ATTEN;
else if (!strcmp(com_token, "havoc"))
entity->attenuation = LIGHT_LH;
else
entity->attenuation = atoi (com_token);
} else if (!strcmp(key, "_radius"))
entity->radius = atof (com_token);
else if (!strcmp(key, "_noise"))
entity->noise = atof (com_token);
else if (!strcmp(key, "_noisetype")) {
if (!strcmp(com_token, "random"))
entity->noisetype = NOISE_RANDOM;
else if (!strcmp(com_token, "smooth"))
entity->noisetype = NOISE_SMOOTH;
else if (!strcmp(com_token, "perlin"))
entity->noisetype = NOISE_PERLIN;
else
entity->noisetype = atoi (com_token);
} else if (!strcmp(key, "_persistence"))
entity->persistence = atof (com_token);
else if (!strcmp(key, "_resolution"))
entity->resolution = atof (com_token);
}
if (entity->targetname)
@ -338,6 +260,7 @@ LoadEntities (void)
// all fields have been parsed
if (entity->classname && !strncmp (entity->classname, "light", 5)) {
set_properties (entity, dict);
if (!entity->light)
entity->light = DEFAULTLIGHTLEVEL;
if (!entity->noise)
@ -345,16 +268,17 @@ LoadEntities (void)
if (!entity->persistence)
entity->persistence = 1;
}
PL_Free (dict);
if (entity->light) {
// convert to subtraction to the brightness for the whole light,
// so it will fade nicely, rather than being clipped off
VectorScale (color2,
VectorScale (entity->color2,
entity->light * 16384.0 * options.globallightscale,
color2);
entity->color[0] *= color2[0];
entity->color[1] *= color2[1];
entity->color[2] *= color2[2];
entity->color2);
entity->color[0] *= entity->color2[0];
entity->color[1] *= entity->color2[1];
entity->color[2] *= entity->color2[2];
if (entity->lightradius)
entity->subbrightness = 1.0 / (entity->lightradius

View file

@ -47,6 +47,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "entities.h"
#include "options.h"
#include "properties.h"
const char *this_program;
@ -56,6 +57,7 @@ static struct option const long_options[] = {
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
{"threads", required_argument, 0, 't'},
{"properties", required_argument, 0, 'P'},
{"attenuation", required_argument, 0, 'a'},
{"noise", required_argument, 0, 'n'},
{"cutoff", required_argument, 0, 'c'},
@ -80,6 +82,7 @@ static const char *short_options =
"e:" // extra sampling
"d:" // scale distance
"r:" // scale range
"P:" // properties file
"f:"
;
@ -103,6 +106,7 @@ usage (int status)
" havoc\n"
" -n, --noise [factor] Scale noise. 0 (default) to disable\n"
" -c, --cutoff [scale] Scale cutoff. 0 to disable\n"
" -P, --properties [file] Properties file\n"
" -f, --file [bspfile] BSP file\n\n");
exit (status);
}
@ -148,23 +152,8 @@ DecodeArgs (int argc, char **argv)
usage (1);
break;
case 'a':
if (!strcmp(optarg, "linear"))
options.attenuation = LIGHT_LINEAR;
else if (!strcmp(optarg, "radius"))
options.attenuation = LIGHT_RADIUS;
else if (!strcmp(optarg, "inverse"))
options.attenuation = LIGHT_INVERSE;
else if (!strcmp(optarg, "realistic"))
options.attenuation = LIGHT_REALISTIC;
else if (!strcmp(optarg, "none"))
options.attenuation = LIGHT_NO_ATTEN;
else if (!strcmp(optarg, "havoc"))
options.attenuation = LIGHT_LH;
else {
options.attenuation = strtol (optarg, &eptr, 10);
if (eptr == optarg || *eptr)
usage (1);
}
if ((options.attenuation = parse_attenuation (optarg)) == -1)
usage (1);
break;
case 'n': // noise
options.noise = strtod (optarg, &eptr);
@ -197,6 +186,9 @@ DecodeArgs (int argc, char **argv)
case 'f':
bspfile = strdup (optarg);
break;
case 'P':
options.properties_filename = strdup (optarg);
break;
default:
usage (1);
}

View file

@ -0,0 +1,283 @@
/*
#FILENAME#
#DESCRIPTION#
Copyright (C) 2004 #AUTHOR#
Author: #AUTHOR#
Date: #DATE#
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
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
#ifdef HAVE_STRING_H
# include "string.h"
#endif
#ifdef HAVE_STRINGS_H
# include "strings.h"
#endif
#include <stdlib.h>
#include <errno.h>
#include "QF/mathlib.h"
#include "QF/qfplist.h"
#include "QF/quakeio.h"
#include "compat.h"
#include "entities.h"
#include "options.h"
#include "properties.h"
static plitem_t *properties;
float
parse_float (const char *str)
{
char *eptr;
double val = strtod (str, &eptr);
return val;
}
void
parse_color (const char *str, vec3_t color)
{
double vec[3];
vec_t temp;
if (sscanf (str, "%lf %lf %lf", &vec[0], &vec[1], &vec[2]) != 3) {
fprintf (stderr, "not 3 values for color");
color[0] = color[1] = color[2] = 1.0;
return;
}
// scale the color to have at least one component at 1.0 (or -1.0)
temp = max (fabs (vec[0]), max (fabs (vec[1]), fabs (vec[2])));
if (temp != 0.0)
temp = 1.0 / temp;
VectorScale (vec, temp, color);
}
float
parse_light (const char *str, vec3_t color)
{
int i;
double vec[4];
i = sscanf (str, "%lf %lf %lf %lf", &vec[0], &vec[1], &vec[2], &vec[3]);
switch (i) {
case 4: // HalfLife light
VectorScale (vec + 1, 1.0 / 255, color);
return vec[3];
break;
case 3:
VectorCopy (vec, color);
return 1.0;
break;
case 1:
color[0] = 1.0;
color[1] = 1.0;
color[2] = 1.0;
return vec[0];
break;
default:
fprintf (stderr, "_light (or light) key must "
"be 1 (Quake), 4 (HalfLife), or 3 (HLight) "
"values, \"%s\" is not valid\n", str);
color[0] = 1.0;
color[1] = 1.0;
color[2] = 1.0;
return DEFAULTLIGHTLEVEL;
}
}
int
parse_attenuation (const char *arg)
{
if (!strcmp(arg, "linear"))
return LIGHT_LINEAR;
else if (!strcmp(arg, "radius"))
return LIGHT_RADIUS;
else if (!strcmp(arg, "inverse"))
return LIGHT_INVERSE;
else if (!strcmp(arg, "realistic"))
return LIGHT_REALISTIC;
else if (!strcmp(arg, "none"))
return LIGHT_NO_ATTEN;
else if (!strcmp(arg, "havoc"))
return LIGHT_LH;
else {
char *eptr;
int val = strtol (arg, &eptr, 10);
if (eptr == arg || *eptr)
return -1;
return val;
}
}
int
parse_noise (const char *arg)
{
if (!strcmp(arg, "random"))
return NOISE_RANDOM;
else if (!strcmp(arg, "smooth"))
return NOISE_SMOOTH;
else if (!strcmp(arg, "perlin"))
return NOISE_PERLIN;
else {
char *eptr;
int val = strtol (arg, &eptr, 10);
if (eptr == arg || *eptr)
return -1;
return val;
}
}
static inline const char *
plstring (plitem_t *pl)
{
if (pl->type == QFString)
return pl->data;
return 0;
}
static plitem_t *
get_item (const char *key, plitem_t *d1, plitem_t *d2)
{
plitem_t *p;
if ((p = PL_ObjectForKey (d1, key)))
return p;
if (d2)
return PL_ObjectForKey (d2, key);
return 0;
}
void
set_properties (entity_t *ent, plitem_t *dict)
{
plitem_t *prop = 0;
plitem_t *p;
const char *str;
if (properties) {
prop = PL_ObjectForKey (properties, ent->classname);
if (!prop)
prop = PL_ObjectForKey (properties, "default");
}
if ((p = get_item ("light", dict, prop))
|| (p = get_item ("_light", dict, prop))) {
if ((str = plstring (p))) {
ent->light = parse_light (str, ent->color);
}
}
if ((p = get_item ("style", dict, prop))) {
if ((str = plstring (p))) {
ent->style = atoi (str);
if ((unsigned) ent->style > 254)
fprintf (stderr, "Bad light style %i (must be 0-254)",
ent->style);
}
}
if ((p = get_item ("angle", dict, prop))) {
if ((str = plstring (p))) {
ent->angle = parse_float (str);
}
}
if ((p = get_item ("wait", dict, prop))) {
if ((str = plstring (p))) {
ent->falloff = parse_float (str);
ent->falloff *= ent->falloff; // presquared
}
}
if ((p = get_item ("_lightradius", dict, prop))) {
if ((str = plstring (p))) {
ent->lightradius = parse_float (str);
}
}
if ((p = get_item ("color", dict, prop))
|| (p = get_item ("_color", dict, prop))) {
if ((str = plstring (p))) {
parse_color (str, ent->color2);
}
}
if ((p = get_item ("_attenuation", dict, prop))) {
if ((str = plstring (p))) {
ent->attenuation = parse_attenuation (str);
if (ent->attenuation == -1) {
ent->attenuation = options.attenuation;
fprintf (stderr, "Bad light light attenuation: %s\n",
str);
}
}
}
if ((p = get_item ("_radius", dict, prop))) {
if ((str = plstring (p))) {
ent->radius = parse_float (str);
}
}
if ((p = get_item ("_noise", dict, prop))) {
if ((str = plstring (p))) {
ent->noise = parse_float (str);
}
}
if ((p = get_item ("_noisetype", dict, prop))) {
if ((str = plstring (p))) {
ent->noisetype = parse_noise (str);
}
}
if ((p = get_item ("_persistence", dict, prop))) {
if ((str = plstring (p))) {
ent->persistence = parse_float (str);
}
}
if ((p = get_item ("_resolution", dict, prop))) {
if ((str = plstring (p))) {
ent->resolution = parse_float (str);
}
}
}
void
LoadProperties (const char *filename)
{
QFile *f;
char *buf;
int len;
f = Qopen (filename, "rt");
if (!f) {
perror (filename);
exit (1);
}
len = Qfilesize (f);
buf = malloc (len + 1);
Qread (f, buf, len);
Qclose (f);
buf[len] = 0;
properties = PL_GetPropertyList (buf);
free (buf);
}

View file

@ -60,6 +60,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "threads.h"
#include "entities.h"
#include "options.h"
#include "properties.h"
options_t options;
bsp_t *bsp;
@ -199,6 +200,9 @@ main (int argc, char **argv)
e = strrchr (litfile->str, '.');
dstring_replace (litfile, e - litfile->str, -1, ".lit", 5);
if (options.properties_filename)
LoadProperties (options.properties_filename);
f = Qopen (bspfile, "rbz");
if (!f)
Sys_Error ("could not open %s for reading", bspfile);