nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include "dsys2.h" nuclear@2: #include "dsys_impl.h" nuclear@2: nuclear@2: static float eval_step(struct dsys_event *ev, demotime_t t); nuclear@2: static float eval_lerp(struct dsys_event *ev, demotime_t t); nuclear@2: static float eval_sigmoid(struct dsys_event *ev, demotime_t t); nuclear@2: nuclear@2: static void free_event(struct dsys_event *ev); nuclear@2: nuclear@2: nuclear@2: nuclear@2: struct dsys_demo *dsys_open(const char *fname) nuclear@2: { nuclear@2: FILE *fp; nuclear@2: struct dsys_demo *res; nuclear@2: nuclear@2: if(!(fp = fopen(fname, "r"))) { nuclear@2: fprintf(stderr, "failed to open demoscript: %s: %s\n", fname, strerror(errno)); nuclear@2: return 0; nuclear@2: } nuclear@2: nuclear@2: res = dsys_open_stream(fp); nuclear@2: fclose(fp); nuclear@2: return res; nuclear@2: } nuclear@2: nuclear@2: struct dsys_demo *dsys_open_stream(FILE *fp) nuclear@2: { nuclear@2: struct dsys_demo *demo; nuclear@2: nuclear@2: if(!(demo = malloc(sizeof *demo))) { nuclear@2: perror("failed to allocate memory"); nuclear@2: return 0; nuclear@2: } nuclear@2: memset(demo, 0, sizeof *demo); nuclear@2: nuclear@2: demo->src_tm = demo->start_tm = -1; nuclear@2: nuclear@2: /* TODO */ nuclear@2: return demo; nuclear@2: } nuclear@2: nuclear@2: void dsys_close(struct dsys_demo *demo) nuclear@2: { nuclear@2: while(demo->ev) { nuclear@2: struct dsys_event *ev = demo->ev; nuclear@2: demo->ev = demo->ev->next; nuclear@2: free_event(ev); nuclear@2: } nuclear@2: nuclear@2: free(demo); nuclear@2: } nuclear@2: nuclear@2: nuclear@2: void dsys_update(struct dsys_demo *demo, demotime_t tm) nuclear@2: { nuclear@2: demo->src_tm = tm; nuclear@2: nuclear@2: if(demo->start_tm == -1) { nuclear@2: dsys_start(demo); nuclear@2: } nuclear@2: nuclear@2: if(demo->running) { nuclear@2: demo->tm = tm - demo->start_tm - demo->stoppage_tm; nuclear@2: } nuclear@2: nuclear@2: /* TODO check the events list etc etc */ nuclear@2: } nuclear@2: nuclear@2: void dsys_start(struct dsys_demo *demo) nuclear@2: { nuclear@2: if(demo->running) { nuclear@2: return; nuclear@2: } nuclear@2: nuclear@2: if(demo->start_tm == -1) { nuclear@2: demo->start_tm = demo->src_tm; nuclear@2: } else { nuclear@2: demo->stoppage_tm += demo->src_tm - demo->stop_tm; nuclear@2: } nuclear@2: nuclear@2: demo->running = 1; nuclear@2: } nuclear@2: nuclear@2: void dsys_stop(struct dsys_demo *demo) nuclear@2: { nuclear@2: if(!demo->running) { nuclear@2: return; nuclear@2: } nuclear@2: nuclear@2: demo->stop_tm = demo->src_tm; nuclear@2: demo->running = 0; nuclear@2: } nuclear@2: nuclear@2: int dsys_is_running(struct dsys_demo *demo) nuclear@2: { nuclear@2: return demo->running; nuclear@2: } nuclear@2: nuclear@2: nuclear@2: demotime_t dsys_duration(struct dsys_demo *demo) nuclear@2: { nuclear@2: return demo->duration; nuclear@2: } nuclear@2: nuclear@2: demotime_t dsys_time(struct dsys_demo *demo) nuclear@2: { nuclear@2: return demo->tm; nuclear@2: } nuclear@2: nuclear@2: float dsys_progress(struct dsys_demo *demo) nuclear@2: { nuclear@2: return demo->tm / demo->duration; nuclear@2: } nuclear@2: nuclear@2: /* seek without continuity */ nuclear@2: void dsys_seek(struct dsys_demo *demo, demotime_t tm) nuclear@2: { nuclear@2: /* TODO */ nuclear@2: } nuclear@2: nuclear@2: void dsys_seek_norm(struct dsys_demo *demo, float t) nuclear@2: { nuclear@2: dsys_seek(demo, t * demo->duration); nuclear@2: } nuclear@2: nuclear@2: /* seek by accelerating time */ nuclear@2: void dsys_warp(struct dsys_demo *demo, demotime_t tm); nuclear@2: void dsys_warp_norm(struct dsys_demo *demo, float t); nuclear@2: nuclear@2: nuclear@2: /* events */ nuclear@2: struct dsys_event *dsys_event(struct dsys_demo *demo, const char *name); nuclear@2: nuclear@2: enum dsys_evtype dsys_event_type(struct dsys_event *ev); nuclear@2: float dsys_event_value(struct dsys_event *ev); nuclear@2: nuclear@2: void dsys_event_callback(struct dsys_event *ev, void (*func)(void*), void *cls); nuclear@2: void dsys_event_link(struct dsys_event *ev, float *link); nuclear@2: nuclear@2: nuclear@2: /* time conversion */ nuclear@2: demotime_t dsys_sec_to_dtime(float sec) nuclear@2: { nuclear@2: return sec; nuclear@2: } nuclear@2: nuclear@2: demotime_t dsys_msec_to_dtime(unsigned long msec) nuclear@2: { nuclear@2: return (demotime_t)msec / 1000.0; nuclear@2: } nuclear@2: nuclear@2: float dsys_dtime_to_sec(demotime_t tm) nuclear@2: { nuclear@2: return tm; nuclear@2: } nuclear@2: nuclear@2: unsigned long dsys_dtime_to_msec(demotime_t tm) nuclear@2: { nuclear@2: return (unsigned long)(tm * 1000.0); nuclear@2: } nuclear@2: nuclear@2: nuclear@2: static float eval_step(struct dsys_event *ev, demotime_t t) nuclear@2: { nuclear@2: return t >= ev->t1 ? 1.0 : 0.0; nuclear@2: } nuclear@2: nuclear@2: static float eval_lerp(struct dsys_event *ev, demotime_t t) nuclear@2: { nuclear@2: return (t - ev->t0) / (ev->t1 - ev->t0); nuclear@2: } nuclear@2: nuclear@2: static float eval_sigmoid(struct dsys_event *ev, demotime_t t) nuclear@2: { nuclear@2: t = eval_lerp(ev, t); nuclear@2: return 1.0 - (cos(t * M_PI) * 0.5 + 0.5); nuclear@2: } nuclear@2: nuclear@2: static void free_event(struct dsys_event *ev) nuclear@2: { nuclear@2: while(ev->cblist) { nuclear@2: struct callback *cb = ev->cblist; nuclear@2: ev->cblist = ev->cblist->next; nuclear@2: free(cb); nuclear@2: } nuclear@2: }