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@7
|
131 ev->t0 = dsys_msec_to_dtime(t0);
|
nuclear@7
|
132 ev->t1 = dsys_msec_to_dtime(t1);
|
nuclear@3
|
133
|
nuclear@3
|
134 if(!(ev->name = malloc(strlen(tok) + 1))) {
|
nuclear@3
|
135 free(ev);
|
nuclear@5
|
136 fprintf(stderr, "read_script: failed to allocate memory for the event name: %s\n", tok);
|
nuclear@3
|
137 return -1;
|
nuclear@3
|
138 }
|
nuclear@4
|
139 strcpy(ev->name, tok);
|
nuclear@4
|
140
|
nuclear@6
|
141 ev->eval = t0 == t1 ? dsys_eval_step : dsys_eval_lerp;
|
nuclear@4
|
142
|
nuclear@4
|
143 ev->next = demo->evlist;
|
nuclear@4
|
144 ev->prev = 0;
|
nuclear@4
|
145 if(demo->evlist) {
|
nuclear@4
|
146 demo->evlist->prev = ev;
|
nuclear@4
|
147 }
|
nuclear@4
|
148 demo->evlist = ev;
|
nuclear@4
|
149 demo->num_ev++;
|
nuclear@7
|
150
|
nuclear@7
|
151 if(ev->t1 > demo->duration) {
|
nuclear@7
|
152 demo->duration = ev->t1;
|
nuclear@7
|
153 }
|
nuclear@3
|
154 }
|
nuclear@3
|
155
|
nuclear@4
|
156 demo->evlist = sort_evlist(demo->evlist, demo->num_ev);
|
nuclear@4
|
157
|
nuclear@7
|
158 dbg_print_events(demo->evlist);
|
nuclear@7
|
159
|
nuclear@3
|
160 return 0;
|
nuclear@3
|
161 }
|
nuclear@3
|
162
|
nuclear@7
|
163 static char *strip_ws(char *buf)
|
nuclear@7
|
164 {
|
nuclear@7
|
165 char *ptr;
|
nuclear@7
|
166
|
nuclear@7
|
167 while(isspace(*buf)) {
|
nuclear@7
|
168 buf++;
|
nuclear@7
|
169 }
|
nuclear@7
|
170
|
nuclear@7
|
171 ptr = buf;
|
nuclear@7
|
172 while(*ptr) {
|
nuclear@7
|
173 if(*ptr == '\n' || *ptr == '\r' || *ptr == '#') {
|
nuclear@7
|
174 *ptr = 0;
|
nuclear@7
|
175 break;
|
nuclear@7
|
176 }
|
nuclear@7
|
177 ptr++;
|
nuclear@7
|
178 }
|
nuclear@7
|
179
|
nuclear@7
|
180 return buf;
|
nuclear@7
|
181 }
|
nuclear@7
|
182
|
nuclear@7
|
183 static void dbg_print_events(struct dsys_event *ev)
|
nuclear@7
|
184 {
|
nuclear@7
|
185 int i;
|
nuclear@7
|
186
|
nuclear@7
|
187 for(i=0; ev; i++) {
|
nuclear@7
|
188 printf("%02d - %s (%f -> %f) [%s]\n", i, ev->eval == dsys_eval_step ? "step" : "lerp",
|
nuclear@7
|
189 ev->t0, ev->t1, ev->name);
|
nuclear@7
|
190 ev = ev->next;
|
nuclear@7
|
191 }
|
nuclear@7
|
192 }
|
nuclear@3
|
193
|
nuclear@2
|
194 void dsys_update(struct dsys_demo *demo, demotime_t tm)
|
nuclear@2
|
195 {
|
nuclear@6
|
196 struct dsys_event *ev;
|
nuclear@6
|
197
|
nuclear@2
|
198 demo->src_tm = tm;
|
nuclear@2
|
199
|
nuclear@2
|
200 if(demo->start_tm == -1) {
|
nuclear@2
|
201 dsys_start(demo);
|
nuclear@2
|
202 }
|
nuclear@2
|
203
|
nuclear@6
|
204 if(!demo->running) {
|
nuclear@6
|
205 return; /* nothing changes */
|
nuclear@2
|
206 }
|
nuclear@2
|
207
|
nuclear@6
|
208 demo->tm = tm - demo->start_tm - demo->stoppage_tm;
|
nuclear@6
|
209
|
nuclear@7
|
210 if(demo->tm < 0) {
|
nuclear@7
|
211 demo->tm = 0;
|
nuclear@7
|
212 }
|
nuclear@7
|
213 if(demo->tm > demo->duration) {
|
nuclear@7
|
214 demo->tm = demo->duration;
|
nuclear@7
|
215 }
|
nuclear@7
|
216
|
nuclear@6
|
217 while(demo->active->t1 < demo->tm) {
|
nuclear@6
|
218 proc_event(demo->active, demo->tm);
|
nuclear@6
|
219 demo->active = demo->active->next;
|
nuclear@6
|
220 }
|
nuclear@6
|
221
|
nuclear@6
|
222 ev = demo->active;
|
nuclear@7
|
223 while(ev && ev->t0 <= demo->tm) {
|
nuclear@6
|
224 proc_event(ev, demo->tm);
|
nuclear@6
|
225 ev = ev->next;
|
nuclear@6
|
226 }
|
nuclear@6
|
227 demo->nextev = ev;
|
nuclear@7
|
228
|
nuclear@7
|
229
|
nuclear@7
|
230 if(demo->tm >= demo->duration) {
|
nuclear@7
|
231 dsys_stop(demo);
|
nuclear@7
|
232 }
|
nuclear@6
|
233 }
|
nuclear@6
|
234
|
nuclear@6
|
235 static void proc_event(struct dsys_event *ev, demotime_t tm)
|
nuclear@6
|
236 {
|
nuclear@6
|
237 float val = ev->eval(ev, tm);
|
nuclear@6
|
238
|
nuclear@6
|
239 if(ev->val != val) {
|
nuclear@6
|
240 struct callback *cb = ev->cblist;
|
nuclear@6
|
241
|
nuclear@6
|
242 while(cb) {
|
nuclear@6
|
243 cb->func(ev, cb->cls);
|
nuclear@6
|
244 cb = cb->next;
|
nuclear@6
|
245 }
|
nuclear@6
|
246 ev->val = val;
|
nuclear@6
|
247 }
|
nuclear@2
|
248 }
|
nuclear@2
|
249
|
nuclear@2
|
250 void dsys_start(struct dsys_demo *demo)
|
nuclear@2
|
251 {
|
nuclear@2
|
252 if(demo->running) {
|
nuclear@2
|
253 return;
|
nuclear@2
|
254 }
|
nuclear@2
|
255
|
nuclear@2
|
256 if(demo->start_tm == -1) {
|
nuclear@2
|
257 demo->start_tm = demo->src_tm;
|
nuclear@6
|
258 demo->nextev = demo->active = demo->evlist;
|
nuclear@2
|
259 } else {
|
nuclear@2
|
260 demo->stoppage_tm += demo->src_tm - demo->stop_tm;
|
nuclear@2
|
261 }
|
nuclear@2
|
262
|
nuclear@2
|
263 demo->running = 1;
|
nuclear@2
|
264 }
|
nuclear@2
|
265
|
nuclear@2
|
266 void dsys_stop(struct dsys_demo *demo)
|
nuclear@2
|
267 {
|
nuclear@2
|
268 if(!demo->running) {
|
nuclear@2
|
269 return;
|
nuclear@2
|
270 }
|
nuclear@2
|
271
|
nuclear@2
|
272 demo->stop_tm = demo->src_tm;
|
nuclear@2
|
273 demo->running = 0;
|
nuclear@2
|
274 }
|
nuclear@2
|
275
|
nuclear@2
|
276 int dsys_is_running(struct dsys_demo *demo)
|
nuclear@2
|
277 {
|
nuclear@2
|
278 return demo->running;
|
nuclear@2
|
279 }
|
nuclear@2
|
280
|
nuclear@2
|
281
|
nuclear@2
|
282 demotime_t dsys_duration(struct dsys_demo *demo)
|
nuclear@2
|
283 {
|
nuclear@2
|
284 return demo->duration;
|
nuclear@2
|
285 }
|
nuclear@2
|
286
|
nuclear@2
|
287 demotime_t dsys_time(struct dsys_demo *demo)
|
nuclear@2
|
288 {
|
nuclear@2
|
289 return demo->tm;
|
nuclear@2
|
290 }
|
nuclear@2
|
291
|
nuclear@2
|
292 float dsys_progress(struct dsys_demo *demo)
|
nuclear@2
|
293 {
|
nuclear@2
|
294 return demo->tm / demo->duration;
|
nuclear@2
|
295 }
|
nuclear@2
|
296
|
nuclear@2
|
297 /* seek without continuity */
|
nuclear@2
|
298 void dsys_seek(struct dsys_demo *demo, demotime_t tm)
|
nuclear@2
|
299 {
|
nuclear@7
|
300 if(tm < 0) {
|
nuclear@7
|
301 tm = 0;
|
nuclear@7
|
302 }
|
nuclear@7
|
303 if(tm > demo->duration) {
|
nuclear@7
|
304 tm = demo->duration;
|
nuclear@7
|
305 }
|
nuclear@7
|
306
|
nuclear@6
|
307 demo->start_tm = demo->src_tm - tm;
|
nuclear@6
|
308 demo->stoppage_tm = 0;
|
nuclear@2
|
309 }
|
nuclear@2
|
310
|
nuclear@2
|
311 void dsys_seek_norm(struct dsys_demo *demo, float t)
|
nuclear@2
|
312 {
|
nuclear@2
|
313 dsys_seek(demo, t * demo->duration);
|
nuclear@2
|
314 }
|
nuclear@2
|
315
|
nuclear@2
|
316 /* seek by accelerating time */
|
nuclear@6
|
317 void dsys_warp(struct dsys_demo *demo, demotime_t tm)
|
nuclear@6
|
318 {
|
nuclear@6
|
319 fprintf(stderr, "dsys_warp not implemented yet\n");
|
nuclear@6
|
320 }
|
nuclear@6
|
321
|
nuclear@6
|
322 void dsys_warp_norm(struct dsys_demo *demo, float t)
|
nuclear@6
|
323 {
|
nuclear@6
|
324 dsys_warp(demo, t * demo->duration);
|
nuclear@6
|
325 }
|
nuclear@2
|
326
|
nuclear@2
|
327
|
nuclear@2
|
328 /* events */
|
nuclear@5
|
329 struct dsys_event *dsys_event(struct dsys_demo *demo, const char *name)
|
nuclear@5
|
330 {
|
nuclear@5
|
331 struct dsys_event *iter = demo->evlist;
|
nuclear@2
|
332
|
nuclear@5
|
333 while(iter) {
|
nuclear@5
|
334 if(strcmp(iter->name, name) == 0) {
|
nuclear@5
|
335 return iter;
|
nuclear@5
|
336 }
|
nuclear@5
|
337 iter = iter->next;
|
nuclear@5
|
338 }
|
nuclear@5
|
339 return 0;
|
nuclear@5
|
340 }
|
nuclear@2
|
341
|
nuclear@5
|
342 enum dsys_evtype dsys_event_type(struct dsys_event *ev)
|
nuclear@5
|
343 {
|
nuclear@5
|
344 return ev->type;
|
nuclear@5
|
345 }
|
nuclear@5
|
346
|
nuclear@5
|
347 float dsys_event_value(struct dsys_event *ev)
|
nuclear@5
|
348 {
|
nuclear@6
|
349 return ev->val;
|
nuclear@5
|
350 }
|
nuclear@5
|
351
|
nuclear@6
|
352 int dsys_event_callback(struct dsys_event *ev, void (*func)(struct dsys_event*, void*), void *cls)
|
nuclear@5
|
353 {
|
nuclear@6
|
354 struct callback *cb;
|
nuclear@6
|
355
|
nuclear@6
|
356 if(!(cb = malloc(sizeof *cb))) {
|
nuclear@6
|
357 perror("failed to allocate memory");
|
nuclear@6
|
358 return -1;
|
nuclear@6
|
359 }
|
nuclear@6
|
360 cb->func = func;
|
nuclear@6
|
361 cb->cls = cls;
|
nuclear@6
|
362 cb->next = ev->cblist;
|
nuclear@6
|
363 ev->cblist = cb;
|
nuclear@6
|
364 return 0;
|
nuclear@5
|
365 }
|
nuclear@5
|
366
|
nuclear@6
|
367 int dsys_event_link(struct dsys_event *ev, float *link)
|
nuclear@6
|
368 {
|
nuclear@6
|
369 return dsys_event_callback(ev, link_callback, link);
|
nuclear@6
|
370 }
|
nuclear@6
|
371
|
nuclear@6
|
372 static void link_callback(struct dsys_event *ev, void *cls)
|
nuclear@6
|
373 {
|
nuclear@6
|
374 *(float*)cls = ev->val;
|
nuclear@6
|
375 }
|
nuclear@2
|
376
|
nuclear@2
|
377
|
nuclear@2
|
378 /* time conversion */
|
nuclear@2
|
379 demotime_t dsys_sec_to_dtime(float sec)
|
nuclear@2
|
380 {
|
nuclear@2
|
381 return sec;
|
nuclear@2
|
382 }
|
nuclear@2
|
383
|
nuclear@2
|
384 demotime_t dsys_msec_to_dtime(unsigned long msec)
|
nuclear@2
|
385 {
|
nuclear@2
|
386 return (demotime_t)msec / 1000.0;
|
nuclear@2
|
387 }
|
nuclear@2
|
388
|
nuclear@2
|
389 float dsys_dtime_to_sec(demotime_t tm)
|
nuclear@2
|
390 {
|
nuclear@2
|
391 return tm;
|
nuclear@2
|
392 }
|
nuclear@2
|
393
|
nuclear@2
|
394 unsigned long dsys_dtime_to_msec(demotime_t tm)
|
nuclear@2
|
395 {
|
nuclear@2
|
396 return (unsigned long)(tm * 1000.0);
|
nuclear@2
|
397 }
|
nuclear@2
|
398
|
nuclear@2
|
399
|
nuclear@5
|
400 float dsys_eval_step(struct dsys_event *ev, demotime_t t)
|
nuclear@2
|
401 {
|
nuclear@2
|
402 return t >= ev->t1 ? 1.0 : 0.0;
|
nuclear@2
|
403 }
|
nuclear@2
|
404
|
nuclear@7
|
405 #define CLAMP(x, low, high) ((x) < (low) ? (low) : ((x) > (high) ? (high) : (x)))
|
nuclear@7
|
406
|
nuclear@5
|
407 float dsys_eval_lerp(struct dsys_event *ev, demotime_t t)
|
nuclear@2
|
408 {
|
nuclear@7
|
409 float res = (t - ev->t0) / (ev->t1 - ev->t0);
|
nuclear@7
|
410 return CLAMP(res, 0.0, 1.0);
|
nuclear@2
|
411 }
|
nuclear@2
|
412
|
nuclear@5
|
413 float dsys_eval_sigmoid(struct dsys_event *ev, demotime_t t)
|
nuclear@2
|
414 {
|
nuclear@5
|
415 t = dsys_eval_lerp(ev, t);
|
nuclear@2
|
416 return 1.0 - (cos(t * M_PI) * 0.5 + 0.5);
|
nuclear@2
|
417 }
|
nuclear@2
|
418
|
nuclear@2
|
419 static void free_event(struct dsys_event *ev)
|
nuclear@2
|
420 {
|
nuclear@2
|
421 while(ev->cblist) {
|
nuclear@2
|
422 struct callback *cb = ev->cblist;
|
nuclear@2
|
423 ev->cblist = ev->cblist->next;
|
nuclear@2
|
424 free(cb);
|
nuclear@2
|
425 }
|
nuclear@2
|
426 }
|
nuclear@4
|
427
|
nuclear@4
|
428 static struct dsys_event *sort_evlist(struct dsys_event *list, int num_ev)
|
nuclear@4
|
429 {
|
nuclear@4
|
430 int i, num_left, num_right;
|
nuclear@4
|
431 struct dsys_event *left, *right, *node = list;
|
nuclear@4
|
432
|
nuclear@4
|
433 if(num_ev < 2) {
|
nuclear@4
|
434 return list;
|
nuclear@4
|
435 }
|
nuclear@4
|
436
|
nuclear@4
|
437 num_left = num_ev / 2;
|
nuclear@4
|
438 num_right = num_ev - num_left;
|
nuclear@4
|
439
|
nuclear@4
|
440 for(i=0; i<num_ev/2; i++) {
|
nuclear@4
|
441 node = node->next;
|
nuclear@4
|
442 }
|
nuclear@4
|
443
|
nuclear@4
|
444 if(node->prev) {
|
nuclear@4
|
445 node->prev->next = 0;
|
nuclear@4
|
446 node->prev = 0;
|
nuclear@4
|
447 }
|
nuclear@4
|
448
|
nuclear@4
|
449 left = sort_evlist(list, num_left);
|
nuclear@4
|
450 right = sort_evlist(node, num_right);
|
nuclear@4
|
451
|
nuclear@4
|
452 return merge_evlists(left, right);
|
nuclear@4
|
453 }
|
nuclear@4
|
454
|
nuclear@4
|
455 static struct dsys_event *merge_evlists(struct dsys_event *list1, struct dsys_event *list2)
|
nuclear@4
|
456 {
|
nuclear@4
|
457 struct dsys_event *head, *tail, *node;
|
nuclear@4
|
458
|
nuclear@4
|
459 if(!list1) {
|
nuclear@4
|
460 return list2;
|
nuclear@4
|
461 }
|
nuclear@4
|
462 if(!list2) {
|
nuclear@4
|
463 return list1;
|
nuclear@4
|
464 }
|
nuclear@4
|
465
|
nuclear@4
|
466 head = tail = 0;
|
nuclear@4
|
467
|
nuclear@4
|
468 while(list1 && list2) {
|
nuclear@4
|
469 if(list1->t0 < list2->t0) {
|
nuclear@4
|
470 node = list1;
|
nuclear@4
|
471 list1 = list1->next;
|
nuclear@4
|
472 } else {
|
nuclear@4
|
473 node = list2;
|
nuclear@4
|
474 list2 = list2->next;
|
nuclear@4
|
475 }
|
nuclear@4
|
476
|
nuclear@4
|
477 node->next = 0;
|
nuclear@4
|
478 node->prev = tail;
|
nuclear@4
|
479
|
nuclear@4
|
480 if(!head) {
|
nuclear@4
|
481 head = node;
|
nuclear@4
|
482 } else {
|
nuclear@4
|
483 tail->next = node;
|
nuclear@4
|
484 }
|
nuclear@4
|
485 tail = node;
|
nuclear@4
|
486 }
|
nuclear@4
|
487
|
nuclear@4
|
488 if(list1) {
|
nuclear@4
|
489 tail->next = list1;
|
nuclear@4
|
490 list1->prev = tail;
|
nuclear@4
|
491 } else if(list2) {
|
nuclear@4
|
492 tail->next = list2;
|
nuclear@4
|
493 list2->prev = tail;
|
nuclear@4
|
494 }
|
nuclear@4
|
495
|
nuclear@4
|
496 return head;
|
nuclear@4
|
497 }
|