# HG changeset patch # User Matti Hamalainen # Date 1350246966 -10800 # Node ID 2964947674d189b0e29f6de5982bbba240c090d7 # Parent 9cc4c6c52938362ecf207763829572388cdb4d80 More work on the timeline code. diff -r 9cc4c6c52938 -r 2964947674d1 dmtimeline.c --- a/dmtimeline.c Sun Oct 14 23:35:57 2012 +0300 +++ b/dmtimeline.c Sun Oct 14 23:36:06 2012 +0300 @@ -78,6 +78,18 @@ } +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]; @@ -126,23 +138,25 @@ 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)) + 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; - if (!dmf_read_le32(res, &hdr.type)) - return DMERR_FREAD; - 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: @@ -181,24 +195,22 @@ return DMERR_MALLOC; // Get basic event data - if (!dmf_read_le32(res, &hdr.startTime)) - return DMERR_FREAD; - if (!dmf_read_le32(res, &hdr.duration)) + 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; - if (dmf_read_str(res, (Uint8 *) &hdr.effectName, sizeof(hdr.effectName)) != sizeof(hdr.effectName)) - return DMERR_FREAD; + hdr.effectName[sizeof(hdr.effectName) - 1] = 0; - if (!dmf_read_le32(res, &hdr.nparams)) - return DMERR_FREAD; 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.startTime, hdr.duration); + hdr.nparams, DT_MAX_EFFECT_PARAMS, hdr.effectName, hdr.start, hdr.duration); return DMERR_INVALID_DATA; } - event->startTime = hdr.startTime; + event->start = hdr.start; event->duration = hdr.duration; event->nparams = hdr.nparams; event->effect = dmFindEffect(hdr.effectName, hdr.nparams); @@ -289,16 +301,12 @@ if (dmf_read_str(res, (Uint8 *) &hdr.magic, sizeof(hdr.magic)) != sizeof(hdr.magic)) return DMERR_FREAD; - if (memcmp(hdr.magic, "SDMETLNE", sizeof(hdr.magic)) != 0) + 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)) - return DMERR_FREAD; - - if (!dmf_read_le32(res, &hdr.ntracks)) - return DMERR_FREAD; - - if (!dmf_read_le32(res, &hdr.duration)) + 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) diff -r 9cc4c6c52938 -r 2964947674d1 dmtimeline.h --- a/dmtimeline.h Sun Oct 14 23:35:57 2012 +0300 +++ b/dmtimeline.h Sun Oct 14 23:36:06 2012 +0300 @@ -8,7 +8,7 @@ extern "C" { #endif - +#define DT_MAGIC_ID "SDMETLNE" #define DT_MAX_EFFECT_PARAMS 16 #define DT_MAX_NAME_LENGTH 32 #define DT_FLOAT_STORE_SIZE 16 @@ -53,10 +53,7 @@ char *vstr; int vint; DMFloat vfloat; - DMTimelinePoints vpoints; - - // Execution related - DMLerpContext lerp; + DMTimelinePoints vpts; } DMTimelineEventParam; @@ -83,7 +80,7 @@ typedef struct { - Uint32 startTime, duration; + Uint32 start, duration; char effectName[DT_MAX_NAME_LENGTH]; Uint32 nparams; } DMFTimelineEvent; @@ -91,7 +88,7 @@ typedef struct { - int startTime, duration; + int start, duration; DMEffect *effect; int nparams; DMTimelineEventParam *params; @@ -118,10 +115,10 @@ char *name; // Name of the timeline track BOOL enabled; // Enabled? - int nevents; // Number of events + int nevents, nallocated; // Number of events DMTimelineEvent **events; // Events - DMTimelineCurve composite; // Composite curve (transparency of the "layer") + DMTimelineCurve composite; // Composite curve (transparency of the "layer") } DMTimelineTrack; @@ -151,7 +148,7 @@ typedef struct { char *name; - int ntracks, duration; + int ntracks, nallocated, duration; DMTimelineTrack **tracks; // Prepared data @@ -168,17 +165,33 @@ int dmRegisterEffect(const DMEffect *ef); int dmInitializeEffects(); void dmShutdownEffects(); +DMEffect *dmFindEffect(const char *name, const int nparams); +DMEffect *dmFindEffectByName(const char *name); + int dmLoadTimeline(DMResource *res, DMTimeline **tl); -int dmSaveTimeline(DMResource *res, DMTimeline *tl); void dmFreeTimeline(DMTimeline *tl); +// Execution related int dmPrepareTimeline(DMTimeline *tl); int dmSeekTimeline(DMTimeline *tl, int time); int dmExecuteTimeline(DMTimeline *tl, SDL_Surface *screen, int time); +// Editing/saving related functions +int dmSaveTimeline(DMResource *res, DMTimeline *tl); + +int dmTimelineNew(DMTimeline **tl, const char *name); +int dmTimelineAddTrack(DMTimeline *tl, DMTimelineTrack **track, const char *name); +int dmTimelineTrackAddEvent(DMTimelineTrack *track, int start, int duration, DMTimelineEvent **pev); +int dmTimelineEventSetEffect(DMTimelineEvent *event, const char *name); + +DMTimelineEvent *dmTimelineGetEventAt(DMTimelineTrack *track, int time); + + + + #ifdef __cplusplus } #endif diff -r 9cc4c6c52938 -r 2964947674d1 dmtimelinew.c --- a/dmtimelinew.c Sun Oct 14 23:35:57 2012 +0300 +++ b/dmtimelinew.c Sun Oct 14 23:36:06 2012 +0300 @@ -1,4 +1,286 @@ #include "dmtimeline.h" +#include "dmresw.h" + + +BOOL dmSaveFloatValue(DMResource *res, DMFloat val) +{ + char tmp[DT_FLOAT_STORE_SIZE]; + snprintf(tmp, DT_FLOAT_STORE_SIZE, "%f", val); + return (dmf_write_str(res, (Uint8 *) tmp, DT_FLOAT_STORE_SIZE) == DT_FLOAT_STORE_SIZE); +} + + +int dmSaveTimelinePoints(DMResource *res, DMTimelinePoints *points) +{ + int point; + Uint32 npoints; + + // Save number of points + npoints = points->npoints; + if (!dmf_write_le32(res, npoints)) + return DMERR_FWRITE; + + // Save points + for (point = 0; point < points->npoints; point++) + { + DMTimelinePoint *pt = &(points->points[point]); + Uint32 ptype, ptime; + ptype = pt->type; + ptime = pt->time; + if (!dmf_write_le32(res, ptype) || + !dmf_write_le32(res, ptime) || + !dmSaveFloatValue(res, pt->value)) + return DMERR_FWRITE; + } + return DMERR_OK; +} + + +int dmSaveTimelineCurve(DMResource *res, DMTimelineCurve *curve) +{ + int err; + + dmfputc(curve->enabled, res); + if ((err = dmSaveTimelinePoints(res, &(curve->points))) != DMERR_OK) + return err; + + return DMERR_OK; +} + + +int dmSaveTimelineEventParam(DMResource *res, DMTimelineEventParam *param) +{ + int err; + DMFTimelineEventParam hdr; + Uint16 len; + Uint32 tmp32; + + strncpy(hdr.name, param->name, sizeof(hdr.name)); + hdr.type = param->type; + + if (dmf_write_str(res, (Uint8 *) hdr.name, sizeof(hdr.name)) != sizeof(hdr.name) || + !dmf_write_le32(res, hdr.type)) + return DMERR_FWRITE; + + switch (param->type) + { + case EFPT_POINTS: + if ((err = dmSaveTimelinePoints(res, ¶m->vpts)) != DMERR_OK) + return err; + break; + + case EFPT_INT: + tmp32 = param->vint; + if (!dmf_write_le32(res, tmp32)) + return DMERR_FWRITE; + break; + + case EFPT_FLOAT: + if (!dmSaveFloatValue(res, param->vfloat)) + return DMERR_FWRITE; + break; + + case EFPT_STRING: + len = strlen(param->vstr); + if (!dmf_write_le16(res, len)) + return DMERR_FWRITE; + + if (dmf_write_str(res, (Uint8 *) param->vstr, len) != len) + return DMERR_FWRITE; + break; + } + + return DMERR_OK; +} + + +int dmSaveTimelineEvent(DMResource *res, DMTimelineEvent *event) +{ + int param, err; + DMFTimelineEvent hdr; + + strncpy(hdr.effectName, event->effect->name, sizeof(hdr.effectName)); + hdr.start = event->start; + hdr.duration = event->duration; + hdr.nparams = event->nparams; + + if (!dmf_write_le32(res, hdr.start) || + !dmf_write_le32(res, hdr.duration) || + dmf_write_str(res, (Uint8 *) hdr.effectName, sizeof(hdr.effectName)) != sizeof(hdr.effectName) || + !dmf_write_le32(res, hdr.nparams)) + return DMERR_FREAD; + + for (param = 0; param < event->nparams; param++) + { + if ((err = dmSaveTimelineEventParam(res, &(event->params[param]))) != DMERR_OK) + return err; + } + + return DMERR_OK; +} + + +int dmSaveTimelineTrack(DMResource *res, DMTimelineTrack *track) +{ + int event, err; + DMFTimelineTrack hdr; + + strncpy(hdr.name, track->name, sizeof(hdr.name)); + hdr.enabled = track->enabled; + hdr.nevents = track->nevents; + + if (dmf_write_str(res, (Uint8 *) &hdr.name, sizeof(hdr.name)) != sizeof(hdr.name)) + return DMERR_FWRITE; + + dmfputc(hdr.enabled, res); + if (!dmf_write_le32(res, hdr.nevents)) + return DMERR_FWRITE; + + for (event = 0; event < track->nevents; event++) + { + if ((err = dmSaveTimelineEvent(res, track->events[event])) != DMERR_OK) + return err; + } + + if ((err = dmSaveTimelineCurve(res, &(track->composite))) != DMERR_OK) + return err; + + int track, err; + DMFTimeline hdr; + + memcpy(&hdr.magic, DT_MAGIC_ID, sizeof(hdr.magic)); + strncpy(hdr.name, tl->name, sizeof(hdr.name)); + hdr.ntracks = tl->ntracks; + hdr.duration = tl->duration; + + if (dmf_write_str(res, (Uint8 *) hdr.magic, sizeof(hdr.magic)) != sizeof(hdr.magic) || + dmf_write_str(res, (Uint8 *) hdr.name, sizeof(hdr.name)) != sizeof(hdr.name) || + !dmf_write_le32(res, hdr.ntracks) || + !dmf_write_le32(res, hdr.duration)) + return DMERR_FWRITE; + + for (track = 0; track < tl->ntracks; track++) + { + if ((err = dmSaveTimelineTrack(res, tl->tracks[track])) != DMERR_OK) + return err; + } + + return DMERR_OK; +int dmTimelineNew(DMTimeline **ptl, const char *name) +{ + DMTimeline *tl; + if ((*ptl = tl = dmMalloc0(sizeof(DMTimeline))) == NULL) + return DMERR_MALLOC; + + tl->name = dm_strdup(name); + + return DMERR_OK; +} + + +int dmTimelineAddTrack(DMTimeline *tl, DMTimelineTrack **ptrack, const char *name) +{ + DMTimelineTrack *track; + + if ((*ptrack = track = dmMalloc0(sizeof(DMTimelineTrack))) == NULL) + return DMERR_MALLOC; + + track->name = dm_strdup(name); + + if (tl->ntracks + 1 >= tl->nallocated) + { + tl->nallocated += 16; + tl->tracks = dmRealloc(tl->tracks, sizeof(DMTimelineTrack *) * tl->nallocated); + if (tl->tracks == NULL) + return DMERR_MALLOC; + } + + tl->tracks[tl->ntracks] = track; + tl->ntracks++; + + return DMERR_OK; +} + + +int dmTimelineTrackAddEvent(DMTimelineTrack *track, int start, int duration, DMTimelineEvent **pev) +{ + DMTimelineEvent *ev; + + if ((*pev = ev = dmMalloc0(sizeof(DMTimelineEvent))) == NULL) + return DMERR_MALLOC; + + ev->start = start; + ev->duration = duration; + + if (track->nevents + 1 >= track->nallocated) + { + track->nallocated += 16; + track->events = dmRealloc(track->events, sizeof(DMTimelineEvent *) * track->nallocated); + if (track->events == NULL) + return DMERR_MALLOC; + } + + track->events[track->nevents] = ev; + track->nevents++; + + return DMERR_OK; +} + + +int dmTimelineEventSetEffect(DMTimelineEvent *event, const char *name) +{ + int param; + DMEffect *ef; + + if ((ef = dmFindEffectByName(name)) == NULL) + return DMERR_INVALID_DATA; + + event->effect = ef; + event->nparams = ef->nparams; + event->params = dmCalloc(ef->nparams, sizeof(DMTimelineEventParam)); + if (event->params == NULL) + return DMERR_MALLOC; + + for (param = 0; param < ef->nparams; param++) + { + DMTimelineEventParam *psrc = &ef->params[param], + *pdst = &event->params[param]; + + pdst->name = dm_strdup(psrc->name); + pdst->type = psrc->type; + pdst->vstr = dm_strdup(psrc->vstr); + pdst->vint = psrc->vint; + pdst->vfloat = psrc->vfloat; + + if (psrc->vpts.points != NULL && psrc->vpts.npoints > 0) + { + pdst->vpts.npoints = psrc->vpts.npoints; + pdst->vpts.nallocated = psrc->vpts.nallocated; + pdst->vpts.points = dmMalloc(psrc->vpts.nallocated * sizeof(DMTimelinePoint)); + if (pdst->vpts.points == NULL) + return DMERR_MALLOC; + + memcpy(pdst->vpts.points, psrc->vpts.points, pdst->vpts.npoints * sizeof(DMTimelinePoint)); + } + } + + return DMERR_OK; +} + + +DMTimelineEvent *dmTimelineGetEventAt(DMTimelineTrack *track, const int time) +{ + int event; + for (event = 0; event < track->nevents; event++) + { + DMTimelineEvent *ev = track->events[event]; + if (time >= ev->start && time <= ev->start + ev->duration) + return ev; + } + return NULL; +} +} + int dmSaveTimeline(DMResource *res, DMTimeline *tl) {