libpsys

changeset 16:3871a45a4e4b

Almost there
author John Tsiombikas <nuclear@mutantstargoat.com>
date Tue, 11 Sep 2012 02:13:12 +0300
parents 5678915dc2c7
children 7fbed016e739
files examples/simple/simple.c src/pattr.c src/psys_gl.c
diffstat 3 files changed, 101 insertions(+), 58 deletions(-) [+]
line diff
     1.1 --- a/examples/simple/simple.c	Mon Sep 10 21:57:49 2012 +0300
     1.2 +++ b/examples/simple/simple.c	Tue Sep 11 02:13:12 2012 +0300
     1.3 @@ -51,7 +51,12 @@
     1.4  	if(!(ps = psys_create())) {
     1.5  		return 1;
     1.6  	}
     1.7 -	ps->attr.tex = tex;
     1.8 +	if(psys_load_attr(&ps->attr, "simple.psys") == -1) {
     1.9 +		fprintf(stderr, "failed to load particle system definition\n");
    1.10 +		psys_free(ps);
    1.11 +		return 1;
    1.12 +	}
    1.13 +	/*ps->attr.tex = tex;
    1.14  	ps->attr.drag = 2;
    1.15  	psys_set_value3(&ps->attr.grav, 0, v3_cons(0, -4, 0));
    1.16  	psys_set_anm_rnd(&ps->attr.life, 0, 2, 0);
    1.17 @@ -62,8 +67,9 @@
    1.18  	psys_set_value3(&ps->attr.part_attr.color, 1000,  v3_cons(0.6, 0.3, 1.0));
    1.19  	psys_set_value(&ps->attr.part_attr.alpha, 0, 1);
    1.20  	psys_set_value(&ps->attr.part_attr.alpha, 700, 1);
    1.21 -	psys_set_value(&ps->attr.part_attr.alpha, 1000, 0);
    1.22 +	psys_set_value(&ps->attr.part_attr.alpha, 1000, 0);*/
    1.23  
    1.24 +	assert(glGetError() == GL_NO_ERROR);
    1.25  	atexit(cleanup);
    1.26  
    1.27  	glutMainLoop();
     2.1 --- a/src/pattr.c	Mon Sep 10 21:57:49 2012 +0300
     2.2 +++ b/src/pattr.c	Tue Sep 11 02:13:12 2012 +0300
     2.3 @@ -1,3 +1,4 @@
     2.4 +#define _GNU_SOURCE
     2.5  #include <stdio.h>
     2.6  #include <stdlib.h>
     2.7  #include <string.h>
     2.8 @@ -31,7 +32,8 @@
     2.9  
    2.10  static int init_particle_attr(struct psys_particle_attributes *pattr);
    2.11  static void destroy_particle_attr(struct psys_particle_attributes *pattr);
    2.12 -static int get_cfg_opt(const char *line, struct cfgopt *opt);
    2.13 +static struct cfgopt *get_cfg_opt(const char *line);
    2.14 +static void release_cfg_opt(struct cfgopt *opt);
    2.15  static char *stripspace(char *str);
    2.16  
    2.17  static void *tex_cls;
    2.18 @@ -154,93 +156,114 @@
    2.19  {
    2.20  	int lineno = 0;
    2.21  	char buf[512];
    2.22 +	struct cfgopt *opt = 0;
    2.23  
    2.24  	psys_init_attr(attr);
    2.25  
    2.26  	while(fgets(buf, sizeof buf, fp)) {
    2.27 -		struct cfgopt opt;
    2.28  
    2.29  		lineno++;
    2.30  
    2.31 -		if(get_cfg_opt(buf, &opt) == -1) {
    2.32 +		if(!(opt = get_cfg_opt(buf))) {
    2.33 +			continue;
    2.34 +		}
    2.35 +
    2.36 +		if(strcmp(opt->name, "texture") == 0) {
    2.37 +			if(opt->type != OPT_STR) {
    2.38 +				goto err;
    2.39 +			}
    2.40 +			if(!(attr->tex = load_texture(opt->valstr, tex_cls))) {
    2.41 +				fprintf(stderr, "failed to load texture: %s\n", opt->valstr);
    2.42 +				goto err;
    2.43 +			}
    2.44 +
    2.45 +			release_cfg_opt(opt);
    2.46 +			continue;
    2.47 +		} else if(opt->type == OPT_STR) {
    2.48 +			fprintf(stderr, "invalid particle config: '%s'\n", opt->name);
    2.49  			goto err;
    2.50  		}
    2.51  
    2.52 -		if(strcmp(opt.name, "texture")) {
    2.53 -			if(opt.type != OPT_STR) {
    2.54 -				goto err;
    2.55 -			}
    2.56 -			if(!(attr->tex = load_texture(opt.valstr, tex_cls))) {
    2.57 -				fprintf(stderr, "failed to load texture: %s\n", opt.valstr);
    2.58 -				goto err;
    2.59 -			}
    2.60 -		} else if(opt.type == OPT_STR) {
    2.61 -			fprintf(stderr, "invalid particle config: %s\n", opt.name);
    2.62 +		if(strcmp(opt->name, "spawn_range") == 0) {
    2.63 +			psys_set_value3(&attr->spawn_range, opt->tm, opt->val);
    2.64 +		} else if(strcmp(opt->name, "rate") == 0) {
    2.65 +			psys_set_value(&attr->rate, opt->tm, opt->val.x);
    2.66 +		} else if(strcmp(opt->name, "life") == 0) {
    2.67 +			psys_set_anm_rnd(&attr->life, opt->tm, opt->val.x, opt->valrng.x);
    2.68 +		} else if(strcmp(opt->name, "size") == 0) {
    2.69 +			psys_set_anm_rnd(&attr->size, opt->tm, opt->val.x, opt->valrng.x);
    2.70 +		} else if(strcmp(opt->name, "dir") == 0) {
    2.71 +			psys_set_anm_rnd3(&attr->dir, opt->tm, opt->val, opt->valrng);
    2.72 +		} else if(strcmp(opt->name, "grav") == 0) {
    2.73 +			psys_set_value3(&attr->grav, opt->tm, opt->val);
    2.74 +		} else if(strcmp(opt->name, "drag") == 0) {
    2.75 +			attr->drag = opt->val.x;
    2.76 +		} else if(strcmp(opt->name, "pcolor") == 0) {
    2.77 +			psys_set_value3(&attr->part_attr.color, opt->tm, opt->val);
    2.78 +		} else if(strcmp(opt->name, "palpha") == 0) {
    2.79 +			psys_set_value(&attr->part_attr.alpha, opt->tm, opt->val.x);
    2.80 +		} else if(strcmp(opt->name, "psize") == 0) {
    2.81 +			psys_set_value(&attr->part_attr.size, opt->tm, opt->val.x);
    2.82 +		} else {
    2.83 +			fprintf(stderr, "unrecognized particle config option: %s\n", opt->name);
    2.84  			goto err;
    2.85  		}
    2.86  
    2.87 -		if(strcmp(opt.name, "spawn_range") == 0) {
    2.88 -			psys_set_value3(&attr->spawn_range, opt.tm, opt.val);
    2.89 -		} else if(strcmp(opt.name, "rate") == 0) {
    2.90 -			psys_set_value(&attr->rate, opt.tm, opt.val.x);
    2.91 -		} else if(strcmp(opt.name, "life") == 0) {
    2.92 -			psys_set_anm_rnd(&attr->life, opt.tm, opt.val.x, opt.valrng.x);
    2.93 -		} else if(strcmp(opt.name, "size") == 0) {
    2.94 -			psys_set_anm_rnd(&attr->size, opt.tm, opt.val.x, opt.valrng.x);
    2.95 -		} else if(strcmp(opt.name, "dir") == 0) {
    2.96 -			psys_set_anm_rnd3(&attr->dir, opt.tm, opt.val, opt.valrng);
    2.97 -		} else if(strcmp(opt.name, "grav") == 0) {
    2.98 -			psys_set_value3(&attr->grav, opt.tm, opt.val);
    2.99 -		} else if(strcmp(opt.name, "drag") == 0) {
   2.100 -			attr->drag = opt.val.x;
   2.101 -		} else if(strcmp(opt.name, "pcolor") == 0) {
   2.102 -			psys_set_value3(&attr->part_attr.color, opt.tm, opt.val);
   2.103 -		} else if(strcmp(opt.name, "palpha") == 0) {
   2.104 -			psys_set_value(&attr->part_attr.alpha, opt.tm, opt.val.x);
   2.105 -		} else if(strcmp(opt.name, "psize") == 0) {
   2.106 -			psys_set_value(&attr->part_attr.size, opt.tm, opt.val.x);
   2.107 -		} else {
   2.108 -			fprintf(stderr, "unrecognized particle config option: %s\n", opt.name);
   2.109 -			goto err;
   2.110 -		}
   2.111 +		release_cfg_opt(opt);
   2.112  	}
   2.113  
   2.114  	return 0;
   2.115  
   2.116  err:
   2.117  	fprintf(stderr, "Line %d: error parsing particle definition\n", lineno);
   2.118 -	psys_destroy_attr(attr);
   2.119 +	release_cfg_opt(opt);
   2.120  	return -1;
   2.121  }
   2.122  
   2.123 -/* strdup on the stack with alloca */
   2.124 -#define strdup_stack(s)  strcpy(alloca(strlen(s) + 1), s)
   2.125 -
   2.126 -static int get_cfg_opt(const char *line, struct cfgopt *opt)
   2.127 +static struct cfgopt *get_cfg_opt(const char *line)
   2.128  {
   2.129 -	char *buf;
   2.130 -	float tmsec;
   2.131 +	char *buf, *tmp;
   2.132 +	struct cfgopt *opt;
   2.133  
   2.134  	line = stripspace((char*)line);
   2.135  	if(line[0] == '#' || !line[0]) {
   2.136  		return 0;	/* skip empty lines and comments */
   2.137  	}
   2.138 +
   2.139 +	if(!(opt = malloc(sizeof *opt))) {
   2.140 +		return 0;
   2.141 +	}
   2.142 +
   2.143  	if(!(opt->valstr = strchr(line, '='))) {
   2.144 -		return -1;
   2.145 +		release_cfg_opt(opt);
   2.146 +		return 0;
   2.147  	}
   2.148  	*opt->valstr++ = 0;
   2.149  	opt->valstr = stripspace(opt->valstr);
   2.150  
   2.151  	/* allocate a working buffer on the stack that could fit the current line */
   2.152  	buf = alloca(strlen(line) + 1);
   2.153 +	strcpy(buf, line);
   2.154 +	buf = stripspace(buf);
   2.155  
   2.156 -	if(sscanf(line, "%s(%fs)", buf, &tmsec) == 2) {
   2.157 -		opt->tm = (long)(tmsec * 1000.0f);
   2.158 -		opt->name = strdup_stack(buf);
   2.159 -	} else if(sscanf(line, "%s(%ld)", buf, &opt->tm) == 2) {
   2.160 -		opt->name = strdup_stack(buf);
   2.161 +	/* parse the keyframe time specifier if it exists */
   2.162 +	if((tmp = strchr(buf, '('))) {
   2.163 +		char *endp;
   2.164 +		float tval;
   2.165 +
   2.166 +		*tmp++ = 0;
   2.167 +		opt->name = strdup(buf);
   2.168 +
   2.169 +		tval = strtod(tmp + 1, &endp);
   2.170 +		if(endp == tmp + 1) { /* nada ... */
   2.171 +			opt->tm = 0;
   2.172 +		} else if(*endp == 's') {	/* seconds suffix */
   2.173 +			opt->tm = (long)(tval * 1000.0f);
   2.174 +		} else {
   2.175 +			opt->tm = (long)tval;
   2.176 +		}
   2.177  	} else {
   2.178 -		opt->name = strdup_stack(buf);
   2.179 +		opt->name = strdup(buf);
   2.180  		opt->tm = 0;
   2.181  	}
   2.182  
   2.183 @@ -268,16 +291,26 @@
   2.184  
   2.185  	} else if(sscanf(opt->valstr, "\"%s\"", buf) == 1) {
   2.186  		/* just a string... strip the quotes */
   2.187 +		if(buf[strlen(buf) - 1] == '\"') {
   2.188 +			buf[strlen(buf) - 1] = 0;
   2.189 +		}
   2.190  		opt->type = OPT_STR;
   2.191 -		opt->valstr = strdup_stack(buf);
   2.192 +		opt->valstr = strdup(buf);
   2.193  	} else {
   2.194  		/* fuck it ... */
   2.195 -		return -1;
   2.196 +		release_cfg_opt(opt);
   2.197 +		return 0;
   2.198  	}
   2.199  
   2.200 -	return 0;
   2.201 +	return opt;
   2.202  }
   2.203  
   2.204 +static void release_cfg_opt(struct cfgopt *opt)
   2.205 +{
   2.206 +	if(opt) {
   2.207 +		free(opt->name);
   2.208 +	}
   2.209 +}
   2.210  
   2.211  
   2.212  int psys_save_attr(struct psys_attributes *attr, const char *fname)
   2.213 @@ -308,7 +341,7 @@
   2.214  		str++;
   2.215  	}
   2.216  
   2.217 -	end = str + strlen(str);
   2.218 +	end = str + strlen(str) - 1;
   2.219  	while(end >= str && isspace(*end)) {
   2.220  		*end-- = 0;
   2.221  	}
     3.1 --- a/src/psys_gl.c	Mon Sep 10 21:57:49 2012 +0300
     3.2 +++ b/src/psys_gl.c	Tue Sep 11 02:13:12 2012 +0300
     3.3 @@ -1,5 +1,6 @@
     3.4  #include <string.h>
     3.5  #include <errno.h>
     3.6 +#include <assert.h>
     3.7  
     3.8  #ifndef __APPLE__
     3.9  #ifdef WIN32
    3.10 @@ -85,6 +86,7 @@
    3.11  	if(!(pixels = img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGBA32))) {
    3.12  		return 0;
    3.13  	}
    3.14 +	printf("%s: creating texture %s (%dx%d)\n", __func__, fname, xsz, ysz);
    3.15  
    3.16  	glGenTextures(1, &tex);
    3.17  	glBindTexture(GL_TEXTURE_2D, tex);
    3.18 @@ -92,7 +94,9 @@
    3.19  	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    3.20  	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    3.21  	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    3.22 -	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, xsz, ysz, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    3.23 +	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    3.24 +
    3.25 +	assert(glGetError() == GL_NO_ERROR);
    3.26  
    3.27  	img_free_pixels(pixels);
    3.28  	return tex;