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