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@2
|
9 static float eval_step(struct dsys_event *ev, demotime_t t);
|
nuclear@2
|
10 static float eval_lerp(struct dsys_event *ev, demotime_t t);
|
nuclear@2
|
11 static float eval_sigmoid(struct dsys_event *ev, demotime_t t);
|
nuclear@2
|
12
|
nuclear@2
|
13 static void free_event(struct dsys_event *ev);
|
nuclear@2
|
14
|
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@2
|
20 struct dsys_demo *res;
|
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@2
|
27 res = dsys_open_stream(fp);
|
nuclear@2
|
28 fclose(fp);
|
nuclear@2
|
29 return res;
|
nuclear@2
|
30 }
|
nuclear@2
|
31
|
nuclear@2
|
32 struct dsys_demo *dsys_open_stream(FILE *fp)
|
nuclear@2
|
33 {
|
nuclear@2
|
34 struct dsys_demo *demo;
|
nuclear@2
|
35
|
nuclear@2
|
36 if(!(demo = malloc(sizeof *demo))) {
|
nuclear@2
|
37 perror("failed to allocate memory");
|
nuclear@2
|
38 return 0;
|
nuclear@2
|
39 }
|
nuclear@2
|
40 memset(demo, 0, sizeof *demo);
|
nuclear@2
|
41
|
nuclear@2
|
42 demo->src_tm = demo->start_tm = -1;
|
nuclear@2
|
43
|
nuclear@3
|
44 if(read_script(demo, fp) == -1) {
|
nuclear@3
|
45 free(demo);
|
nuclear@3
|
46 return 0;
|
nuclear@3
|
47 }
|
nuclear@3
|
48
|
nuclear@2
|
49 return demo;
|
nuclear@2
|
50 }
|
nuclear@2
|
51
|
nuclear@2
|
52 void dsys_close(struct dsys_demo *demo)
|
nuclear@2
|
53 {
|
nuclear@2
|
54 while(demo->ev) {
|
nuclear@2
|
55 struct dsys_event *ev = demo->ev;
|
nuclear@2
|
56 demo->ev = demo->ev->next;
|
nuclear@2
|
57 free_event(ev);
|
nuclear@2
|
58 }
|
nuclear@2
|
59
|
nuclear@2
|
60 free(demo);
|
nuclear@2
|
61 }
|
nuclear@2
|
62
|
nuclear@2
|
63
|
nuclear@3
|
64
|
nuclear@3
|
65 static int read_script(struct dsys_demo *demo, FILE *fp)
|
nuclear@3
|
66 {
|
nuclear@3
|
67 int nline = 0;
|
nuclear@3
|
68 char buf[512], *line, tok;
|
nuclear@3
|
69 int timestamp;
|
nuclear@3
|
70 struct dsys_event *ev;
|
nuclear@3
|
71
|
nuclear@3
|
72 while(fgets(buf, sizeof buf, fp)) {
|
nuclear@3
|
73 nline++;
|
nuclear@3
|
74
|
nuclear@3
|
75 line = buf;/*strip_ws(buf);*/
|
nuclear@3
|
76
|
nuclear@3
|
77 if(!line || !*line) {
|
nuclear@3
|
78 continue;
|
nuclear@3
|
79 }
|
nuclear@3
|
80
|
nuclear@3
|
81 if(!(tok = strtok(line, SEP)) || !isdigit(*tok)) {
|
nuclear@3
|
82 fprintf(stderr, "error reading script at line: %d: expected timestamp\n", nline);
|
nuclear@3
|
83 return -1;
|
nuclear@3
|
84 }
|
nuclear@3
|
85 timestamp = atoi(tok);
|
nuclear@3
|
86
|
nuclear@3
|
87 if(!(tok = strtok(0, SEP))) {
|
nuclear@3
|
88 fprintf(stderr, "error reading script at line: %d: expected event name\n", nline);
|
nuclear@3
|
89 return -1;
|
nuclear@3
|
90 }
|
nuclear@3
|
91
|
nuclear@3
|
92 if(!(ev = malloc(sizeof *ev))) {
|
nuclear@3
|
93 perror("read_script: failed to allocate memory for an event\n");
|
nuclear@3
|
94 return -1;
|
nuclear@3
|
95 }
|
nuclear@3
|
96 ev->t0 = t0;
|
nuclear@3
|
97 ev->t1 = t1;
|
nuclear@3
|
98
|
nuclear@3
|
99 if(!(ev->name = malloc(strlen(tok) + 1))) {
|
nuclear@3
|
100 free(ev);
|
nuclear@3
|
101 sprintf("read_script: failed to allocate memory for the event name: %s\n", tok);
|
nuclear@3
|
102 return -1;
|
nuclear@3
|
103 }
|
nuclear@3
|
104 }
|
nuclear@3
|
105
|
nuclear@3
|
106 return 0;
|
nuclear@3
|
107 }
|
nuclear@3
|
108
|
nuclear@3
|
109
|
nuclear@2
|
110 void dsys_update(struct dsys_demo *demo, demotime_t tm)
|
nuclear@2
|
111 {
|
nuclear@2
|
112 demo->src_tm = tm;
|
nuclear@2
|
113
|
nuclear@2
|
114 if(demo->start_tm == -1) {
|
nuclear@2
|
115 dsys_start(demo);
|
nuclear@2
|
116 }
|
nuclear@2
|
117
|
nuclear@2
|
118 if(demo->running) {
|
nuclear@2
|
119 demo->tm = tm - demo->start_tm - demo->stoppage_tm;
|
nuclear@2
|
120 }
|
nuclear@2
|
121
|
nuclear@2
|
122 /* TODO check the events list etc etc */
|
nuclear@2
|
123 }
|
nuclear@2
|
124
|
nuclear@2
|
125 void dsys_start(struct dsys_demo *demo)
|
nuclear@2
|
126 {
|
nuclear@2
|
127 if(demo->running) {
|
nuclear@2
|
128 return;
|
nuclear@2
|
129 }
|
nuclear@2
|
130
|
nuclear@2
|
131 if(demo->start_tm == -1) {
|
nuclear@2
|
132 demo->start_tm = demo->src_tm;
|
nuclear@2
|
133 } else {
|
nuclear@2
|
134 demo->stoppage_tm += demo->src_tm - demo->stop_tm;
|
nuclear@2
|
135 }
|
nuclear@2
|
136
|
nuclear@2
|
137 demo->running = 1;
|
nuclear@2
|
138 }
|
nuclear@2
|
139
|
nuclear@2
|
140 void dsys_stop(struct dsys_demo *demo)
|
nuclear@2
|
141 {
|
nuclear@2
|
142 if(!demo->running) {
|
nuclear@2
|
143 return;
|
nuclear@2
|
144 }
|
nuclear@2
|
145
|
nuclear@2
|
146 demo->stop_tm = demo->src_tm;
|
nuclear@2
|
147 demo->running = 0;
|
nuclear@2
|
148 }
|
nuclear@2
|
149
|
nuclear@2
|
150 int dsys_is_running(struct dsys_demo *demo)
|
nuclear@2
|
151 {
|
nuclear@2
|
152 return demo->running;
|
nuclear@2
|
153 }
|
nuclear@2
|
154
|
nuclear@2
|
155
|
nuclear@2
|
156 demotime_t dsys_duration(struct dsys_demo *demo)
|
nuclear@2
|
157 {
|
nuclear@2
|
158 return demo->duration;
|
nuclear@2
|
159 }
|
nuclear@2
|
160
|
nuclear@2
|
161 demotime_t dsys_time(struct dsys_demo *demo)
|
nuclear@2
|
162 {
|
nuclear@2
|
163 return demo->tm;
|
nuclear@2
|
164 }
|
nuclear@2
|
165
|
nuclear@2
|
166 float dsys_progress(struct dsys_demo *demo)
|
nuclear@2
|
167 {
|
nuclear@2
|
168 return demo->tm / demo->duration;
|
nuclear@2
|
169 }
|
nuclear@2
|
170
|
nuclear@2
|
171 /* seek without continuity */
|
nuclear@2
|
172 void dsys_seek(struct dsys_demo *demo, demotime_t tm)
|
nuclear@2
|
173 {
|
nuclear@2
|
174 /* TODO */
|
nuclear@2
|
175 }
|
nuclear@2
|
176
|
nuclear@2
|
177 void dsys_seek_norm(struct dsys_demo *demo, float t)
|
nuclear@2
|
178 {
|
nuclear@2
|
179 dsys_seek(demo, t * demo->duration);
|
nuclear@2
|
180 }
|
nuclear@2
|
181
|
nuclear@2
|
182 /* seek by accelerating time */
|
nuclear@2
|
183 void dsys_warp(struct dsys_demo *demo, demotime_t tm);
|
nuclear@2
|
184 void dsys_warp_norm(struct dsys_demo *demo, float t);
|
nuclear@2
|
185
|
nuclear@2
|
186
|
nuclear@2
|
187 /* events */
|
nuclear@2
|
188 struct dsys_event *dsys_event(struct dsys_demo *demo, const char *name);
|
nuclear@2
|
189
|
nuclear@2
|
190 enum dsys_evtype dsys_event_type(struct dsys_event *ev);
|
nuclear@2
|
191 float dsys_event_value(struct dsys_event *ev);
|
nuclear@2
|
192
|
nuclear@2
|
193 void dsys_event_callback(struct dsys_event *ev, void (*func)(void*), void *cls);
|
nuclear@2
|
194 void dsys_event_link(struct dsys_event *ev, float *link);
|
nuclear@2
|
195
|
nuclear@2
|
196
|
nuclear@2
|
197 /* time conversion */
|
nuclear@2
|
198 demotime_t dsys_sec_to_dtime(float sec)
|
nuclear@2
|
199 {
|
nuclear@2
|
200 return sec;
|
nuclear@2
|
201 }
|
nuclear@2
|
202
|
nuclear@2
|
203 demotime_t dsys_msec_to_dtime(unsigned long msec)
|
nuclear@2
|
204 {
|
nuclear@2
|
205 return (demotime_t)msec / 1000.0;
|
nuclear@2
|
206 }
|
nuclear@2
|
207
|
nuclear@2
|
208 float dsys_dtime_to_sec(demotime_t tm)
|
nuclear@2
|
209 {
|
nuclear@2
|
210 return tm;
|
nuclear@2
|
211 }
|
nuclear@2
|
212
|
nuclear@2
|
213 unsigned long dsys_dtime_to_msec(demotime_t tm)
|
nuclear@2
|
214 {
|
nuclear@2
|
215 return (unsigned long)(tm * 1000.0);
|
nuclear@2
|
216 }
|
nuclear@2
|
217
|
nuclear@2
|
218
|
nuclear@2
|
219 static float eval_step(struct dsys_event *ev, demotime_t t)
|
nuclear@2
|
220 {
|
nuclear@2
|
221 return t >= ev->t1 ? 1.0 : 0.0;
|
nuclear@2
|
222 }
|
nuclear@2
|
223
|
nuclear@2
|
224 static float eval_lerp(struct dsys_event *ev, demotime_t t)
|
nuclear@2
|
225 {
|
nuclear@2
|
226 return (t - ev->t0) / (ev->t1 - ev->t0);
|
nuclear@2
|
227 }
|
nuclear@2
|
228
|
nuclear@2
|
229 static float eval_sigmoid(struct dsys_event *ev, demotime_t t)
|
nuclear@2
|
230 {
|
nuclear@2
|
231 t = eval_lerp(ev, t);
|
nuclear@2
|
232 return 1.0 - (cos(t * M_PI) * 0.5 + 0.5);
|
nuclear@2
|
233 }
|
nuclear@2
|
234
|
nuclear@2
|
235 static void free_event(struct dsys_event *ev)
|
nuclear@2
|
236 {
|
nuclear@2
|
237 while(ev->cblist) {
|
nuclear@2
|
238 struct callback *cb = ev->cblist;
|
nuclear@2
|
239 ev->cblist = ev->cblist->next;
|
nuclear@2
|
240 free(cb);
|
nuclear@2
|
241 }
|
nuclear@2
|
242 }
|