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;