dsys2
diff src/dsys.c @ 4:95f010f7eadc
*burp*
author | John Tsiombikas <nuclear@siggraph.org> |
---|---|
date | Thu, 01 Sep 2011 07:55:22 +0300 |
parents | eec499998960 |
children | 94ce16dd20c0 |
line diff
1.1 --- a/src/dsys.c Wed Aug 31 23:23:38 2011 +0300 1.2 +++ b/src/dsys.c Thu Sep 01 07:55:22 2011 +0300 1.3 @@ -6,27 +6,45 @@ 1.4 #include "dsys2.h" 1.5 #include "dsys_impl.h" 1.6 1.7 +static int read_script(struct dsys_demo *demo, FILE *fp, const char *fname); 1.8 + 1.9 static float eval_step(struct dsys_event *ev, demotime_t t); 1.10 static float eval_lerp(struct dsys_event *ev, demotime_t t); 1.11 static float eval_sigmoid(struct dsys_event *ev, demotime_t t); 1.12 1.13 static void free_event(struct dsys_event *ev); 1.14 1.15 +static struct dsys_event *sort_evlist(struct dsys_event *list, int num_ev); 1.16 +static struct dsys_event *merge_evlists(struct dsys_event *list1, struct dsys_event *list2); 1.17 1.18 1.19 struct dsys_demo *dsys_open(const char *fname) 1.20 { 1.21 FILE *fp; 1.22 - struct dsys_demo *res; 1.23 + struct dsys_demo *demo; 1.24 1.25 if(!(fp = fopen(fname, "r"))) { 1.26 fprintf(stderr, "failed to open demoscript: %s: %s\n", fname, strerror(errno)); 1.27 return 0; 1.28 } 1.29 1.30 - res = dsys_open_stream(fp); 1.31 + if(!(demo = malloc(sizeof *demo))) { 1.32 + perror("failed to allocate memory"); 1.33 + fclose(fp); 1.34 + return 0; 1.35 + } 1.36 + memset(demo, 0, sizeof *demo); 1.37 + 1.38 + demo->src_tm = demo->start_tm = -1; 1.39 + 1.40 + if(read_script(demo, fp, fname) == -1) { 1.41 + free(demo); 1.42 + fclose(fp); 1.43 + return 0; 1.44 + } 1.45 + 1.46 fclose(fp); 1.47 - return res; 1.48 + return demo; 1.49 } 1.50 1.51 struct dsys_demo *dsys_open_stream(FILE *fp) 1.52 @@ -41,7 +59,7 @@ 1.53 1.54 demo->src_tm = demo->start_tm = -1; 1.55 1.56 - if(read_script(demo, fp) == -1) { 1.57 + if(read_script(demo, fp, 0) == -1) { 1.58 free(demo); 1.59 return 0; 1.60 } 1.61 @@ -51,9 +69,9 @@ 1.62 1.63 void dsys_close(struct dsys_demo *demo) 1.64 { 1.65 - while(demo->ev) { 1.66 - struct dsys_event *ev = demo->ev; 1.67 - demo->ev = demo->ev->next; 1.68 + while(demo->evlist) { 1.69 + struct dsys_event *ev = demo->evlist; 1.70 + demo->evlist = demo->evlist->next; 1.71 free_event(ev); 1.72 } 1.73 1.74 @@ -61,14 +79,19 @@ 1.75 } 1.76 1.77 1.78 +#define SEP " \t\n\r" 1.79 1.80 -static int read_script(struct dsys_demo *demo, FILE *fp) 1.81 +static int read_script(struct dsys_demo *demo, FILE *fp, const char *fname) 1.82 { 1.83 int nline = 0; 1.84 - char buf[512], *line, tok; 1.85 - int timestamp; 1.86 + char buf[512], *line, *tok, *endp; 1.87 + unsigned int t0, t1; 1.88 struct dsys_event *ev; 1.89 1.90 + if(!fname) { 1.91 + fname = "<unknown>"; 1.92 + } 1.93 + 1.94 while(fgets(buf, sizeof buf, fp)) { 1.95 nline++; 1.96 1.97 @@ -78,17 +101,26 @@ 1.98 continue; 1.99 } 1.100 1.101 - if(!(tok = strtok(line, SEP)) || !isdigit(*tok)) { 1.102 - fprintf(stderr, "error reading script at line: %d: expected timestamp\n", nline); 1.103 + if(!(tok = strtok(line, SEP)) || (t0 = strtol(tok, &endp, 10), endp == tok)) { 1.104 + fprintf(stderr, "%s line: %d, error: expected timestamp t0\n", fname, nline); 1.105 return -1; 1.106 } 1.107 - timestamp = atoi(tok); 1.108 1.109 if(!(tok = strtok(0, SEP))) { 1.110 - fprintf(stderr, "error reading script at line: %d: expected event name\n", nline); 1.111 + fprintf(stderr, "%s line: %d, error: expected second timestamp or event name\n", fname, nline); 1.112 return -1; 1.113 } 1.114 1.115 + t1 = strtol(tok, &endp, 10); 1.116 + if(endp == tok) { 1.117 + t1 = t0; 1.118 + } else { 1.119 + if(!(tok = strtok(0, SEP))) { 1.120 + fprintf(stderr, "%s line: %d, error: expected event name\n", fname, nline); 1.121 + return -1; 1.122 + } 1.123 + } 1.124 + 1.125 if(!(ev = malloc(sizeof *ev))) { 1.126 perror("read_script: failed to allocate memory for an event\n"); 1.127 return -1; 1.128 @@ -101,8 +133,21 @@ 1.129 sprintf("read_script: failed to allocate memory for the event name: %s\n", tok); 1.130 return -1; 1.131 } 1.132 + strcpy(ev->name, tok); 1.133 + 1.134 + ev->eval_func = t0 == t1 ? eval_step : eval_lerp; 1.135 + 1.136 + ev->next = demo->evlist; 1.137 + ev->prev = 0; 1.138 + if(demo->evlist) { 1.139 + demo->evlist->prev = ev; 1.140 + } 1.141 + demo->evlist = ev; 1.142 + demo->num_ev++; 1.143 } 1.144 1.145 + demo->evlist = sort_evlist(demo->evlist, demo->num_ev); 1.146 + 1.147 return 0; 1.148 } 1.149 1.150 @@ -240,3 +285,74 @@ 1.151 free(cb); 1.152 } 1.153 } 1.154 + 1.155 +static struct dsys_event *sort_evlist(struct dsys_event *list, int num_ev) 1.156 +{ 1.157 + int i, num_left, num_right; 1.158 + struct dsys_event *left, *right, *node = list; 1.159 + 1.160 + if(num_ev < 2) { 1.161 + return list; 1.162 + } 1.163 + 1.164 + num_left = num_ev / 2; 1.165 + num_right = num_ev - num_left; 1.166 + 1.167 + for(i=0; i<num_ev/2; i++) { 1.168 + node = node->next; 1.169 + } 1.170 + 1.171 + if(node->prev) { 1.172 + node->prev->next = 0; 1.173 + node->prev = 0; 1.174 + } 1.175 + 1.176 + left = sort_evlist(list, num_left); 1.177 + right = sort_evlist(node, num_right); 1.178 + 1.179 + return merge_evlists(left, right); 1.180 +} 1.181 + 1.182 +static struct dsys_event *merge_evlists(struct dsys_event *list1, struct dsys_event *list2) 1.183 +{ 1.184 + struct dsys_event *head, *tail, *node; 1.185 + 1.186 + if(!list1) { 1.187 + return list2; 1.188 + } 1.189 + if(!list2) { 1.190 + return list1; 1.191 + } 1.192 + 1.193 + head = tail = 0; 1.194 + 1.195 + while(list1 && list2) { 1.196 + if(list1->t0 < list2->t0) { 1.197 + node = list1; 1.198 + list1 = list1->next; 1.199 + } else { 1.200 + node = list2; 1.201 + list2 = list2->next; 1.202 + } 1.203 + 1.204 + node->next = 0; 1.205 + node->prev = tail; 1.206 + 1.207 + if(!head) { 1.208 + head = node; 1.209 + } else { 1.210 + tail->next = node; 1.211 + } 1.212 + tail = node; 1.213 + } 1.214 + 1.215 + if(list1) { 1.216 + tail->next = list1; 1.217 + list1->prev = tail; 1.218 + } else if(list2) { 1.219 + tail->next = list2; 1.220 + list2->prev = tail; 1.221 + } 1.222 + 1.223 + return head; 1.224 +}