dsys2

annotate src/dsys.c @ 5:94ce16dd20c0

foo
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 02 Sep 2011 01:57:00 +0300
parents 95f010f7eadc
children 80f86f0f67ec
rev   line source
nuclear@2 1 #include <stdio.h>
nuclear@2 2 #include <math.h>
nuclear@2 3 #include <stdlib.h>
nuclear@2 4 #include <string.h>
nuclear@2 5 #include <errno.h>
nuclear@2 6 #include "dsys2.h"
nuclear@2 7 #include "dsys_impl.h"
nuclear@2 8
nuclear@4 9 static int read_script(struct dsys_demo *demo, FILE *fp, const char *fname);
nuclear@4 10
nuclear@2 11 static void free_event(struct dsys_event *ev);
nuclear@2 12
nuclear@4 13 static struct dsys_event *sort_evlist(struct dsys_event *list, int num_ev);
nuclear@4 14 static struct dsys_event *merge_evlists(struct dsys_event *list1, struct dsys_event *list2);
nuclear@2 15
nuclear@2 16
nuclear@2 17 struct dsys_demo *dsys_open(const char *fname)
nuclear@2 18 {
nuclear@2 19 FILE *fp;
nuclear@4 20 struct dsys_demo *demo;
nuclear@2 21
nuclear@2 22 if(!(fp = fopen(fname, "r"))) {
nuclear@2 23 fprintf(stderr, "failed to open demoscript: %s: %s\n", fname, strerror(errno));
nuclear@2 24 return 0;
nuclear@2 25 }
nuclear@2 26
nuclear@4 27 if(!(demo = malloc(sizeof *demo))) {
nuclear@4 28 perror("failed to allocate memory");
nuclear@4 29 fclose(fp);
nuclear@4 30 return 0;
nuclear@4 31 }
nuclear@4 32 memset(demo, 0, sizeof *demo);
nuclear@4 33
nuclear@4 34 demo->src_tm = demo->start_tm = -1;
nuclear@4 35
nuclear@4 36 if(read_script(demo, fp, fname) == -1) {
nuclear@4 37 free(demo);
nuclear@4 38 fclose(fp);
nuclear@4 39 return 0;
nuclear@4 40 }
nuclear@4 41
nuclear@2 42 fclose(fp);
nuclear@4 43 return demo;
nuclear@2 44 }
nuclear@2 45
nuclear@2 46 struct dsys_demo *dsys_open_stream(FILE *fp)
nuclear@2 47 {
nuclear@2 48 struct dsys_demo *demo;
nuclear@2 49
nuclear@2 50 if(!(demo = malloc(sizeof *demo))) {
nuclear@2 51 perror("failed to allocate memory");
nuclear@2 52 return 0;
nuclear@2 53 }
nuclear@2 54 memset(demo, 0, sizeof *demo);
nuclear@2 55
nuclear@2 56 demo->src_tm = demo->start_tm = -1;
nuclear@2 57
nuclear@4 58 if(read_script(demo, fp, 0) == -1) {
nuclear@3 59 free(demo);
nuclear@3 60 return 0;
nuclear@3 61 }
nuclear@3 62
nuclear@2 63 return demo;
nuclear@2 64 }
nuclear@2 65
nuclear@2 66 void dsys_close(struct dsys_demo *demo)
nuclear@2 67 {
nuclear@4 68 while(demo->evlist) {
nuclear@4 69 struct dsys_event *ev = demo->evlist;
nuclear@4 70 demo->evlist = demo->evlist->next;
nuclear@2 71 free_event(ev);
nuclear@2 72 }
nuclear@2 73
nuclear@2 74 free(demo);
nuclear@2 75 }
nuclear@2 76
nuclear@2 77
nuclear@4 78 #define SEP " \t\n\r"
nuclear@3 79
nuclear@4 80 static int read_script(struct dsys_demo *demo, FILE *fp, const char *fname)
nuclear@3 81 {
nuclear@3 82 int nline = 0;
nuclear@4 83 char buf[512], *line, *tok, *endp;
nuclear@4 84 unsigned int t0, t1;
nuclear@3 85 struct dsys_event *ev;
nuclear@3 86
nuclear@4 87 if(!fname) {
nuclear@4 88 fname = "<unknown>";
nuclear@4 89 }
nuclear@4 90
nuclear@3 91 while(fgets(buf, sizeof buf, fp)) {
nuclear@3 92 nline++;
nuclear@3 93
nuclear@3 94 line = buf;/*strip_ws(buf);*/
nuclear@3 95
nuclear@3 96 if(!line || !*line) {
nuclear@3 97 continue;
nuclear@3 98 }
nuclear@3 99
nuclear@4 100 if(!(tok = strtok(line, SEP)) || (t0 = strtol(tok, &endp, 10), endp == tok)) {
nuclear@4 101 fprintf(stderr, "%s line: %d, error: expected timestamp t0\n", fname, nline);
nuclear@3 102 return -1;
nuclear@3 103 }
nuclear@3 104
nuclear@3 105 if(!(tok = strtok(0, SEP))) {
nuclear@4 106 fprintf(stderr, "%s line: %d, error: expected second timestamp or event name\n", fname, nline);
nuclear@3 107 return -1;
nuclear@3 108 }
nuclear@3 109
nuclear@4 110 t1 = strtol(tok, &endp, 10);
nuclear@4 111 if(endp == tok) {
nuclear@4 112 t1 = t0;
nuclear@4 113 } else {
nuclear@4 114 if(!(tok = strtok(0, SEP))) {
nuclear@4 115 fprintf(stderr, "%s line: %d, error: expected event name\n", fname, nline);
nuclear@4 116 return -1;
nuclear@4 117 }
nuclear@4 118 }
nuclear@4 119
nuclear@3 120 if(!(ev = malloc(sizeof *ev))) {
nuclear@3 121 perror("read_script: failed to allocate memory for an event\n");
nuclear@3 122 return -1;
nuclear@3 123 }
nuclear@3 124 ev->t0 = t0;
nuclear@3 125 ev->t1 = t1;
nuclear@3 126
nuclear@3 127 if(!(ev->name = malloc(strlen(tok) + 1))) {
nuclear@3 128 free(ev);
nuclear@5 129 fprintf(stderr, "read_script: failed to allocate memory for the event name: %s\n", tok);
nuclear@3 130 return -1;
nuclear@3 131 }
nuclear@4 132 strcpy(ev->name, tok);
nuclear@4 133
nuclear@5 134 ev->eval_func = t0 == t1 ? dsys_eval_step : dsys_eval_lerp;
nuclear@4 135
nuclear@4 136 ev->next = demo->evlist;
nuclear@4 137 ev->prev = 0;
nuclear@4 138 if(demo->evlist) {
nuclear@4 139 demo->evlist->prev = ev;
nuclear@4 140 }
nuclear@4 141 demo->evlist = ev;
nuclear@4 142 demo->num_ev++;
nuclear@3 143 }
nuclear@3 144
nuclear@4 145 demo->evlist = sort_evlist(demo->evlist, demo->num_ev);
nuclear@4 146
nuclear@3 147 return 0;
nuclear@3 148 }
nuclear@3 149
nuclear@3 150
nuclear@2 151 void dsys_update(struct dsys_demo *demo, demotime_t tm)
nuclear@2 152 {
nuclear@2 153 demo->src_tm = tm;
nuclear@2 154
nuclear@2 155 if(demo->start_tm == -1) {
nuclear@2 156 dsys_start(demo);
nuclear@2 157 }
nuclear@2 158
nuclear@2 159 if(demo->running) {
nuclear@2 160 demo->tm = tm - demo->start_tm - demo->stoppage_tm;
nuclear@2 161 }
nuclear@2 162
nuclear@2 163 /* TODO check the events list etc etc */
nuclear@2 164 }
nuclear@2 165
nuclear@2 166 void dsys_start(struct dsys_demo *demo)
nuclear@2 167 {
nuclear@2 168 if(demo->running) {
nuclear@2 169 return;
nuclear@2 170 }
nuclear@2 171
nuclear@2 172 if(demo->start_tm == -1) {
nuclear@2 173 demo->start_tm = demo->src_tm;
nuclear@2 174 } else {
nuclear@2 175 demo->stoppage_tm += demo->src_tm - demo->stop_tm;
nuclear@2 176 }
nuclear@2 177
nuclear@2 178 demo->running = 1;
nuclear@2 179 }
nuclear@2 180
nuclear@2 181 void dsys_stop(struct dsys_demo *demo)
nuclear@2 182 {
nuclear@2 183 if(!demo->running) {
nuclear@2 184 return;
nuclear@2 185 }
nuclear@2 186
nuclear@2 187 demo->stop_tm = demo->src_tm;
nuclear@2 188 demo->running = 0;
nuclear@2 189 }
nuclear@2 190
nuclear@2 191 int dsys_is_running(struct dsys_demo *demo)
nuclear@2 192 {
nuclear@2 193 return demo->running;
nuclear@2 194 }
nuclear@2 195
nuclear@2 196
nuclear@2 197 demotime_t dsys_duration(struct dsys_demo *demo)
nuclear@2 198 {
nuclear@2 199 return demo->duration;
nuclear@2 200 }
nuclear@2 201
nuclear@2 202 demotime_t dsys_time(struct dsys_demo *demo)
nuclear@2 203 {
nuclear@2 204 return demo->tm;
nuclear@2 205 }
nuclear@2 206
nuclear@2 207 float dsys_progress(struct dsys_demo *demo)
nuclear@2 208 {
nuclear@2 209 return demo->tm / demo->duration;
nuclear@2 210 }
nuclear@2 211
nuclear@2 212 /* seek without continuity */
nuclear@2 213 void dsys_seek(struct dsys_demo *demo, demotime_t tm)
nuclear@2 214 {
nuclear@2 215 /* TODO */
nuclear@2 216 }
nuclear@2 217
nuclear@2 218 void dsys_seek_norm(struct dsys_demo *demo, float t)
nuclear@2 219 {
nuclear@2 220 dsys_seek(demo, t * demo->duration);
nuclear@2 221 }
nuclear@2 222
nuclear@2 223 /* seek by accelerating time */
nuclear@2 224 void dsys_warp(struct dsys_demo *demo, demotime_t tm);
nuclear@2 225 void dsys_warp_norm(struct dsys_demo *demo, float t);
nuclear@2 226
nuclear@2 227
nuclear@2 228 /* events */
nuclear@5 229 struct dsys_event *dsys_event(struct dsys_demo *demo, const char *name)
nuclear@5 230 {
nuclear@5 231 struct dsys_event *iter = demo->evlist;
nuclear@2 232
nuclear@5 233 while(iter) {
nuclear@5 234 if(strcmp(iter->name, name) == 0) {
nuclear@5 235 return iter;
nuclear@5 236 }
nuclear@5 237 iter = iter->next;
nuclear@5 238 }
nuclear@5 239 return 0;
nuclear@5 240 }
nuclear@2 241
nuclear@5 242 enum dsys_evtype dsys_event_type(struct dsys_event *ev)
nuclear@5 243 {
nuclear@5 244 return ev->type;
nuclear@5 245 }
nuclear@5 246
nuclear@5 247 float dsys_event_value(struct dsys_event *ev)
nuclear@5 248 {
nuclear@5 249 return ev->value;
nuclear@5 250 }
nuclear@5 251
nuclear@5 252 void dsys_event_callback(struct dsys_event *ev, void (*func)(void*), void *cls)
nuclear@5 253 {
nuclear@5 254 }
nuclear@5 255
nuclear@2 256 void dsys_event_link(struct dsys_event *ev, float *link);
nuclear@2 257
nuclear@2 258
nuclear@2 259 /* time conversion */
nuclear@2 260 demotime_t dsys_sec_to_dtime(float sec)
nuclear@2 261 {
nuclear@2 262 return sec;
nuclear@2 263 }
nuclear@2 264
nuclear@2 265 demotime_t dsys_msec_to_dtime(unsigned long msec)
nuclear@2 266 {
nuclear@2 267 return (demotime_t)msec / 1000.0;
nuclear@2 268 }
nuclear@2 269
nuclear@2 270 float dsys_dtime_to_sec(demotime_t tm)
nuclear@2 271 {
nuclear@2 272 return tm;
nuclear@2 273 }
nuclear@2 274
nuclear@2 275 unsigned long dsys_dtime_to_msec(demotime_t tm)
nuclear@2 276 {
nuclear@2 277 return (unsigned long)(tm * 1000.0);
nuclear@2 278 }
nuclear@2 279
nuclear@2 280
nuclear@5 281 float dsys_eval_step(struct dsys_event *ev, demotime_t t)
nuclear@2 282 {
nuclear@2 283 return t >= ev->t1 ? 1.0 : 0.0;
nuclear@2 284 }
nuclear@2 285
nuclear@5 286 float dsys_eval_lerp(struct dsys_event *ev, demotime_t t)
nuclear@2 287 {
nuclear@2 288 return (t - ev->t0) / (ev->t1 - ev->t0);
nuclear@2 289 }
nuclear@2 290
nuclear@5 291 float dsys_eval_sigmoid(struct dsys_event *ev, demotime_t t)
nuclear@2 292 {
nuclear@5 293 t = dsys_eval_lerp(ev, t);
nuclear@2 294 return 1.0 - (cos(t * M_PI) * 0.5 + 0.5);
nuclear@2 295 }
nuclear@2 296
nuclear@2 297 static void free_event(struct dsys_event *ev)
nuclear@2 298 {
nuclear@2 299 while(ev->cblist) {
nuclear@2 300 struct callback *cb = ev->cblist;
nuclear@2 301 ev->cblist = ev->cblist->next;
nuclear@2 302 free(cb);
nuclear@2 303 }
nuclear@2 304 }
nuclear@4 305
nuclear@4 306 static struct dsys_event *sort_evlist(struct dsys_event *list, int num_ev)
nuclear@4 307 {
nuclear@4 308 int i, num_left, num_right;
nuclear@4 309 struct dsys_event *left, *right, *node = list;
nuclear@4 310
nuclear@4 311 if(num_ev < 2) {
nuclear@4 312 return list;
nuclear@4 313 }
nuclear@4 314
nuclear@4 315 num_left = num_ev / 2;
nuclear@4 316 num_right = num_ev - num_left;
nuclear@4 317
nuclear@4 318 for(i=0; i<num_ev/2; i++) {
nuclear@4 319 node = node->next;
nuclear@4 320 }
nuclear@4 321
nuclear@4 322 if(node->prev) {
nuclear@4 323 node->prev->next = 0;
nuclear@4 324 node->prev = 0;
nuclear@4 325 }
nuclear@4 326
nuclear@4 327 left = sort_evlist(list, num_left);
nuclear@4 328 right = sort_evlist(node, num_right);
nuclear@4 329
nuclear@4 330 return merge_evlists(left, right);
nuclear@4 331 }
nuclear@4 332
nuclear@4 333 static struct dsys_event *merge_evlists(struct dsys_event *list1, struct dsys_event *list2)
nuclear@4 334 {
nuclear@4 335 struct dsys_event *head, *tail, *node;
nuclear@4 336
nuclear@4 337 if(!list1) {
nuclear@4 338 return list2;
nuclear@4 339 }
nuclear@4 340 if(!list2) {
nuclear@4 341 return list1;
nuclear@4 342 }
nuclear@4 343
nuclear@4 344 head = tail = 0;
nuclear@4 345
nuclear@4 346 while(list1 && list2) {
nuclear@4 347 if(list1->t0 < list2->t0) {
nuclear@4 348 node = list1;
nuclear@4 349 list1 = list1->next;
nuclear@4 350 } else {
nuclear@4 351 node = list2;
nuclear@4 352 list2 = list2->next;
nuclear@4 353 }
nuclear@4 354
nuclear@4 355 node->next = 0;
nuclear@4 356 node->prev = tail;
nuclear@4 357
nuclear@4 358 if(!head) {
nuclear@4 359 head = node;
nuclear@4 360 } else {
nuclear@4 361 tail->next = node;
nuclear@4 362 }
nuclear@4 363 tail = node;
nuclear@4 364 }
nuclear@4 365
nuclear@4 366 if(list1) {
nuclear@4 367 tail->next = list1;
nuclear@4 368 list1->prev = tail;
nuclear@4 369 } else if(list2) {
nuclear@4 370 tail->next = list2;
nuclear@4 371 list2->prev = tail;
nuclear@4 372 }
nuclear@4 373
nuclear@4 374 return head;
nuclear@4 375 }