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 }