dsys2
view 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 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 float eval_step(struct dsys_event *ev, demotime_t t);
12 static float eval_lerp(struct dsys_event *ev, demotime_t t);
13 static float eval_sigmoid(struct dsys_event *ev, demotime_t t);
15 static void free_event(struct dsys_event *ev);
17 static struct dsys_event *sort_evlist(struct dsys_event *list, int num_ev);
18 static struct dsys_event *merge_evlists(struct dsys_event *list1, struct dsys_event *list2);
21 struct dsys_demo *dsys_open(const char *fname)
22 {
23 FILE *fp;
24 struct dsys_demo *demo;
26 if(!(fp = fopen(fname, "r"))) {
27 fprintf(stderr, "failed to open demoscript: %s: %s\n", fname, strerror(errno));
28 return 0;
29 }
31 if(!(demo = malloc(sizeof *demo))) {
32 perror("failed to allocate memory");
33 fclose(fp);
34 return 0;
35 }
36 memset(demo, 0, sizeof *demo);
38 demo->src_tm = demo->start_tm = -1;
40 if(read_script(demo, fp, fname) == -1) {
41 free(demo);
42 fclose(fp);
43 return 0;
44 }
46 fclose(fp);
47 return demo;
48 }
50 struct dsys_demo *dsys_open_stream(FILE *fp)
51 {
52 struct dsys_demo *demo;
54 if(!(demo = malloc(sizeof *demo))) {
55 perror("failed to allocate memory");
56 return 0;
57 }
58 memset(demo, 0, sizeof *demo);
60 demo->src_tm = demo->start_tm = -1;
62 if(read_script(demo, fp, 0) == -1) {
63 free(demo);
64 return 0;
65 }
67 return demo;
68 }
70 void dsys_close(struct dsys_demo *demo)
71 {
72 while(demo->evlist) {
73 struct dsys_event *ev = demo->evlist;
74 demo->evlist = demo->evlist->next;
75 free_event(ev);
76 }
78 free(demo);
79 }
82 #define SEP " \t\n\r"
84 static int read_script(struct dsys_demo *demo, FILE *fp, const char *fname)
85 {
86 int nline = 0;
87 char buf[512], *line, *tok, *endp;
88 unsigned int t0, t1;
89 struct dsys_event *ev;
91 if(!fname) {
92 fname = "<unknown>";
93 }
95 while(fgets(buf, sizeof buf, fp)) {
96 nline++;
98 line = buf;/*strip_ws(buf);*/
100 if(!line || !*line) {
101 continue;
102 }
104 if(!(tok = strtok(line, SEP)) || (t0 = strtol(tok, &endp, 10), endp == tok)) {
105 fprintf(stderr, "%s line: %d, error: expected timestamp t0\n", fname, nline);
106 return -1;
107 }
109 if(!(tok = strtok(0, SEP))) {
110 fprintf(stderr, "%s line: %d, error: expected second timestamp or event name\n", fname, nline);
111 return -1;
112 }
114 t1 = strtol(tok, &endp, 10);
115 if(endp == tok) {
116 t1 = t0;
117 } else {
118 if(!(tok = strtok(0, SEP))) {
119 fprintf(stderr, "%s line: %d, error: expected event name\n", fname, nline);
120 return -1;
121 }
122 }
124 if(!(ev = malloc(sizeof *ev))) {
125 perror("read_script: failed to allocate memory for an event\n");
126 return -1;
127 }
128 ev->t0 = t0;
129 ev->t1 = t1;
131 if(!(ev->name = malloc(strlen(tok) + 1))) {
132 free(ev);
133 sprintf("read_script: failed to allocate memory for the event name: %s\n", tok);
134 return -1;
135 }
136 strcpy(ev->name, tok);
138 ev->eval_func = t0 == t1 ? eval_step : eval_lerp;
140 ev->next = demo->evlist;
141 ev->prev = 0;
142 if(demo->evlist) {
143 demo->evlist->prev = ev;
144 }
145 demo->evlist = ev;
146 demo->num_ev++;
147 }
149 demo->evlist = sort_evlist(demo->evlist, demo->num_ev);
151 return 0;
152 }
155 void dsys_update(struct dsys_demo *demo, demotime_t tm)
156 {
157 demo->src_tm = tm;
159 if(demo->start_tm == -1) {
160 dsys_start(demo);
161 }
163 if(demo->running) {
164 demo->tm = tm - demo->start_tm - demo->stoppage_tm;
165 }
167 /* TODO check the events list etc etc */
168 }
170 void dsys_start(struct dsys_demo *demo)
171 {
172 if(demo->running) {
173 return;
174 }
176 if(demo->start_tm == -1) {
177 demo->start_tm = demo->src_tm;
178 } else {
179 demo->stoppage_tm += demo->src_tm - demo->stop_tm;
180 }
182 demo->running = 1;
183 }
185 void dsys_stop(struct dsys_demo *demo)
186 {
187 if(!demo->running) {
188 return;
189 }
191 demo->stop_tm = demo->src_tm;
192 demo->running = 0;
193 }
195 int dsys_is_running(struct dsys_demo *demo)
196 {
197 return demo->running;
198 }
201 demotime_t dsys_duration(struct dsys_demo *demo)
202 {
203 return demo->duration;
204 }
206 demotime_t dsys_time(struct dsys_demo *demo)
207 {
208 return demo->tm;
209 }
211 float dsys_progress(struct dsys_demo *demo)
212 {
213 return demo->tm / demo->duration;
214 }
216 /* seek without continuity */
217 void dsys_seek(struct dsys_demo *demo, demotime_t tm)
218 {
219 /* TODO */
220 }
222 void dsys_seek_norm(struct dsys_demo *demo, float t)
223 {
224 dsys_seek(demo, t * demo->duration);
225 }
227 /* seek by accelerating time */
228 void dsys_warp(struct dsys_demo *demo, demotime_t tm);
229 void dsys_warp_norm(struct dsys_demo *demo, float t);
232 /* events */
233 struct dsys_event *dsys_event(struct dsys_demo *demo, const char *name);
235 enum dsys_evtype dsys_event_type(struct dsys_event *ev);
236 float dsys_event_value(struct dsys_event *ev);
238 void dsys_event_callback(struct dsys_event *ev, void (*func)(void*), void *cls);
239 void dsys_event_link(struct dsys_event *ev, float *link);
242 /* time conversion */
243 demotime_t dsys_sec_to_dtime(float sec)
244 {
245 return sec;
246 }
248 demotime_t dsys_msec_to_dtime(unsigned long msec)
249 {
250 return (demotime_t)msec / 1000.0;
251 }
253 float dsys_dtime_to_sec(demotime_t tm)
254 {
255 return tm;
256 }
258 unsigned long dsys_dtime_to_msec(demotime_t tm)
259 {
260 return (unsigned long)(tm * 1000.0);
261 }
264 static float eval_step(struct dsys_event *ev, demotime_t t)
265 {
266 return t >= ev->t1 ? 1.0 : 0.0;
267 }
269 static float eval_lerp(struct dsys_event *ev, demotime_t t)
270 {
271 return (t - ev->t0) / (ev->t1 - ev->t0);
272 }
274 static float eval_sigmoid(struct dsys_event *ev, demotime_t t)
275 {
276 t = eval_lerp(ev, t);
277 return 1.0 - (cos(t * M_PI) * 0.5 + 0.5);
278 }
280 static void free_event(struct dsys_event *ev)
281 {
282 while(ev->cblist) {
283 struct callback *cb = ev->cblist;
284 ev->cblist = ev->cblist->next;
285 free(cb);
286 }
287 }
289 static struct dsys_event *sort_evlist(struct dsys_event *list, int num_ev)
290 {
291 int i, num_left, num_right;
292 struct dsys_event *left, *right, *node = list;
294 if(num_ev < 2) {
295 return list;
296 }
298 num_left = num_ev / 2;
299 num_right = num_ev - num_left;
301 for(i=0; i<num_ev/2; i++) {
302 node = node->next;
303 }
305 if(node->prev) {
306 node->prev->next = 0;
307 node->prev = 0;
308 }
310 left = sort_evlist(list, num_left);
311 right = sort_evlist(node, num_right);
313 return merge_evlists(left, right);
314 }
316 static struct dsys_event *merge_evlists(struct dsys_event *list1, struct dsys_event *list2)
317 {
318 struct dsys_event *head, *tail, *node;
320 if(!list1) {
321 return list2;
322 }
323 if(!list2) {
324 return list1;
325 }
327 head = tail = 0;
329 while(list1 && list2) {
330 if(list1->t0 < list2->t0) {
331 node = list1;
332 list1 = list1->next;
333 } else {
334 node = list2;
335 list2 = list2->next;
336 }
338 node->next = 0;
339 node->prev = tail;
341 if(!head) {
342 head = node;
343 } else {
344 tail->next = node;
345 }
346 tail = node;
347 }
349 if(list1) {
350 tail->next = list1;
351 list1->prev = tail;
352 } else if(list2) {
353 tail->next = list2;
354 list2->prev = tail;
355 }
357 return head;
358 }