libpsys

diff src/pattr.c @ 16:3871a45a4e4b

Almost there
author John Tsiombikas <nuclear@mutantstargoat.com>
date Tue, 11 Sep 2012 02:13:12 +0300
parents 5678915dc2c7
children 7fbed016e739
line diff
     1.1 --- a/src/pattr.c	Mon Sep 10 21:57:49 2012 +0300
     1.2 +++ b/src/pattr.c	Tue Sep 11 02:13:12 2012 +0300
     1.3 @@ -1,3 +1,4 @@
     1.4 +#define _GNU_SOURCE
     1.5  #include <stdio.h>
     1.6  #include <stdlib.h>
     1.7  #include <string.h>
     1.8 @@ -31,7 +32,8 @@
     1.9  
    1.10  static int init_particle_attr(struct psys_particle_attributes *pattr);
    1.11  static void destroy_particle_attr(struct psys_particle_attributes *pattr);
    1.12 -static int get_cfg_opt(const char *line, struct cfgopt *opt);
    1.13 +static struct cfgopt *get_cfg_opt(const char *line);
    1.14 +static void release_cfg_opt(struct cfgopt *opt);
    1.15  static char *stripspace(char *str);
    1.16  
    1.17  static void *tex_cls;
    1.18 @@ -154,93 +156,114 @@
    1.19  {
    1.20  	int lineno = 0;
    1.21  	char buf[512];
    1.22 +	struct cfgopt *opt = 0;
    1.23  
    1.24  	psys_init_attr(attr);
    1.25  
    1.26  	while(fgets(buf, sizeof buf, fp)) {
    1.27 -		struct cfgopt opt;
    1.28  
    1.29  		lineno++;
    1.30  
    1.31 -		if(get_cfg_opt(buf, &opt) == -1) {
    1.32 +		if(!(opt = get_cfg_opt(buf))) {
    1.33 +			continue;
    1.34 +		}
    1.35 +
    1.36 +		if(strcmp(opt->name, "texture") == 0) {
    1.37 +			if(opt->type != OPT_STR) {
    1.38 +				goto err;
    1.39 +			}
    1.40 +			if(!(attr->tex = load_texture(opt->valstr, tex_cls))) {
    1.41 +				fprintf(stderr, "failed to load texture: %s\n", opt->valstr);
    1.42 +				goto err;
    1.43 +			}
    1.44 +
    1.45 +			release_cfg_opt(opt);
    1.46 +			continue;
    1.47 +		} else if(opt->type == OPT_STR) {
    1.48 +			fprintf(stderr, "invalid particle config: '%s'\n", opt->name);
    1.49  			goto err;
    1.50  		}
    1.51  
    1.52 -		if(strcmp(opt.name, "texture")) {
    1.53 -			if(opt.type != OPT_STR) {
    1.54 -				goto err;
    1.55 -			}
    1.56 -			if(!(attr->tex = load_texture(opt.valstr, tex_cls))) {
    1.57 -				fprintf(stderr, "failed to load texture: %s\n", opt.valstr);
    1.58 -				goto err;
    1.59 -			}
    1.60 -		} else if(opt.type == OPT_STR) {
    1.61 -			fprintf(stderr, "invalid particle config: %s\n", opt.name);
    1.62 +		if(strcmp(opt->name, "spawn_range") == 0) {
    1.63 +			psys_set_value3(&attr->spawn_range, opt->tm, opt->val);
    1.64 +		} else if(strcmp(opt->name, "rate") == 0) {
    1.65 +			psys_set_value(&attr->rate, opt->tm, opt->val.x);
    1.66 +		} else if(strcmp(opt->name, "life") == 0) {
    1.67 +			psys_set_anm_rnd(&attr->life, opt->tm, opt->val.x, opt->valrng.x);
    1.68 +		} else if(strcmp(opt->name, "size") == 0) {
    1.69 +			psys_set_anm_rnd(&attr->size, opt->tm, opt->val.x, opt->valrng.x);
    1.70 +		} else if(strcmp(opt->name, "dir") == 0) {
    1.71 +			psys_set_anm_rnd3(&attr->dir, opt->tm, opt->val, opt->valrng);
    1.72 +		} else if(strcmp(opt->name, "grav") == 0) {
    1.73 +			psys_set_value3(&attr->grav, opt->tm, opt->val);
    1.74 +		} else if(strcmp(opt->name, "drag") == 0) {
    1.75 +			attr->drag = opt->val.x;
    1.76 +		} else if(strcmp(opt->name, "pcolor") == 0) {
    1.77 +			psys_set_value3(&attr->part_attr.color, opt->tm, opt->val);
    1.78 +		} else if(strcmp(opt->name, "palpha") == 0) {
    1.79 +			psys_set_value(&attr->part_attr.alpha, opt->tm, opt->val.x);
    1.80 +		} else if(strcmp(opt->name, "psize") == 0) {
    1.81 +			psys_set_value(&attr->part_attr.size, opt->tm, opt->val.x);
    1.82 +		} else {
    1.83 +			fprintf(stderr, "unrecognized particle config option: %s\n", opt->name);
    1.84  			goto err;
    1.85  		}
    1.86  
    1.87 -		if(strcmp(opt.name, "spawn_range") == 0) {
    1.88 -			psys_set_value3(&attr->spawn_range, opt.tm, opt.val);
    1.89 -		} else if(strcmp(opt.name, "rate") == 0) {
    1.90 -			psys_set_value(&attr->rate, opt.tm, opt.val.x);
    1.91 -		} else if(strcmp(opt.name, "life") == 0) {
    1.92 -			psys_set_anm_rnd(&attr->life, opt.tm, opt.val.x, opt.valrng.x);
    1.93 -		} else if(strcmp(opt.name, "size") == 0) {
    1.94 -			psys_set_anm_rnd(&attr->size, opt.tm, opt.val.x, opt.valrng.x);
    1.95 -		} else if(strcmp(opt.name, "dir") == 0) {
    1.96 -			psys_set_anm_rnd3(&attr->dir, opt.tm, opt.val, opt.valrng);
    1.97 -		} else if(strcmp(opt.name, "grav") == 0) {
    1.98 -			psys_set_value3(&attr->grav, opt.tm, opt.val);
    1.99 -		} else if(strcmp(opt.name, "drag") == 0) {
   1.100 -			attr->drag = opt.val.x;
   1.101 -		} else if(strcmp(opt.name, "pcolor") == 0) {
   1.102 -			psys_set_value3(&attr->part_attr.color, opt.tm, opt.val);
   1.103 -		} else if(strcmp(opt.name, "palpha") == 0) {
   1.104 -			psys_set_value(&attr->part_attr.alpha, opt.tm, opt.val.x);
   1.105 -		} else if(strcmp(opt.name, "psize") == 0) {
   1.106 -			psys_set_value(&attr->part_attr.size, opt.tm, opt.val.x);
   1.107 -		} else {
   1.108 -			fprintf(stderr, "unrecognized particle config option: %s\n", opt.name);
   1.109 -			goto err;
   1.110 -		}
   1.111 +		release_cfg_opt(opt);
   1.112  	}
   1.113  
   1.114  	return 0;
   1.115  
   1.116  err:
   1.117  	fprintf(stderr, "Line %d: error parsing particle definition\n", lineno);
   1.118 -	psys_destroy_attr(attr);
   1.119 +	release_cfg_opt(opt);
   1.120  	return -1;
   1.121  }
   1.122  
   1.123 -/* strdup on the stack with alloca */
   1.124 -#define strdup_stack(s)  strcpy(alloca(strlen(s) + 1), s)
   1.125 -
   1.126 -static int get_cfg_opt(const char *line, struct cfgopt *opt)
   1.127 +static struct cfgopt *get_cfg_opt(const char *line)
   1.128  {
   1.129 -	char *buf;
   1.130 -	float tmsec;
   1.131 +	char *buf, *tmp;
   1.132 +	struct cfgopt *opt;
   1.133  
   1.134  	line = stripspace((char*)line);
   1.135  	if(line[0] == '#' || !line[0]) {
   1.136  		return 0;	/* skip empty lines and comments */
   1.137  	}
   1.138 +
   1.139 +	if(!(opt = malloc(sizeof *opt))) {
   1.140 +		return 0;
   1.141 +	}
   1.142 +
   1.143  	if(!(opt->valstr = strchr(line, '='))) {
   1.144 -		return -1;
   1.145 +		release_cfg_opt(opt);
   1.146 +		return 0;
   1.147  	}
   1.148  	*opt->valstr++ = 0;
   1.149  	opt->valstr = stripspace(opt->valstr);
   1.150  
   1.151  	/* allocate a working buffer on the stack that could fit the current line */
   1.152  	buf = alloca(strlen(line) + 1);
   1.153 +	strcpy(buf, line);
   1.154 +	buf = stripspace(buf);
   1.155  
   1.156 -	if(sscanf(line, "%s(%fs)", buf, &tmsec) == 2) {
   1.157 -		opt->tm = (long)(tmsec * 1000.0f);
   1.158 -		opt->name = strdup_stack(buf);
   1.159 -	} else if(sscanf(line, "%s(%ld)", buf, &opt->tm) == 2) {
   1.160 -		opt->name = strdup_stack(buf);
   1.161 +	/* parse the keyframe time specifier if it exists */
   1.162 +	if((tmp = strchr(buf, '('))) {
   1.163 +		char *endp;
   1.164 +		float tval;
   1.165 +
   1.166 +		*tmp++ = 0;
   1.167 +		opt->name = strdup(buf);
   1.168 +
   1.169 +		tval = strtod(tmp + 1, &endp);
   1.170 +		if(endp == tmp + 1) { /* nada ... */
   1.171 +			opt->tm = 0;
   1.172 +		} else if(*endp == 's') {	/* seconds suffix */
   1.173 +			opt->tm = (long)(tval * 1000.0f);
   1.174 +		} else {
   1.175 +			opt->tm = (long)tval;
   1.176 +		}
   1.177  	} else {
   1.178 -		opt->name = strdup_stack(buf);
   1.179 +		opt->name = strdup(buf);
   1.180  		opt->tm = 0;
   1.181  	}
   1.182  
   1.183 @@ -268,16 +291,26 @@
   1.184  
   1.185  	} else if(sscanf(opt->valstr, "\"%s\"", buf) == 1) {
   1.186  		/* just a string... strip the quotes */
   1.187 +		if(buf[strlen(buf) - 1] == '\"') {
   1.188 +			buf[strlen(buf) - 1] = 0;
   1.189 +		}
   1.190  		opt->type = OPT_STR;
   1.191 -		opt->valstr = strdup_stack(buf);
   1.192 +		opt->valstr = strdup(buf);
   1.193  	} else {
   1.194  		/* fuck it ... */
   1.195 -		return -1;
   1.196 +		release_cfg_opt(opt);
   1.197 +		return 0;
   1.198  	}
   1.199  
   1.200 -	return 0;
   1.201 +	return opt;
   1.202  }
   1.203  
   1.204 +static void release_cfg_opt(struct cfgopt *opt)
   1.205 +{
   1.206 +	if(opt) {
   1.207 +		free(opt->name);
   1.208 +	}
   1.209 +}
   1.210  
   1.211  
   1.212  int psys_save_attr(struct psys_attributes *attr, const char *fname)
   1.213 @@ -308,7 +341,7 @@
   1.214  		str++;
   1.215  	}
   1.216  
   1.217 -	end = str + strlen(str);
   1.218 +	end = str + strlen(str) - 1;
   1.219  	while(end >= str && isspace(*end)) {
   1.220  		*end-- = 0;
   1.221  	}