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@7
|
5 #include <ctype.h>
|
nuclear@2
|
6 #include <errno.h>
|
nuclear@2
|
7 #include "dsys2.h"
|
nuclear@2
|
8 #include "dsys_impl.h"
|
nuclear@2
|
9
|
nuclear@4
|
10 static int read_script(struct dsys_demo *demo, FILE *fp, const char *fname);
|
nuclear@7
|
11 static char *strip_ws(char *buf);
|
nuclear@7
|
12 static void dbg_print_events(struct dsys_event *ev);
|
nuclear@4
|
13
|
nuclear@6
|
14 static void proc_event(struct dsys_event *ev, demotime_t tm);
|
nuclear@6
|
15 static void link_callback(struct dsys_event *ev, void *cls);
|
nuclear@2
|
16 static void free_event(struct dsys_event *ev);
|
nuclear@2
|
17
|
nuclear@4
|
18 static struct dsys_event *sort_evlist(struct dsys_event *list, int num_ev);
|
nuclear@4
|
19 static struct dsys_event *merge_evlists(struct dsys_event *list1, struct dsys_event *list2);
|
nuclear@2
|
20
|
nuclear@2
|
21
|
nuclear@2
|
22 struct dsys_demo *dsys_open(const char *fname)
|
nuclear@2
|
23 {
|
nuclear@2
|
24 FILE *fp;
|
nuclear@4
|
25 struct dsys_demo *demo;
|
nuclear@2
|
26
|
nuclear@2
|
27 if(!(fp = fopen(fname, "r"))) {
|
nuclear@2
|
28 fprintf(stderr, "failed to open demoscript: %s: %s\n", fname, strerror(errno));
|
nuclear@2
|
29 return 0;
|
nuclear@2
|
30 }
|
nuclear@2
|
31
|
nuclear@4
|
32 if(!(demo = malloc(sizeof *demo))) {
|
nuclear@4
|
33 perror("failed to allocate memory");
|
nuclear@4
|
34 fclose(fp);
|
nuclear@4
|
35 return 0;
|
nuclear@4
|
36 }
|
nuclear@4
|
37 memset(demo, 0, sizeof *demo);
|
nuclear@4
|
38
|
nuclear@4
|
39 demo->src_tm = demo->start_tm = -1;
|
nuclear@4
|
40
|
nuclear@4
|
41 if(read_script(demo, fp, fname) == -1) {
|
nuclear@4
|
42 free(demo);
|
nuclear@4
|
43 fclose(fp);
|
nuclear@4
|
44 return 0;
|
nuclear@4
|
45 }
|
nuclear@4
|
46
|
nuclear@2
|
47 fclose(fp);
|
nuclear@4
|
48 return demo;
|
nuclear@2
|
49 }
|
nuclear@2
|
50
|
nuclear@2
|
51 struct dsys_demo *dsys_open_stream(FILE *fp)
|
nuclear@2
|
52 {
|
nuclear@2
|
53 struct dsys_demo *demo;
|
nuclear@2
|
54
|
nuclear@2
|
55 if(!(demo = malloc(sizeof *demo))) {
|
nuclear@2
|
56 perror("failed to allocate memory");
|
nuclear@2
|
57 return 0;
|
nuclear@2
|
58 }
|
nuclear@2
|
59 memset(demo, 0, sizeof *demo);
|
nuclear@2
|
60
|
nuclear@2
|
61 demo->src_tm = demo->start_tm = -1;
|
nuclear@2
|
62
|
nuclear@4
|
63 if(read_script(demo, fp, 0) == -1) {
|
nuclear@3
|
64 free(demo);
|
nuclear@3
|
65 return 0;
|
nuclear@3
|
66 }
|
nuclear@3
|
67
|
nuclear@2
|
68 return demo;
|
nuclear@2
|
69 }
|
nuclear@2
|
70
|
nuclear@2
|
71 void dsys_close(struct dsys_demo *demo)
|
nuclear@2
|
72 {
|
nuclear@4
|
73 while(demo->evlist) {
|
nuclear@4
|
74 struct dsys_event *ev = demo->evlist;
|
nuclear@4
|
75 demo->evlist = demo->evlist->next;
|
nuclear@2
|
76 free_event(ev);
|
nuclear@2
|
77 }
|
nuclear@2
|
78
|
nuclear@2
|
79 free(demo);
|
nuclear@2
|
80 }
|
nuclear@2
|
81
|
nuclear@2
|
82
|
nuclear@4
|
83 #define SEP " \t\n\r"
|
nuclear@3
|
84
|
nuclear@4
|
85 static int read_script(struct dsys_demo *demo, FILE *fp, const char *fname)
|
nuclear@3
|
86 {
|
nuclear@3
|
87 int nline = 0;
|
nuclear@4
|
88 char buf[512], *line, *tok, *endp;
|
nuclear@4
|
89 unsigned int t0, t1;
|
nuclear@3
|
90 struct dsys_event *ev;
|
nuclear@3
|
91
|
nuclear@4
|
92 if(!fname) {
|
nuclear@4
|
93 fname = "<unknown>";
|
nuclear@4
|
94 }
|
nuclear@4
|
95
|
nuclear@7
|
96 demo->duration = dsys_msec_to_dtime(0);
|
nuclear@7
|
97
|
nuclear@3
|
98 while(fgets(buf, sizeof buf, fp)) {
|
nuclear@3
|
99 nline++;
|
nuclear@3
|
100
|
nuclear@7
|
101 line = strip_ws(buf);
|
nuclear@3
|
102
|
nuclear@3
|
103 if(!line || !*line) {
|
nuclear@3
|
104 continue;
|
nuclear@3
|
105 }
|
nuclear@3
|
106
|
nuclear@4
|
107 if(!(tok = strtok(line, SEP)) || (t0 = strtol(tok, &endp, 10), endp == tok)) {
|
nuclear@4
|
108 fprintf(stderr, "%s line: %d, error: expected timestamp t0\n", fname, nline);
|
nuclear@3
|
109 return -1;
|
nuclear@3
|
110 }
|
nuclear@3
|
111
|
nuclear@3
|
112 if(!(tok = strtok(0, SEP))) {
|
nuclear@4
|
113 fprintf(stderr, "%s line: %d, error: expected second timestamp or event name\n", fname, nline);
|
nuclear@3
|
114 return -1;
|
nuclear@3
|
115 }
|
nuclear@3
|
116
|
nuclear@4
|
117 t1 = strtol(tok, &endp, 10);
|
nuclear@4
|
118 if(endp == tok) {
|
nuclear@4
|
119 t1 = t0;
|
nuclear@4
|
120 } else {
|
nuclear@4
|
121 if(!(tok = strtok(0, SEP))) {
|
nuclear@4
|
122 fprintf(stderr, "%s line: %d, error: expected event name\n", fname, nline);
|
nuclear@4
|
123 return -1;
|
nuclear@4
|
124 }
|
nuclear@4
|
125 }
|
nuclear@4
|
126
|
nuclear@3
|
127 if(!(ev = malloc(sizeof *ev))) {
|
nuclear@3
|
128 perror("read_script: failed to allocate memory for an event\n");
|
nuclear@3
|
129 return -1;
|
nuclear@3
|
130 }
|
nuclear@10
|
131 memset(ev, 0, sizeof *ev);
|
nuclear@7
|
132 ev->t0 = dsys_msec_to_dtime(t0);
|
nuclear@7
|
133 ev->t1 = dsys_msec_to_dtime(t1);
|
nuclear@3
|
134
|
nuclear@3
|
135 if(!(ev->name = malloc(strlen(tok) + 1))) {
|
nuclear@3
|
136 free(ev);
|
nuclear@5
|
137 fprintf(stderr, "read_script: failed to allocate memory for the event name: %s\n", tok);
|
nuclear@3
|
138 return -1;
|
nuclear@3
|
139 }
|
nuclear@4
|
140 strcpy(ev->name, tok);
|
nuclear@4
|
141
|
nuclear@6
|
142 ev->eval = t0 == t1 ? dsys_eval_step : dsys_eval_lerp;
|
nuclear@4
|
143
|
nuclear@4
|
144 ev->next = demo->evlist;
|
nuclear@4
|
145 ev->prev = 0;
|
nuclear@4
|
146 if(demo->evlist) {
|
nuclear@4
|
147 demo->evlist->prev = ev;
|
nuclear@4
|
148 }
|
nuclear@4
|
149 demo->evlist = ev;
|
nuclear@4
|
150 demo->num_ev++;
|
nuclear@7
|
151
|
nuclear@7
|
152 if(ev->t1 > demo->duration) {
|
nuclear@7
|
153 demo->duration = ev->t1;
|
nuclear@7
|
154 }
|
nuclear@3
|
155 }
|
nuclear@3
|
156
|
nuclear@4
|
157 demo->evlist = sort_evlist(demo->evlist, demo->num_ev);
|
nuclear@4
|
158
|
nuclear@10
|
159 /*dbg_print_events(demo->evlist);*/
|
nuclear@7
|
160
|
nuclear@3
|
161 return 0;
|
nuclear@3
|
162 }
|
nuclear@3
|
163
|
nuclear@7
|
164 static char *strip_ws(char *buf)
|
nuclear@7
|
165 {
|
nuclear@7
|
166 char *ptr;
|
nuclear@7
|
167
|
nuclear@7
|
168 while(isspace(*buf)) {
|
nuclear@7
|
169 buf++;
|
nuclear@7
|
170 }
|
nuclear@7
|
171
|
nuclear@7
|
172 ptr = buf;
|
nuclear@7
|
173 while(*ptr) {
|
nuclear@7
|
174 if(*ptr == '\n' || *ptr == '\r' || *ptr == '#') {
|
nuclear@7
|
175 *ptr = 0;
|
nuclear@7
|
176 break;
|
nuclear@7
|
177 }
|
nuclear@7
|
178 ptr++;
|
nuclear@7
|
179 }
|
nuclear@7
|
180
|
nuclear@7
|
181 return buf;
|
nuclear@7
|
182 }
|
nuclear@7
|
183
|
nuclear@7
|
184 static void dbg_print_events(struct dsys_event *ev)
|
nuclear@7
|
185 {
|
nuclear@7
|
186 int i;
|
nuclear@7
|
187
|
nuclear@7
|
188 for(i=0; ev; i++) {
|
nuclear@7
|
189 printf("%02d - %s (%f -> %f) [%s]\n", i, ev->eval == dsys_eval_step ? "step" : "lerp",
|
nuclear@7
|
190 ev->t0, ev->t1, ev->name);
|
nuclear@7
|
191 ev = ev->next;
|
nuclear@7
|
192 }
|
nuclear@7
|
193 }
|
nuclear@3
|
194
|
nuclear@2
|
195 void dsys_update(struct dsys_demo *demo, demotime_t tm)
|
nuclear@2
|
196 {
|
nuclear@6
|
197 struct dsys_event *ev;
|
nuclear@6
|
198
|
nuclear@2
|
199 demo->src_tm = tm;
|
nuclear@2
|
200
|
nuclear@2
|
201 if(demo->start_tm == -1) {
|
nuclear@2
|
202 dsys_start(demo);
|
nuclear@2
|
203 }
|
nuclear@2
|
204
|
nuclear@6
|
205 demo->tm = tm - demo->start_tm - demo->stoppage_tm;
|
nuclear@6
|
206
|
nuclear@7
|
207 if(demo->tm < 0) {
|
nuclear@7
|
208 demo->tm = 0;
|
nuclear@7
|
209 }
|
nuclear@7
|
210 if(demo->tm > demo->duration) {
|
nuclear@7
|
211 demo->tm = demo->duration;
|
nuclear@7
|
212 }
|
nuclear@7
|
213
|
nuclear@9
|
214 if(!demo->running) {
|
nuclear@9
|
215 return; /* nothing changes */
|
nuclear@9
|
216 }
|
nuclear@9
|
217
|
nuclear@10
|
218 while(demo->active && demo->active->t1 <= demo->tm) {
|
nuclear@6
|
219 proc_event(demo->active, demo->tm);
|
nuclear@6
|
220 demo->active = demo->active->next;
|
nuclear@6
|
221 }
|
nuclear@6
|
222
|
nuclear@6
|
223 ev = demo->active;
|
nuclear@7
|
224 while(ev && ev->t0 <= demo->tm) {
|
nuclear@6
|
225 proc_event(ev, demo->tm);
|
nuclear@6
|
226 ev = ev->next;
|
nuclear@6
|
227 }
|
nuclear@6
|
228 demo->nextev = ev;
|
nuclear@7
|
229
|
nuclear@7
|
230
|
nuclear@7
|
231 if(demo->tm >= demo->duration) {
|
nuclear@7
|
232 dsys_stop(demo);
|
nuclear@7
|
233 }
|
nuclear@6
|
234 }
|
nuclear@6
|
235
|
nuclear@6
|
236 static void proc_event(struct dsys_event *ev, demotime_t tm)
|
nuclear@6
|
237 {
|
nuclear@6
|
238 float val = ev->eval(ev, tm);
|
nuclear@6
|
239
|
nuclear@6
|
240 if(ev->val != val) {
|
nuclear@6
|
241 struct callback *cb = ev->cblist;
|
nuclear@6
|
242
|
nuclear@10
|
243 ev->val = val;
|
nuclear@10
|
244
|
nuclear@6
|
245 while(cb) {
|
nuclear@6
|
246 cb->func(ev, cb->cls);
|
nuclear@6
|
247 cb = cb->next;
|
nuclear@6
|
248 }
|
nuclear@6
|
249 }
|
nuclear@2
|
250 }
|
nuclear@2
|
251
|
nuclear@2
|
252 void dsys_start(struct dsys_demo *demo)
|
nuclear@2
|
253 {
|
nuclear@2
|
254 if(demo->running) {
|
nuclear@2
|
255 return;
|
nuclear@2
|
256 }
|
nuclear@2
|
257
|
nuclear@2
|
258 if(demo->start_tm == -1) {
|
nuclear@2
|
259 demo->start_tm = demo->src_tm;
|
nuclear@6
|
260 demo->nextev = demo->active = demo->evlist;
|
nuclear@2
|
261 } else {
|
nuclear@2
|
262 demo->stoppage_tm += demo->src_tm - demo->stop_tm;
|
nuclear@2
|
263 }
|
nuclear@2
|
264
|
nuclear@2
|
265 demo->running = 1;
|
nuclear@2
|
266 }
|
nuclear@2
|
267
|
nuclear@2
|
268 void dsys_stop(struct dsys_demo *demo)
|
nuclear@2
|
269 {
|
nuclear@2
|
270 if(!demo->running) {
|
nuclear@2
|
271 return;
|
nuclear@2
|
272 }
|
nuclear@2
|
273
|
nuclear@2
|
274 demo->stop_tm = demo->src_tm;
|
nuclear@2
|
275 demo->running = 0;
|
nuclear@2
|
276 }
|
nuclear@2
|
277
|
nuclear@2
|
278 int dsys_is_running(struct dsys_demo *demo)
|
nuclear@2
|
279 {
|
nuclear@2
|
280 return demo->running;
|
nuclear@2
|
281 }
|
nuclear@2
|
282
|
nuclear@2
|
283
|
nuclear@2
|
284 demotime_t dsys_duration(struct dsys_demo *demo)
|
nuclear@2
|
285 {
|
nuclear@2
|
286 return demo->duration;
|
nuclear@2
|
287 }
|
nuclear@2
|
288
|
nuclear@2
|
289 demotime_t dsys_time(struct dsys_demo *demo)
|
nuclear@2
|
290 {
|
nuclear@2
|
291 return demo->tm;
|
nuclear@2
|
292 }
|
nuclear@2
|
293
|
nuclear@2
|
294 float dsys_progress(struct dsys_demo *demo)
|
nuclear@2
|
295 {
|
nuclear@2
|
296 return demo->tm / demo->duration;
|
nuclear@2
|
297 }
|
nuclear@2
|
298
|
nuclear@2
|
299 /* seek without continuity */
|
nuclear@2
|
300 void dsys_seek(struct dsys_demo *demo, demotime_t tm)
|
nuclear@2
|
301 {
|
nuclear@8
|
302 struct dsys_event *ev;
|
nuclear@8
|
303
|
nuclear@7
|
304 if(tm < 0) {
|
nuclear@7
|
305 tm = 0;
|
nuclear@7
|
306 }
|
nuclear@7
|
307 if(tm > demo->duration) {
|
nuclear@7
|
308 tm = demo->duration;
|
nuclear@7
|
309 }
|
nuclear@7
|
310
|
nuclear@10
|
311 if(tm < demo->tm) {
|
nuclear@10
|
312 /* on backwards seek, invalidate the sliding window */
|
nuclear@10
|
313 demo->nextev = demo->active = demo->evlist;
|
nuclear@10
|
314 }
|
nuclear@10
|
315
|
nuclear@6
|
316 demo->start_tm = demo->src_tm - tm;
|
nuclear@6
|
317 demo->stoppage_tm = 0;
|
nuclear@10
|
318 demo->stop_tm = demo->src_tm;
|
nuclear@10
|
319 demo->tm = tm;
|
nuclear@8
|
320
|
nuclear@8
|
321 /* recalculate events */
|
nuclear@8
|
322 ev = demo->evlist;
|
nuclear@8
|
323 while(ev) {
|
nuclear@8
|
324 proc_event(ev, tm);
|
nuclear@8
|
325 ev = ev->next;
|
nuclear@8
|
326 }
|
nuclear@2
|
327 }
|
nuclear@2
|
328
|
nuclear@2
|
329 void dsys_seek_norm(struct dsys_demo *demo, float t)
|
nuclear@2
|
330 {
|
nuclear@2
|
331 dsys_seek(demo, t * demo->duration);
|
nuclear@2
|
332 }
|
nuclear@2
|
333
|
nuclear@2
|
334 /* seek by accelerating time */
|
nuclear@6
|
335 void dsys_warp(struct dsys_demo *demo, demotime_t tm)
|
nuclear@6
|
336 {
|
nuclear@6
|
337 fprintf(stderr, "dsys_warp not implemented yet\n");
|
nuclear@6
|
338 }
|
nuclear@6
|
339
|
nuclear@6
|
340 void dsys_warp_norm(struct dsys_demo *demo, float t)
|
nuclear@6
|
341 {
|
nuclear@6
|
342 dsys_warp(demo, t * demo->duration);
|
nuclear@6
|
343 }
|
nuclear@2
|
344
|
nuclear@2
|
345
|
nuclear@2
|
346 /* events */
|
nuclear@5
|
347 struct dsys_event *dsys_event(struct dsys_demo *demo, const char *name)
|
nuclear@5
|
348 {
|
nuclear@5
|
349 struct dsys_event *iter = demo->evlist;
|
nuclear@2
|
350
|
nuclear@5
|
351 while(iter) {
|
nuclear@5
|
352 if(strcmp(iter->name, name) == 0) {
|
nuclear@5
|
353 return iter;
|
nuclear@5
|
354 }
|
nuclear@5
|
355 iter = iter->next;
|
nuclear@5
|
356 }
|
nuclear@5
|
357 return 0;
|
nuclear@5
|
358 }
|
nuclear@2
|
359
|
nuclear@5
|
360 enum dsys_evtype dsys_event_type(struct dsys_event *ev)
|
nuclear@5
|
361 {
|
nuclear@5
|
362 return ev->type;
|
nuclear@5
|
363 }
|
nuclear@5
|
364
|
nuclear@5
|
365 float dsys_event_value(struct dsys_event *ev)
|
nuclear@5
|
366 {
|
nuclear@6
|
367 return ev->val;
|
nuclear@5
|
368 }
|
nuclear@5
|
369
|
nuclear@6
|
370 int dsys_event_callback(struct dsys_event *ev, void (*func)(struct dsys_event*, void*), void *cls)
|
nuclear@5
|
371 {
|
nuclear@6
|
372 struct callback *cb;
|
nuclear@6
|
373
|
nuclear@6
|
374 if(!(cb = malloc(sizeof *cb))) {
|
nuclear@6
|
375 perror("failed to allocate memory");
|
nuclear@6
|
376 return -1;
|
nuclear@6
|
377 }
|
nuclear@6
|
378 cb->func = func;
|
nuclear@6
|
379 cb->cls = cls;
|
nuclear@6
|
380 cb->next = ev->cblist;
|
nuclear@6
|
381 ev->cblist = cb;
|
nuclear@6
|
382 return 0;
|
nuclear@5
|
383 }
|
nuclear@5
|
384
|
nuclear@6
|
385 int dsys_event_link(struct dsys_event *ev, float *link)
|
nuclear@6
|
386 {
|
nuclear@6
|
387 return dsys_event_callback(ev, link_callback, link);
|
nuclear@6
|
388 }
|
nuclear@6
|
389
|
nuclear@6
|
390 static void link_callback(struct dsys_event *ev, void *cls)
|
nuclear@6
|
391 {
|
nuclear@6
|
392 *(float*)cls = ev->val;
|
nuclear@6
|
393 }
|
nuclear@2
|
394
|
nuclear@2
|
395
|
nuclear@2
|
396 /* time conversion */
|
nuclear@2
|
397 demotime_t dsys_sec_to_dtime(float sec)
|
nuclear@2
|
398 {
|
nuclear@2
|
399 return sec;
|
nuclear@2
|
400 }
|
nuclear@2
|
401
|
nuclear@2
|
402 demotime_t dsys_msec_to_dtime(unsigned long msec)
|
nuclear@2
|
403 {
|
nuclear@2
|
404 return (demotime_t)msec / 1000.0;
|
nuclear@2
|
405 }
|
nuclear@2
|
406
|
nuclear@2
|
407 float dsys_dtime_to_sec(demotime_t tm)
|
nuclear@2
|
408 {
|
nuclear@2
|
409 return tm;
|
nuclear@2
|
410 }
|
nuclear@2
|
411
|
nuclear@2
|
412 unsigned long dsys_dtime_to_msec(demotime_t tm)
|
nuclear@2
|
413 {
|
nuclear@2
|
414 return (unsigned long)(tm * 1000.0);
|
nuclear@2
|
415 }
|
nuclear@2
|
416
|
nuclear@2
|
417
|
nuclear@5
|
418 float dsys_eval_step(struct dsys_event *ev, demotime_t t)
|
nuclear@2
|
419 {
|
nuclear@2
|
420 return t >= ev->t1 ? 1.0 : 0.0;
|
nuclear@2
|
421 }
|
nuclear@2
|
422
|
nuclear@7
|
423 #define CLAMP(x, low, high) ((x) < (low) ? (low) : ((x) > (high) ? (high) : (x)))
|
nuclear@7
|
424
|
nuclear@5
|
425 float dsys_eval_lerp(struct dsys_event *ev, demotime_t t)
|
nuclear@2
|
426 {
|
nuclear@7
|
427 float res = (t - ev->t0) / (ev->t1 - ev->t0);
|
nuclear@7
|
428 return CLAMP(res, 0.0, 1.0);
|
nuclear@2
|
429 }
|
nuclear@2
|
430
|
nuclear@5
|
431 float dsys_eval_sigmoid(struct dsys_event *ev, demotime_t t)
|
nuclear@2
|
432 {
|
nuclear@5
|
433 t = dsys_eval_lerp(ev, t);
|
nuclear@2
|
434 return 1.0 - (cos(t * M_PI) * 0.5 + 0.5);
|
nuclear@2
|
435 }
|
nuclear@2
|
436
|
nuclear@2
|
437 static void free_event(struct dsys_event *ev)
|
nuclear@2
|
438 {
|
nuclear@2
|
439 while(ev->cblist) {
|
nuclear@2
|
440 struct callback *cb = ev->cblist;
|
nuclear@2
|
441 ev->cblist = ev->cblist->next;
|
nuclear@2
|
442 free(cb);
|
nuclear@2
|
443 }
|
nuclear@2
|
444 }
|
nuclear@4
|
445
|
nuclear@4
|
446 static struct dsys_event *sort_evlist(struct dsys_event *list, int num_ev)
|
nuclear@4
|
447 {
|
nuclear@4
|
448 int i, num_left, num_right;
|
nuclear@4
|
449 struct dsys_event *left, *right, *node = list;
|
nuclear@4
|
450
|
nuclear@4
|
451 if(num_ev < 2) {
|
nuclear@4
|
452 return list;
|
nuclear@4
|
453 }
|
nuclear@4
|
454
|
nuclear@4
|
455 num_left = num_ev / 2;
|
nuclear@4
|
456 num_right = num_ev - num_left;
|
nuclear@4
|
457
|
nuclear@4
|
458 for(i=0; i<num_ev/2; i++) {
|
nuclear@4
|
459 node = node->next;
|
nuclear@4
|
460 }
|
nuclear@4
|
461
|
nuclear@4
|
462 if(node->prev) {
|
nuclear@4
|
463 node->prev->next = 0;
|
nuclear@4
|
464 node->prev = 0;
|
nuclear@4
|
465 }
|
nuclear@4
|
466
|
nuclear@4
|
467 left = sort_evlist(list, num_left);
|
nuclear@4
|
468 right = sort_evlist(node, num_right);
|
nuclear@4
|
469
|
nuclear@4
|
470 return merge_evlists(left, right);
|
nuclear@4
|
471 }
|
nuclear@4
|
472
|
nuclear@4
|
473 static struct dsys_event *merge_evlists(struct dsys_event *list1, struct dsys_event *list2)
|
nuclear@4
|
474 {
|
nuclear@4
|
475 struct dsys_event *head, *tail, *node;
|
nuclear@4
|
476
|
nuclear@4
|
477 if(!list1) {
|
nuclear@4
|
478 return list2;
|
nuclear@4
|
479 }
|
nuclear@4
|
480 if(!list2) {
|
nuclear@4
|
481 return list1;
|
nuclear@4
|
482 }
|
nuclear@4
|
483
|
nuclear@4
|
484 head = tail = 0;
|
nuclear@4
|
485
|
nuclear@4
|
486 while(list1 && list2) {
|
nuclear@4
|
487 if(list1->t0 < list2->t0) {
|
nuclear@4
|
488 node = list1;
|
nuclear@4
|
489 list1 = list1->next;
|
nuclear@4
|
490 } else {
|
nuclear@4
|
491 node = list2;
|
nuclear@4
|
492 list2 = list2->next;
|
nuclear@4
|
493 }
|
nuclear@4
|
494
|
nuclear@4
|
495 node->next = 0;
|
nuclear@4
|
496 node->prev = tail;
|
nuclear@4
|
497
|
nuclear@4
|
498 if(!head) {
|
nuclear@4
|
499 head = node;
|
nuclear@4
|
500 } else {
|
nuclear@4
|
501 tail->next = node;
|
nuclear@4
|
502 }
|
nuclear@4
|
503 tail = node;
|
nuclear@4
|
504 }
|
nuclear@4
|
505
|
nuclear@4
|
506 if(list1) {
|
nuclear@4
|
507 tail->next = list1;
|
nuclear@4
|
508 list1->prev = tail;
|
nuclear@4
|
509 } else if(list2) {
|
nuclear@4
|
510 tail->next = list2;
|
nuclear@4
|
511 list2->prev = tail;
|
nuclear@4
|
512 }
|
nuclear@4
|
513
|
nuclear@4
|
514 return head;
|
nuclear@4
|
515 }
|