Mercurial > hg > dmlib
view dmtimeline.c @ 327:2964947674d1
More work on the timeline code.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 14 Oct 2012 23:36:06 +0300 |
parents | f2b65aa474c9 |
children | dd7b1356d726 |
line wrap: on
line source
#include "dmtimeline.h" DMEffect *dmEffects = NULL; int ndmEffects = 0, ndmEffectsAlloc = 0; void **dmEffectData = NULL; int dmRegisterEffect(const DMEffect *ef) { if (ef == NULL) return DMERR_NULLPTR; // Allocate more space for effects if (ndmEffects + 1 >= ndmEffectsAlloc) { ndmEffectsAlloc += 16; dmEffects = dmRealloc(dmEffects, sizeof(DMEffect) * ndmEffectsAlloc); if (dmEffects == NULL) { dmError("Could not expand effects structure.\n"); return DMERR_INIT_FAIL; } dmEffectData = dmRealloc(dmEffectData, sizeof(void *) * ndmEffectsAlloc); if (dmEffectData == NULL) { dmError("Could not expand effects data structure.\n"); return DMERR_INIT_FAIL; } } // Copy effects structure memcpy(dmEffects + ndmEffects, ef, sizeof(DMEffect)); dmEffectData[ndmEffects] = NULL; ndmEffects++; return DMERR_OK; } int dmInitializeEffects() { int i, res; for (i = 0; i < ndmEffects; i++) { if (dmEffects[i].init != NULL && (res = dmEffects[i].init(&dmEffectData[i])) != DMERR_OK) return res; } return DMERR_OK; } void dmShutdownEffects() { int i; for (i = 0; i < ndmEffects; i++) { if (dmEffects[i].shutdown != NULL) dmEffects[i].shutdown(dmEffectData[i]); } } DMEffect *dmFindEffect(const char *name, const int nparams) { int i; for (i = 0; i < ndmEffects; i++) { if (strcmp(dmEffects[i].name, name) == 0 && dmEffects[i].nparams == nparams) return &dmEffects[i]; } return NULL; } DMEffect *dmFindEffectByName(const char *name) { int i; for (i = 0; i < ndmEffects; i++) { if (strcmp(dmEffects[i].name, name) == 0) return &dmEffects[i]; } return NULL; } BOOL dmLoadFloatValue(DMResource *res, DMFloat *val) { char tmp[DT_FLOAT_STORE_SIZE + 1]; if (dmf_read_str(res, (Uint8 *) tmp, DT_FLOAT_STORE_SIZE) != DT_FLOAT_STORE_SIZE) return FALSE; tmp[DT_FLOAT_STORE_SIZE] = 0; *val = atof(tmp); return TRUE; } int dmLoadTimelinePoints(DMResource *res, DMTimelinePoints *points) { int point; Uint32 npoints; // Get number of points if (!dmf_read_le32(res, &npoints)) return DMERR_FREAD; // Calculate and allocate space points->npoints = npoints; points->nallocated = ((npoints / 16) + 1) * 16; points->points = dmCalloc(npoints, sizeof(DMTimelinePoint)); if (points->points == NULL) return DMERR_MALLOC; // Read points for (point = 0; point < points->npoints; point++) { DMTimelinePoint *pt = &(points->points[point]); Uint32 ptype, ptime; if (!dmf_read_le32(res, &ptype) || !dmf_read_le32(res, &ptime) || !dmLoadFloatValue(res, &pt->value)) return DMERR_FREAD; pt->type = ptype; pt->time = ptime; } return DMERR_OK; } int dmLoadTimelineEventParam(DMResource *res, DMTimelineEventParam *param) { int err; DMFTimelineEventParam hdr; Uint16 len; Uint32 tmp32; if (dmf_read_str(res, (Uint8 *) &hdr.name, sizeof(hdr.name)) != sizeof(hdr.name) || !dmf_read_le32(res, &hdr.type)) return DMERR_FREAD; hdr.name[sizeof(hdr.name) - 1] = 0; param->name = dm_strdup(hdr.name); param->type = hdr.type; switch (hdr.type) { case EFPT_POINTS: if ((err = dmLoadTimelinePoints(res, ¶m->vpts)) != DMERR_OK) return err; break; case EFPT_INT: if (!dmf_read_le32(res, &tmp32)) return DMERR_FREAD; param->vint = tmp32; break; case EFPT_FLOAT: if (!dmLoadFloatValue(res, ¶m->vfloat)) return DMERR_FREAD; break; case EFPT_STRING: if (!dmf_read_le16(res, &len)) return DMERR_FREAD; param->vstr = dmMalloc((unsigned int)len + 1); if (dmf_read_str(res, (Uint8 *) param->vstr, len) != len) return DMERR_FREAD; param->vstr[len] = 0; break; } return DMERR_OK; } int dmLoadTimelineEvent(DMResource *res, DMTimelineEvent **pevent) { int param; DMFTimelineEvent hdr; DMTimelineEvent *event; if ((*pevent = event = dmMalloc0(sizeof(DMTimelineEvent))) == NULL) return DMERR_MALLOC; // Get basic event data if (!dmf_read_le32(res, &hdr.start) || !dmf_read_le32(res, &hdr.duration) || dmf_read_str(res, (Uint8 *) &hdr.effectName, sizeof(hdr.effectName)) != sizeof(hdr.effectName) || !dmf_read_le32(res, &hdr.nparams)) return DMERR_FREAD; hdr.effectName[sizeof(hdr.effectName) - 1] = 0; if (hdr.nparams > DT_MAX_EFFECT_PARAMS) { dmError("Invalid number of parameters, %d > %d ('%s' @ %d:%d)\n", hdr.nparams, DT_MAX_EFFECT_PARAMS, hdr.effectName, hdr.start, hdr.duration); return DMERR_INVALID_DATA; } event->start = hdr.start; event->duration = hdr.duration; event->nparams = hdr.nparams; event->effect = dmFindEffect(hdr.effectName, hdr.nparams); if (event->effect == NULL) { dmError("No matching registered effect found for '%s'.\n", hdr.effectName); return DMERR_INVALID_DATA; } event->params = dmCalloc(event->nparams, sizeof(DMTimelineEventParam)); if (event->params == NULL) { dmError("Could not allocate memory for timeline event parameters.\n"); return DMERR_MALLOC; } for (param = 0; param < event->nparams; param++) { int err; if ((err = dmLoadTimelineEventParam(res, &(event->params[param]))) != DMERR_OK) return err; } return DMERR_OK; } int dmLoadTimelineCurve(DMResource *res, DMTimelineCurve *curve) { int err; curve->enabled = dmfgetc(res); if ((err = dmLoadTimelinePoints(res, &(curve->points))) != DMERR_OK) return err; return DMERR_OK; } int dmLoadTimelineTrack(DMResource *res, DMTimelineTrack **ptrack) { int event, err; DMFTimelineTrack hdr; DMTimelineTrack *track; if ((*ptrack = track = dmMalloc0(sizeof(DMTimelineTrack))) == NULL) return DMERR_MALLOC; if (dmf_read_str(res, (Uint8 *) &hdr.name, sizeof(hdr.name)) != sizeof(hdr.name)) return DMERR_FREAD; hdr.enabled = dmfgetc(res); if (!dmf_read_le32(res, &hdr.nevents)) return DMERR_FREAD; if (hdr.nevents >= 4096) return DMERR_INVALID_DATA; if ((track->events = dmCalloc(hdr.nevents, sizeof(DMTimelineEvent *))) == NULL) return DMERR_MALLOC; hdr.name[sizeof(hdr.name) - 1] = 0; track->name = dm_strdup(hdr.name); track->enabled = hdr.enabled; track->nevents = hdr.nevents; for (event = 0; event < track->nevents; event++) { if ((err = dmLoadTimelineEvent(res, &(track->events[event]))) != DMERR_OK) return err; } if ((err = dmLoadTimelineCurve(res, &(track->composite))) != DMERR_OK) return err; return DMERR_OK; } int dmLoadTimeline(DMResource *res, DMTimeline **ptl) { int track, err; DMFTimeline hdr; DMTimeline *tl; if ((*ptl = tl = dmMalloc0(sizeof(DMTimeline))) == NULL) return DMERR_MALLOC; // Read and check header if (dmf_read_str(res, (Uint8 *) &hdr.magic, sizeof(hdr.magic)) != sizeof(hdr.magic)) return DMERR_FREAD; if (memcmp(hdr.magic, DT_MAGIC_ID, sizeof(hdr.magic)) != 0) return DMERR_INVALID_DATA; if (dmf_read_str(res, (Uint8 *) &hdr.name, sizeof(hdr.name)) != sizeof(hdr.name) || !dmf_read_le32(res, &hdr.ntracks) || !dmf_read_le32(res, &hdr.duration)) return DMERR_FREAD; if (hdr.ntracks >= 64) return DMERR_INVALID_DATA; // Allocate track pointers tl->tracks = (DMTimelineTrack **) dmCalloc(hdr.ntracks, sizeof(DMTimelineTrack *)); if (tl->tracks == NULL) return DMERR_MALLOC; // Copy rest hdr.name[sizeof(hdr.name) - 1] = 0; tl->name = dm_strdup(hdr.name); tl->duration = hdr.duration; tl->ntracks = hdr.ntracks; // Read tracks for (track = 0; track < tl->ntracks; track++) { if ((err = dmLoadTimelineTrack(res, &(tl->tracks[track]))) != DMERR_OK) return err; } return DMERR_OK; } void dmFreeTimelinePoints(DMTimelinePoints *points) { dmFree(points->points); points->points = NULL; points->npoints = points->nallocated = 0; } void dmFreeTimelineTrack(DMTimelineTrack *track) { if (track != NULL) { dmFree(track->name); track->name = NULL; dmFreeTimelinePoints(&(track->composite.points)); } } void dmFreeTimeline(DMTimeline *tl) { if (tl != NULL) { int i; for (i = 0; i < tl->ntracks; i++) dmFreeTimelineTrack(tl->tracks[i]); dmFree(tl->tracks); dmFree(tl->name); dmFree(tl->pevents); } } /* Prepare a loaded timeline for execution. Creates the "stacked" structure * of timeline data for efficient rendering. */ int dmPrepareTimeline(DMTimeline *tl) { return DMERR_OK; } /* Seeks to specified position in the timeline. The execution function * only handles monotonously increasing time, going backwards will not work * there correctly, thus to seek freely this function must be used. */ int dmSeekTimeline(DMTimeline *tl, int time) { return DMERR_OK; } /* "Executes", or rather renders a frame on the specified timeline position. */ int dmExecuteTimeline(DMTimeline *tl, SDL_Surface *screen, int time) { return DMERR_OK; }